#26 Linux kernel(內核)詳解與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法
Linux kernel:
內核設計流派:
單內核設計,但是充分借鑒了微內核體系設計的優點,為內核引入了模塊化機制,內核高度模塊化;
內核被模塊化之後,一些最為基本最為重要的內容,被編譯到內核核心;而其他更多的功能則以模塊的方式來提供;而且支持動態裝載和卸載各內核模塊;
內核的組成部分:
kernel:內核核心文件,一般為bzimage,經過壓縮處理的鏡像文件;通常內核核心文件保存在/boot/目錄下,名稱為vmlinuz-version-release
kernel object(ko):內核對象,內核額外功能模塊,一般該類文件放置於/lib/modules/version-release
註意:內核模塊與內核核心,版本號必須嚴格匹配;
內核模塊其實就是內核源代碼的一部分,只是在編譯內核的過程中,由於其功能可能並非內核核心所必須,所以以模塊的方式被編譯;
在編譯內核時,內核的功能通常有如下幾種選擇方式;
[ ] kernel function:no,不選擇編譯此功能;
[M] kernel function:modules,將此功能編譯為內核模塊使用;此功能不占據內和空間,只占用磁盤空間;
[*] kernel function:yes,將此功能直接編譯進內核核心;
ramdisk:內和補充文件,輔助文件,對於內核核心來說,此文件非必須,是否使用此文件取決於內核能否直接驅動rootfs所在的存儲設備;
設備的驅動程序,SCSI設備的驅動
邏輯設備驅程序,lvm的驅動程序,軟raid驅動程序等;
文件系統;
cpio -i -F initramfs-2.6.32-573.el6.x86_64.img
簡化的rootfs
註意:一般來講,kernel核心文件和ramdisk文件必須具有完全相同的版本號;
內核管理的相關命令:
uname:打印當前系統相關信息(內核版本號、硬件架構、主機名稱和操作系統類型等)。
常用選項:
-n:顯示節點名稱
-r:顯示內核版本號,包括version和release
-a:顯示所有信息
例子:
uname -a
lsmod:顯示已經加載到內核中的模塊的狀態信息。
顯示有Linux內核核心已經裝載的內核模塊;
lsmod顯示的內容,分為三個字段:
模塊名稱 模塊大小 被引用次數及被誰所引用;
例子:
lsmod
modinfo:顯示kernel模塊的信息。
常用選項:
-F field:僅顯示指定字段的信息;通常只能指定一個字段;
-n:只顯示模塊文件的絕對路徑;(最常用)
-a:只顯示模塊的作者信息;
-d:只顯示模塊的描述信息;
-l:只顯示許可證信息;
-p:只顯示模塊參數信息;
例子:
modinfo
depmod:可產生模塊依賴的映射文件,在構建嵌入式系統時,需要由這個命令來生成相應的文件,由modprobe使用。
選項:
-a或--all:分析所有可用的模塊;
-d或debug:執行排錯模式;
-e:輸出無法參照的符號;
-i:不檢查符號表的版本;
-m<文件>或system-map<文件>:使用指定的符號表文件;
-s或--system-log:在系統記錄中記錄錯誤;
-v或--verbose:執行時顯示詳細的信息;
-V或--version:顯示版本信息;
--help:顯示幫助。
實現內核模塊的動態裝載和卸載的命令:
insmod:裝載指定的內核模塊,但無法自動解決模塊間的依賴關系;
例子:
insmod modinfo -n btrfs
註意:filename:模塊文件的絕對路徑;
rmmod:用於從當前運行的內核中移除指定的內核模塊。
例子:
rmmod raid1
modprobe:從內核中移除模塊或者向內核中插入模塊;
默認的配置文件:/etc/modprobe.conf , /etc/modprobe.d/*
例子:
modprobe module_name:裝載模塊,自動識別和解決依賴關系;
modprobe -r module_name:卸載模塊
ramdisk管理:
ramdisk文件是在操作系統安裝完成之後,由特定的應用程序根據當前硬件設備信息,文件系統信息等量身定制而成;
ramdisk文件的制作工具:
centos 5:
mkinitrd:建立要載入ramdisk的映像文件,以供Linux開機時載入ramdisk。
選項:
-f:若指定的映像問家名稱與現有文件重復,則覆蓋現有的文件;
-v:執行時顯示詳細的信息;
--omit-scsi-modules:不要載入SCSI模塊;
--preload=<模塊名稱>:指定要載入的模塊;
--with=<模塊名稱>:指定要載入的模塊;
--version:顯示版本信息。
例子:
mkinitrd -v -f myinitrd.img $(uname -r)
centos 6/7:
dracut:建立要載入ramdisk的映像文件,以供Linux開機時載入ramdisk。
例子:
dracut /boot/initramfs-$(uname -r).img $(uname -r)
mkinitrd腳本:
內和信息輸出的兩個重要的偽文件系統:
/proc:內核狀態及統計信息的主要的輸出接口;同時還提供了一個能夠輸入配置信息,完成內核參數實時配置的接口——/proc/sys;
/proc/*(除了sys目錄):信息輸出,只讀;
/proc/sys:可讀寫,可以接受用戶指定的“新值”,來實現對內核相應功能或特性的實時配置;
查看內核輸出的狀態信息或統計信息,直接使用cat命令即可;
修改或設置內核功能或特性:
使用echo命令,借助於覆蓋輸出重定向進行修改或設置即可;
echo "value" > /proc/sys/path/to/parameter
查看內核參數以及配置/proc/sys中的諸多功能,還可以使用:
sysctl命令:
sysctl - configure kernel parameters at runtime
sysctl:用於在內核運行時動態地修改內核的運行參數,可用的內核參數在目錄/proc/sys中。
查看內核參數:
sysctl -a:查看所有可以被修改的內核參數;
sysctl variable:查看指定內核參數的設定值;
配置某個內核參數(功能或特性)的值:
sysctl -w variable=value
註意:此方法中,"="兩端不能寫空格字符;
sysctl -p:根據配置文件設置內存參數;重新讀取並加載配置文件中所有的設置參數並且使其生效;
常用的幾個內核參數:
net.ipv4.ip_forward:Linux的核心轉發功能,路由功能;取值0,1
net.ipv4.icmp_echo_ignore_all:忽略所有來源於外部主機的ping操作請求,取值0,1
vm.drcp_caches:清理buffer和cache,釋放物理內存,取值:0,1,2
kernel.hostname:當前生效的主機名:
DDOS:dynamic deny of service,動態拒絕服務攻擊
DCHP:IP地址耗盡策略,發送大量隨機Mac地址DHCP discover消息
DNS:ARP攻擊,ARP欺騙,
網關欺騙
源IP地址欺騙
dead ping:
/sys:sysfs
專門為用戶提供使用的偽文件系統,輸出內核識別出來的各硬件設備的相關屬性信息,也包括內核對硬件特性的可設定的信息;對於某些參數進行特定格式的修改,以調整或設定硬件的工作特性;
echo ‘- - -‘ > /sys/class/scsi_host/host2/scan
udev:
通過讀取/sys目錄下的硬件設備的信息,按需為各硬件設備創建設備文件;
udev是運行在用戶空間的進程;
專用工具:udevadmin,hotplug...
當內核已經被加載至內存中,假如操作系統被安裝到sda磁盤上,則內核需先標識出sda磁盤並而將其標記為設備(創建設備文件),而後才能掛載此設備;
為了能夠讓這樣的設備以後也能正常使用,內核通過內置的devtmpfs為每個內核所要使用的設備創建設備文件;而這樣的文件可以被當作文件系統掛載之後,從內核直接轉移到真正的rootfs中的dev目錄內的;對於操作系統啟動之後被新插入的設備,就必須要依靠udev來識別並創建設備文件了;
udev之所以能夠為設備創建設備文件,主要依賴於其事先定義好的規則;而這樣的規則一般保存在udev的規則配置文件中:
/etc/udev/runles.d
/usr/lib/udev/rules.d
如何定制內核——編譯內核源代碼:
http://kernel.org 內核維護的官方站點,可以獲取內核源代碼包;
編譯源代碼的前提條件:
1.開發環境
開發工具:gcc,make,automake,qt,GTK,ncurese
程序包組:
“Development Tool”,“Server Platform Development”
“開發工具”,“服務器平臺開發”
ncurses-devel
頭文件:/usr/include/*.h
2.獲取目標主機上各硬件設備的相關信息;
CPU:
# cat /proc/cpuinfo
# lscpu
# x86info -a
PCI設備:
# lspic[-v|-vv]
USB設備:
#lsubs[-v|-vv]
塊設備:
#lsblk
了解更多的硬件設備信息:
# hal-device(centos6可用包名:hal-0.5.14-14.e16.x86_64)
3.獲取目標主機系統功能的相關選項:
比如:目標主機需要使用哪種文件系統;
目標主機是否需要啟動安全防護機制;
...
編譯安裝應用程序的一般步驟:
1. #./.configure arg1 [arg2...]
2. # make
3. # make install
編譯安裝內核的一般步驟:
1.需要準備或生成一個.config的文件,該文件記錄了內核的編譯細節:
哪些功能直接編譯進內核;
哪些功能編譯成內核模塊;
哪些功能在此次編譯中不啟用;
make menuconfig|xconfig|config
2.開始編譯內核
make [-j #]
多線程編譯,可以將編譯進程在多個CPU核心上並行進行;
3.安裝模塊文件:
make module-install
4.安裝內核核心文件,並生成grub的啟動菜單;
make install
安裝的是bziage文件,安裝到/boot/vmlinuz-version-release
生成與內核版本完全匹配的initramfs文件
編輯grub的配置文件,生成啟動菜單項;
Screen:一款由GNU計劃開發的用於命令行終端切換的自由軟件。
例子:
screen(開啟screen)
Ctrl +a;d(拆除screen)
screen -ls(列表顯示screen)
screen -r screen_ID(恢復連接至指定的screen)
exit(關閉screen)
內核的配置選項:
64-bit kernel
是否支持64位內核
general setup --->
通用配置項:
() local version - append to kernel release
自定義本地版本號,附加到內核版本號後面的信息,由變異者定義;
((none)) default hostname
定義當沒有設置主機名時的默認主機名;
enable loadable module support
是否支持內核模塊的動態裝卸載;
enable the block layer
是否支持啟用塊層,通常是選擇支持;
processor type and features:
處理器類型和特性
processor family (generic-x86-64) --> (core 2/newer Xeon)
選擇處理器類型
power management and acpi options:
電源管理及高級電源管理接口選項
executable file formats / emulations
指定可執行文件的格式,默認為ELF,以#!開頭的文件也具備可執行特性;
networking support
內核中的網絡協議棧
networking options
[ ] ipv6 support
device drivers:
設備驅動程序
file system:
dos/fat/nt file systems
[M] NTFS support
kernel hacking:
內核調試的相關內容
security options:
NAS selinux support
安全選項
cryptographic API:
加密解密的應用程序變口;
virtualization:
虛擬化相關
配置內核的方式:
1.make config:基於單行命令以遍歷內核所有功能的方式進行內核配置,因此每個內核選項的配置都是交互式的;
2.make menuconfig:基於curses的文本模式的配置窗口;
3.make gconfig:基於gtk開發環境的窗口配置界面;一般情況下,只要安裝了“桌面平臺開發”程序包組就可以了;
4.make xconfig:基於QT開發環境的窗口配置界面;一般情況下,只要安裝了“桌面平臺開發”程序包組就可以了;
5.make defconfig:基於內核為目標平臺提供默認配置模板進行配置;
6.make allnoconfig:所有的功能全部不編譯(全部選no)的配置方式;
7.make allyesconfig:所有的功能全部編譯進核心(全部選yes)的配置方式;
內核的編譯方式:
1.全編譯:make [-j #]
2.部分編譯:
a.只編譯某個子目錄中的相關源代碼;
# cd /user/src/linux
# make [-j #] dir_name/
b.只編譯特定的模塊
# cd /usr/src/linux
# make [dir/]file.ko
示例:
# cd /usr/src/linux
# make drivers/net/ethernet/intel/e1000/e1000.ko
3.交叉編譯:編譯的目標平臺與當前編譯的平臺不相同;
make arch=arch_name
示例:
# make arch=arm
內核重新編譯:
1.將所有/usr/src/inux-version目錄的內容直接刪除,重新從源代碼包釋放;隨後可以重復之前的步驟重新編譯即可;
2.先清理之前的編譯接口:
make clean:
清理大多數的編譯生成的文件,但是會保留.config文件;
make mrproper:
清理所有編譯生成的文件,包括.config以及其他的備份文件;
make distclean:
相當於make mrproper,但是還會額外清理各種patches以及編譯器自身的備份文件;
編譯安裝內核實例
~]# tar xf linux-3.10.99.tar.xz -C /usr/src
~]# cd /usr/src
src]# ln -sv linux-3.10.99 linux
src]# cd /usr/src/linux
linux]# cp /boot/config-$(uname -r) ./.config
linux]# make menuconfig
linux]# make -j 4
linux]# make modules_install
linux]# make install
linux]# reboot
重啟之後在grub菜單中選擇新編譯的內核來啟動,如果可以看到登錄提示符,則說明內核編譯升級成功!
然後可以嘗試編譯其他與當前操作系統版本不同的其他更高級版本的內核,多試幾個版本,了解一下各個不同版本的內核的特性;
#26 Linux kernel(內核)詳解與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法