Linux Kernel
概述:文章將主要介紹Linux 內核的相關信息,包括內核各組成部分的詳細介紹,其中有內核信息的獲取命令,uname;內核模塊管理類命令:lsmod,modinfo,modprobe,insomd,rmmod;ramdisk生成的相關命令,mkinitrd和dracut命令;以及linux中的兩個為文件系統 /proc和/sys。最后是內核的簡單編譯。
1.ldd命令(– print shared library dependencies)
功能:打印二進制應用程序所依賴的庫文件
語法:ldd [OPTION]… FILE…(二進制文件)
舉例:查看/bin/ls所以來的庫文件
[root@CentOS6 ~]# ldd /bin/ls # 庫文件名稱 => # 庫文件路徑 linux-vdso.so.1 => (0x00007fff615d7000) # 沒有對用文件,是調用庫真正的入口 libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003270e00000) librt.so.1 => /lib64/librt.so.1 (0x000000326fe00000) libcap.so.2 => /lib64/libcap.so.2 (0x0000003273e00000) libacl.so.1 => /lib64/libacl.so.1 (0x000000327a200000) libc.so.6 => /lib64/libc.so.6 (0x000000326f600000) libdl.so.2 => /lib64/libdl.so.2 (0x000000326f200000) /lib64/ld-linux-x86-64.so.2 (0x000000326ee00000) # 整個系統調用庫的入口 libpthread.so.0 => /lib64/libpthread.so.0 (0x000000326fa00000) libattr.so.1 => /lib64/libattr.so.1 (0x000000327d200000)
取庫文件的路徑,如下:
[root@CentOS6 ~]# ldd /bin/ls |grep -o "/lib[^[:space:]]*" /lib64/libselinux.so.1 /lib64/librt.so.1 /lib64/libcap.so.2 /lib64/libacl.so.1 /lib64/libc.so.6 /lib64/libdl.so.2 /lib64/ld-linux-x86-64.so.2 /lib64/libpthread.so.0 /lib64/libattr.so.1
2.Linux Kernel
★內核設計體系:單內核,微內核
Linux:為單內核設計,但充分借鑒了微內核體系設計的優點;為內核引入了模塊化機制(高度模塊化);
★內核的組成部分:
kernel:內核核心,一般為bzimage,通常位于/boot目錄,名稱為vmlinuz-VERSION-release
kernel object:內核對象,即內核模塊,一般放置于/lib/modules/VERSION-release
注意:內核模塊與內核核心版本一定要嚴格匹配
ramdisk:輔助性文件,并非必須,這取決于內核是否能直接驅動rootfs所在的設備
目標設備驅動:例如SCSI設備的驅動;
邏輯設備驅動:例如LVM設備的驅動;
文件系統驅動:例如xfs文件系統;
ramdisk是一個簡裝版的根文件系統,之后要進行根切換,掛載真正的根文件系統。
★內核編譯的三種選擇
[ ]:N,不編譯此功能
[M]:Module ,編譯成內核模塊,用到時再裝載
[*]:Y,編譯進內核核心,即所有人都用的功能才會編輯進去
★內核模塊支持動態裝載和卸載
[root@centos7 ~]# ls /lib/modules/3.10.0-327.el7.x86_64/ build modules.alias modules.builtin modules.dep.bin modules.modesetting modules.softdep source weak-updates extra modules.alias.bin modules.builtin.bin modules.devname modules.networking modules.symbols updates kernel modules.block modules.dep modules.drm modules.order modules.symbols.bin vdso [root@centos7 ~]# uname -r # 內核模塊與核心版本要完全匹配 3.10.0-327.el7.x86_64 [root@centos7 ~]#
3.uname(內核信息獲?。?/strong>
語法:uname [OPTION]…
選項:-r:內核的release號;
-n:主機名;
-a:顯示所有信息;
文件:/boot/vmlinuz-VERSION-release
顯示如下:
[root@CentOS6 ~]# uname -n # 顯示主機名,同hostname CentOS6.localdomain [root@CentOS6 ~]# hostname CentOS6.localdomain [root@CentOS6 ~]# uname -r # 顯示內核的release號 2.6.32-642.el6.x86_64 [root@CentOS6 ~]# uname -v # 顯示編譯的版本號 #1 SMP Tue May 10 17:27:01 UTC 2016 [root@CentOS6 ~]# uname -a # 顯示所有的信息 Linux CentOS6.localdomain 2.6.32-642.el6.x86_64 #1 SMP Tue May 10 17:27:01 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
4.內核模塊管理
1)lsmod (查看當前內核已經裝載的模塊)
顯示的內核來自于 /proc/modules
查找指定模塊:lsmod |grep MOD_NAME
[root@CentOS6 ~]# lsmod Module Size Used by autofs4 27000 3 ipv6 336282 282 fuse 79892 2 vmhgfs 50307 0 vsock 46582 2 uinput 8120 0 microcode 112205 0 snd_seq_midi 6423 0 vmware_balloon 7199 0 snd_seq_midi_event 7205 1 snd_seq_midi snd_ens1371 21523 0 snd_rawmidi 24633 2 snd_seq_midi,snd_ens1371 snd_ac97_codec 124967 1 snd_ens1371
2)modinfo(顯示模塊的詳細描述信息)
語法:modinfo[ -k kernel ] [ modulename|filename… ]
選項:-n: 只顯示模塊文件路徑;
-p: 顯示模塊參數;
-F:僅顯示指定字段的信息;
-a: author;
-d: description;
-l: license;
[root@CentOS6 ~]# modinfo ext4 filename: /lib/modules/2.6.32-642.el6.x86_64/kernel/fs/ext4/ext4.ko license: GPL description: Fourth Extended Filesystem author: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others srcversion: 78B9CBCA6A7D7547B8566CC depends: mbcache,jbd2 # 表示被此模塊所依賴的其他模塊 vermagic: 2.6.32-642.el6.x86_64 SMP mod_unload modversions
3)modprobe(模塊的裝載與卸載)
語法:modprobe [-r] module_name…
裝載模塊:modprobe module_name… (會自動解決模塊間的依賴關系)
卸載模塊:modprobe -r module_name…
[root@CentOS6 ~]# lsmod |grep btrfs # 查找指定的模塊 [root@CentOS6 ~]# modprobe btrfs # 裝載模塊 [root@CentOS6 ~]# lsmod |grep btrfs btrfs 786956 0 zlib_deflate 21629 1 btrfs lzo_decompress 2343 1 btrfs lzo_compress 2368 1 btrfs libcrc32c 1246 1 btrfs [root@CentOS6 ~]# modprobe -r btrfs # 卸載模塊 [root@CentOS6 ~]# lsmod |grep btrfs
4)depmod
內核模塊依賴關系文件及系統信息映射文件的生成工具
模塊裝載和卸載的另一組命令(insmod、rmmod)
1)insmod
insmod[ filename ] [ module options… ] (這里不會自動解決模塊間的依賴關系)
filename:為模塊文件的文件路徑;
[root@centos7 ~]# lsmod |grep btrfs [root@centos7 ~]# insmod btrfs # 不能直接裝載,需要指明模塊的文件路徑 insmod: ERROR: could not load module btrfs: No such file or directory [root@centos7 ~]# modinfo -n btrfs /lib/modules/3.10.0-327.el7.x86_64/kernel/fs/btrfs/btrfs.ko [root@centos7 ~]# insmod `modinfo -n btrfs` insmod: ERROR: could not insert module /lib/modules/3.10.0-327.el7.x86_64/kernel/fs/btrfs/btrfs.ko: Unknown symbol in module # 有依賴關系,不能安裝
2)rmmod
rmmod[ modulename] 直接指明模塊名稱卸載就可以。
5.ramdisk文件管理
·ramdisk–> ramfs 提高速度(完成對真正根文件系統的驅動加載)
·CentOS 5: initrd, 工具程序:mkinitrd
·CentOS 6: initramfs,工具程序:mkinitrd,dracut
1)為當前正在使用的內核重新制作ramdisk
-
mkinitrd命令
–with=<module>:除了默認的模塊之外需要裝載至initramfs中的模塊;
–preload=<module>:initramfs所提供的模塊需要預先裝載的模塊;
mkinitrd /boot/initramfs-$(uname-r).img $(uname-r)
示例:
[root@centos7 ~]# mv /boot/initramfs-3.10.0-327.el7.x86_64.img /tmp # 移除 [root@centos7 ~]# mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) #創建 [root@centos7 ~]# ls /boot config-3.10.0-327.el7.x86_64 initramfs-3.10.0-327.el7.x86_64.img vmlinuz-0-rescue-2044869cb7454de39dc9ec0daa7a8588 grub initrd-plymouth.img vmlinuz-3.10.0-327.el7.x86_64 grub2 symvers-3.10.0-327.el7.x86_64.gz initramfs-0-rescue-2044869cb7454de39dc9ec0daa7a8588.img System.map-3.10.0-327.el7.x86_64 [root@centos7 ~]#
-
dracut命令
dracut /boot/initramfs-$(uname-r).img $(uname-r)
示例:
[root@centos7 ~]# rm -f /boot/initramfs-3.10.0-327.el7.x86_64.img [root@centos7 ~]# dracut /boot/initramfs-$(uname -r).img $(uname -r) [root@centos7 ~]# ls /boot config-3.10.0-327.el7.x86_64 grub grub2 initramfs-0-rescue-2044869cb7454de39dc9ec0daa7a8588.img initramfs-3.10.0-327.el7.x86_64.img initrd-plymouth.img symvers-3.10.0-327.el7.x86_64.gz System.map-3.10.0-327.el7.x86_64 vmlinuz-0-rescue-2044869cb7454de39dc9ec0daa7a8588 vmlinuz-3.10.0-327.el7.x86_64
6.內核信息輸出的偽文件系統:/proc,/sys
1)/proc目錄
★ /proc:內核狀態和統計信息的輸出接口;同時還提供一個配置接口,/proc/sys
★ 參數:
·只讀:信息輸出。例如:/proc/#/* 只是用來輸出某進程的相關信息;
· 可寫:可接受用戶指定一個“新值”來實現對內核某功能或特性的配 置;/proc/sys
★ /proc/sys 參數和文件系統的有映射關系的,
例如:net/ipv4/ip_forwad 相當于 net.ipv4.ip_forward
★ 偽文件系統的的特點是:不能夠直接使用編輯器編輯;但是可以通過以下方式修改:
文件系統命令(cat,echo)
查看:cat /proc/sys/PATH/TO/SOMR_KERNEL_FILE
設定:echo "NEW_Value" > /proc/sys/path/to/somefile
sysctl命令 專用于查看或設定/proc/sys目錄下參數的值;
語法:sysctl [options] [variable[=value]]
查看:# sysctl -a
# sysctl variable
修改其值:# sysctl -w variable=value
★ 以上兩種方式的設定僅當前運行內核有效,要想永久生效,就要寫入到配置文件當中。
內核參數配置文件:
/etc/sysctl.conf ,/etc/sysctl.d/*.conf
此種設定不能立即生效,但重啟系統后一直有效,為了不重啟系統而生效的方 式: # sysctl -p
★ 內核參數:
net.ipv4.ip_forward:核心轉發
vm.drop_caches:
kernel.hostname:主機名
net.ipv4.icmp_echo_ignore_all:忽略所有發往本主機的ping操作
示例:
[root@centos7 ~]# sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 0 [root@centos7 ~]# sysctl -w net.ipv4.ip_forward=1 # 修改其值 net.ipv4.ip_forward = 1 [root@centos7 ~]# uname -n centos7 [root@centos7 ~]# sysctl -w kernel.hostname=taotao kernel.hostname = taotao # 注意參數和文件系統的映射關系,這里是簡裝形式 [root@centos7 ~]# uname -n taotao [root@centos7 ~]# cat /proc/sys/kernel/hostname # taotao [root@centos7 ~]# echo "centos7" > /proc/sys/kernel/hostname # echo 命令修改主機名 [root@centos7 ~]# uname -n centos7
修改配置文件:
[root@centos7 ~]# vim /etc/sysctl.conf # 修改配置文件 1 # System default settings live in /usr/lib/sysctl.d/00-system.conf. 2 # To override those settings, enter new settings here, or in an /etc/sysctl.d/<name>.conf file 3 # 4 # For more information, see sysctl.conf(5) and sysctl.d(5). 5 net.ipv4.ip_forward = 1 # 添加一行 [root@centos7 ~]# cat /proc/sys/net/ipv4/ip_forward # 查看其值發現并沒有改變 0 [root@centos7 ~]# sysctl -p # 不用重啟,直接生效 net.ipv4.ip_forward = 1 [root@centos7 ~]# cat /proc/sys/net/ipv4/ip_forward 1
內核參數:
[root@centos7 ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all 0 [root@centos7 ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all [root@centos7 ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all 1
2)/sys目錄:
★ sysfs:輸出內核識別出的個硬件設備的相關屬性信息,也有內核對硬件的可設置參數;對這些參數的修改,即可定制硬件設備工作特性;
★udev:通過讀取/sys目錄下的硬件設備信息按需為各硬件設備創建設備文件;udev是用戶空間程序;專用工具:devadmin,jostplug
★udev 為設備創建文件時,會讀取其事先定義好的規則文件,
一般在/etc/udev/rules.d/目錄下,
如修改網卡名對應的規則文件為:/etc/udev/rules.d/70-persistent-net.rules
示例:
[root@centos7 ~]# ls /sys block bus class dev devices firmware fs hypervisor kernel module power
[root@CentOS6 ~]# vim /etc/udev/rules.d/70-persistent-net.rules 1 # This file was automatically generated by the /lib/udev/write_net_rules 2 # program, run by the persistent-net-generator.rules rules file. 3 # 4 # You can modify it, as long as you keep each rule on a single 5 # line, and change only the value of the NAME= key. 6 7 # PCI device 0x8086:0x100f (e1000) 8 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:e4:5e:4d", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0" 9 10 # PCI device 0x8086:0x100f (e1000) 11 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:e4:5e:57", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
內核編譯
一、程序包的編譯安裝:
1.步驟:
./configure
make;
makeinstall
2.前提:開發環境(開發環境,開發庫),頭文件:usr/include
3.開源:源代碼–>可執行格式
4.發行版:以“通用”的目標
二、內核編譯:
1.前提:
1)準備好開發環境;
2)獲取目標主機上硬件設備的相關信息;
3)獲取到目標主機系統功能的相關信息,例如,要啟用的文件系統
4)獲取內核源碼包:www.kernel.org
2.準備開發環境:
1)CentOS 6,7:包組:
Development Tools
Server Platform Development
2)目標主機硬件相關信息:
CPU:# cat /proc/cpuinfo
# x86info -a
# lscpu
PCI: # lspci -v,-vv
# lsusb -v,-vv
# lsblk 塊設備
了解全部硬件設備信息
# hal-device
三、編譯步驟:
tar xf linux-3.10.67.tar.xz -C /usr/src
cd /usr/src
ln -sv linux-3.10.67 linux
cd /usr/src/linux
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig 配置內核選項
make [-j 2] 編譯內核,可使用-j指定編譯線程數量
make modules_install 安裝內核模塊
make install 安裝內核核心
reboot 重啟系統,選擇使用新內核
演示過程如下:
1.獲取源碼包(www.kernel.org),選擇要編譯的版本,為了保障能夠成功編譯,建議不要使用跨版本太大的源碼包
2.準備開發環境(相關開發工具包),以及查看自己的主機硬件相關信息是否可以符合
3.解壓到 /usr/src 目錄下
tar xf linux-3.10.67.tar.xz -C /usr/src
[root@centos7 ~]# ls 2016-09-11-16-52-39 bin Documents f1 httpd-2.2.29 linux-3.18.41.tar.xz # 獲取的源碼包 Music Public Templates anaconda-ks.cfg Desktop Downloads hanshu3.sh httpd-2.2.29.tar.bz2 mbox Pictures select.sh Videos [root@centos7 ~]# tar xvf linux-3.18.41.tar.xz -C /usr/src # 解壓到/usr/src目錄下 [root@centos7 ~]# ls /usr/src debug kernels linux-3.18.41 # 解壓的源碼包
4.進到/usr/src目錄中,并創建一個軟鏈接
[root@centos7 ~]# cd /usr/src [root@centos7 src]# ls debug kernels linux-3.18.41 [root@centos7 src]# ln -s linux-3.18.41/ linux # 創建軟鏈接 [root@centos7 src]# ls debug kernels linux linux-3.18.41 [root@centos7 src]# cd linux # 進到目錄中去 [root@centos7 linux]# ls arch COPYING crypto drivers fs init Kbuild kernel MAINTAINERS mm README samples security tools virt block CREDITS Documentation firmware include ipc Kconfig lib Makefile net REPORTING-BUGS scripts sound usr [root@centos7 linux]# du -sh . # 查看大小 631M .
5.復制/boot下的以config開頭的文件作為模板文件到/usr/src/linux/.config
# cp /boot/config-3.10.0-327.el7.x86_64 /usr/src/linux/.config
[root@centos7 linux]# cp /boot/config-3.10.0-327.el7.x86_64 /usr/src/linux/.config #復制模板文件 [root@centos7 linux]# ls -a . arch .config(# 復制的模板文件) CREDITS Documentation firmware .gitignore init Kbuild kernel .mailmap Makefile net REPORTING-BUGS scripts sound usr .. block COPYING crypto drivers fs include ipc Kconfig lib MAINTAINERS mm README samples security tools virt
6.在/usr/src/linux 中使用 # make menuconfig 配置內核選項,選好之后保存退出;
7.打開screen界面,執行 # make [-j 4] 編譯內核,可使用-j指定編譯線程數量
這時可以使用 # htop 查看一下cpu的使用情況,如下所示:
8.編譯完成之后,接下來需要執行 # make modules_install 安裝內核模塊
[root@centos7 src]# du -sh linux-3.18.41/ 7.1G linux-3.18.41/ # 可以看到編譯完成之后,變成了7.1G [root@centos7 linux]# ls /lib/modules 3.10.0-327.el7.x86_64 # 可以看到這時模塊文件只有一個 [root@centos7 linux]# make modules_install # 安裝內核模塊 [root@centos7 linux]# ls /lib/modules 3.10.0-327.el7.x86_64 3.18.41-1.0-Taolinux # 可以發現多了一個內核模塊 [root@centos7 linux]# ls /lib/modules/3.18.41-1.0-Taolinux/ # 編譯完成,而已看到生成的內核模塊文件 build modules.builtin.bin modules.softdep kernel modules.dep modules.symbols modules.alias modules.dep.bin modules.symbols.bin modules.alias.bin modules.devname source modules.builtin modules.order
9.執行 # make install 生成內核文件
[root@centos7 linux]# make install sh ./arch/x86/boot/install.sh 3.18.41-1.0-Taolinux arch/86/boot/bzlmage \ System.map "/boot"
10.reboot 重啟系統,選擇使用新內核
啟動之后,查看內核版本如下:
[root@centos7 ~]# uname -r 3.18.41-1.0-Taolinux # 說明新版內核已經啟動,編譯成功!
至此,一個全新的內核就已經編譯完成了?。?!
編譯詳細說明
1)配置內核選項:
★支持“更新”模式進行配置:在已有的.config文件的基礎之上進行“修改”配置;
(a) make config:基于命令行以遍歷的方式去配置內核中可配置的每個選項;
(b) make menuconfig:基于curses的文本窗口界面
(c) make gconfig:基于GTK (GNOME)環境窗口界面
(d) make xconfig:基于QT(KDE)環境的窗口界面
★持“全新配置”模式進行配置
(a) make defconfig:基于內核為目標平臺提供的“默認”配置進行配置
(b) make allyesconfig: 所有選項均回答為“yes“
(c) make allnoconfig: 所有選項均回答為"no“
2)編譯:
a)多線程編譯:make [-j #]
b) 編譯內核中的一部分代碼:
(i) 只編譯某子目錄中的相關代碼:
# cd /usr/src/linux
# make dir/
(ii) 只編譯一個特定的模塊:
# cd /usr/src/linux
# make dir/file.ko
例如:只為e1000編譯驅動
# make drivers/net/ethernet/intel/e1000/e1000.ko
C)如何交叉編譯內核:
編譯的目標平臺與當前平臺不相同;
# make ARCH=arch_name
要獲取特定目標平臺的使用幫助
# make ARCH=arch help
3)如何在執行過編譯操作的內核元碼樹上做重新編譯:
需要事先清理操作:
# make clean:清理大多數編譯生成的文件,但會保留config文件等
# make mrproper: 清理所有編譯生成的文件、config及某些備份文件
# make distclean:mrproper、patches以及編輯器備份文件
原創文章,作者:zhumengxiaotao,如若轉載,請注明出處:http://www.www58058.com/47767
總結的很完整,內容很充實,第一個ldd,而不是idd,我已經幫你修改了,下次細心點哦。