內核|內核模塊編譯
(對於內核的知識覺得了解不夠,等學習完LFS再來詳細整理下這方面的知識)
內核:系統上面的一個文件,這個文件包含了驅動主機各項硬件的檢測程序和驅動模塊。
計算機真正工作的是硬件,內核是用來控制這些硬件工作的(主要通過硬件驅動),如果我們需要硬件來完成某項工作時需要內核的幫助才能完成
內核模塊:編譯成模塊的驅動程序。既然內核中已經包括了驅動程序,那麼爲什麼需要驅動模塊呢?因爲硬件發展很快,如果一有新的硬件出現,就需要重新編譯內核就會很麻煩,因此將部分驅動編譯成內核模塊,在內核需要的時候加載,這樣就既可以保證新硬件的使用,也可以保證內核不會一出現新硬件就重新編譯
對於硬件驅動程序存在以下兩種處理方式
1. 編譯到內核
2. 編譯成內核模塊,內核需要時候進行加載
對於內核來說越簡單越好,一些不常用的驅動可以獨立成內核模塊
內核的編譯
1. 解壓縮內核文件
[root@localhost shared]# tar -jxvf linux-3.12.2.tar.bz2-C /usr/src/kernels/
2. 打開內核配置菜單,開始配置內核
[root@localhost linux-3.12.2]# make menuconfig
配置項主要分爲3中選擇類型
<>:不參加編譯
<*>參加編譯
<M>以內核模塊形式參加編譯
3. 配置完畢後,會生成一個.config文件保存剛纔的配置信息
[root@localhost linux-3.12.2]# ll -a
-rw-r--r-- 1 root root 107133 04-03 15:08 .config
4. 清理上一次緩衝後開始編譯內核
[root@localhost linux-3.12.2]# make clean
[root@localhost linux-3.12.2]# make bzImage
Setup is 15704 bytes (padded to 15872 bytes).
System is 2890 kB
CRC 4dc9f3fc
Kernel: arch/x86/boot/bzImage is ready (#1)
[root@localhost linux-3.12.2]# ll ./arch/x86/boot/bzImage
-rw-r--r-- 1 root root 2974816 04-03 16:15 ./arch/x86/boot/bzImage
5. 編譯在第2步選擇的內核模塊[root@localhost linux-3.12.2]# make modules
[root@localhost ~]# ll /lib/modules/
drwxr-xr-x 3 root root 4096 04-03 12:57 2.6.30.3
=>編譯完成內核模塊但未安裝,所以在/lib/modules/下並未產生任何內核模塊
6.
安裝內核模塊,在/lib/modules/會產生對應版本的內核模塊庫[root@localhost ~]# make modules_install
[root@localhost linux-3.12.2]# ll /lib/modules/
drwxr-xr-x 3 root root 4096 04-03 16:54 3.12.2
=>到處爲止內核與內核模塊已經編譯安裝完畢
7. 利用GRUB做一個多重引導,新的引導加載剛編好的內核[root@localhost ~]#
cp /usr/src/kernels/linux-3.12.2/arch/x86/boot/bzImage /boot/vmlinuz-3.12.2
8.
創建虛擬文件系統[root@localhost ~]# mkinitrd -v /boot/initrd-3.12.2.img 3.12.2
[root@localhost ~]# ll /boot/initrd-3.12.2.img /boot/vmlinuz-3.12.2
-rw------- 1 root root 2752740 04-04 08:53 /boot/initrd-3.12.2.img
-rw-r--r-- 1 root root 2974816 04-04 08:52 /boot/vmlinuz-3.12.2
9. 將內核配置信息保存以便下回使用
[root@localhost kernels]# cp /usr/src/kernels/linux-3.12.2/.config /boot/config-3.12.2
10. 編輯menu.lst 添加新的指向新內核的引導
[root@localhost ~]# vim /boot/grub/menu.lst
title CentOS (3.12.2)
root (hd0,0)
kernel /vmlinuz-3.12.2 ro root=LABEL=/ rhgb quiet rgb=0x317
initrd /initrd-3.12.2.img
11. 重啓之後查看內核版本[root@localhost ~]# uname -r
3.12.2.3
=>已經是最新的內核了
總結起來編譯內核主要分爲這麼幾步
1. 配置內核make menuconfig
2. 清除緩存make clean
3. 編譯內核make bzImage
4. 編譯內核模塊make modules
5. 安裝內核模塊make modules_install
獨立內核模塊的編譯
在內核編譯的時候我們可以通過內核菜單選擇內核模塊進行編譯。但如果內核已經編譯完成,此時有新的硬件產生,但是內核菜單並沒有此新硬件對應的驅動,那怎麼編譯其對應的內核模塊,即使內核菜單存在此驅動,難道還需要重新編譯內核?這就需要進行獨立內核模塊的編譯來解決了。
簡單的說,獨立內核模塊編譯,就是單獨編譯一個內核模塊,並將內核模塊添加到內核管理器。這樣內核就可以使用新增加內核模塊而不需要重新編譯了
[root@bogon shared]# tar -jxvf r8168-8.038.00.tar.bz2
=>解壓縮內核模塊
[root@bogon shared]# ll
drwxrwxrwx 1 root root 0 01-08 16:56 r8168-8.038.00
-rwxrwxrwx 1 root root 74460 04-08 21:07 r8168-8.038.00.tar.bz2
[root@localhost r8168-8.038.00]# make clean
[root@localhost r8168-8.038.00]# make modules
=>編譯內核模塊
[root@localhost r8168-8.038.00]# make install
=>安裝內核模塊
make -C src/ install
make[1]: Entering directory `/mnt/hgfs/shared/r8168-8.038.00/src'
make -C /lib/modules/2.6.18-371.el5/build SUBDIRS=/mnt/hgfs/shared/r8168-8.038.00/src INSTALL_MOD_DIR=kernel/drivers/net modules_install
make[2]: Entering directory `/usr/src/kernels/2.6.18-371.el5-i686'
INSTALL /mnt/hgfs/shared/r8168-8.038.00/src/r8168.ko
DEPMOD 2.6.18-371.el5
make[2]: Leaving directory `/usr/src/kernels/2.6.18-371.el5-i686'
make[1]: Leaving directory `/mnt/hgfs/shared/r8168-8.038.00/src'
[root@localhost ~]# ll /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko
-rwxr-xr-x 1 root root 1083997 04-09 14:44 /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko
=>內核模塊已經安裝成功
[root@localhost ~]# depmod –a
=>建立內核模塊依賴關係
[root@localhost ~]# ll /lib/modules/2.6.18-371.el5/modules.dep
-rw-r--r-- 1 root root 228487 04-09 14:54 /lib/modules/2.6.18-371.el5/modules.dep
=> modules.dep已經被修改
總結起來編譯獨立內核模塊主要分爲這麼幾步
1. 清除緩存make clean
2. 編譯內核模塊make modules
3. 安裝內核模塊 make install
4. 建立依賴關係depmod –a
說明:上面只是將內核模塊編譯與安裝,還未將內核模塊加載到內核,因此還需使用insmod進行內核模塊的加載
內核模塊管理
內核模塊依賴性
內核模塊存放在/lib/modules/$(uname –r)/kernel當中,其中內核模塊一直是存在依賴性的。這些依賴關係記錄在/lib/modules/$(uname –r)/modules.dep當我們增加會減少內核模塊時就要修改內核模塊之間的依賴關係。依賴關係的修改可以通過depmod命令來進行
語法:depmod
depmod [-Anea]
選項與參數:
不加參數:分析目前所有內核,模塊並重寫寫入
-A:只分析比modules.dep記錄還新的內核模塊。纔會更新
-n: 不寫入modules.dep只輸出到聘僱
-e: 顯示目前已經加載的不可執行的模塊名稱
-a:分析所有可用模塊
內核模塊的查看
查看所有內核模塊
lsmod
查看指定名稱的內核模塊
modinfo 模塊名稱[root@bogon kernels]# lsmod
Module Size Used by
ppdev 12613 0
autofs4 28997 3
hidp 22977 2
=> Used by代表此內核模塊被其他內核模塊所使用
[root@localhost ~]# modinfo r8168
filename: /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko
version: 8.038.00-NAPI
license: GPL
description: RealTek RTL-8168 Gigabit Ethernet driver
…….
depends:
vermagic: 2.6.18-371.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
內核模塊的加載與刪除
內核模塊加載
[root@localhost 2.6.18-371.el5-i686]#
insmod /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko
[root@localhost 2.6.18-371.el5-i686]# lsmod|grep r8168
r8168 248428 0
內核模塊刪除
rmmod 內核模塊絕對路徑
[root@localhost ~]# rmmod /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko
[root@localhost ~]# lsmod|grep r8168
modprobe內核模塊處理
使用上面的方法可以管理內核模塊,但是需要指定內核模塊的完整路徑,同時如果要刪除某個內核模塊時如果存在依賴關係,則無法刪除成功。使用modprobe可以避免此問題
Modprobe去modules.dep中尋找內核模塊因此不需要指定絕對路徑(前提我們已經使用的depmod將依賴關係寫入該文件)
語法:modprobe[-lfr] 內核模塊名稱
選項與參數:
-l:列出所有內核模塊
-f:強制加載內核模塊
-r:刪除內核模塊
舉例:
[root@localhost ~]# modprobe vfat =>加載內核模塊
[root@localhost ~]# lsmod |grep vfat
vfat 15937 0
[root@localhost ~]# modprobe -r vfat =>刪除內核模塊