鍍金池/ 教程/ Linux/ 內(nèi)核|內(nèi)核模塊編譯
Linux 學(xué)習(xí)記錄--開機(jī)掛載錯誤
日志系統(tǒng)
數(shù)據(jù)流重定向
內(nèi)存交換空間的構(gòu)建
文件系統(tǒng)簡介
Linux 學(xué)習(xí)記錄--軟件安裝 RPM|SRPM|YUM
文件特殊權(quán)限
目錄配置 FHS
文件內(nèi)容查閱
Boot Loader
文件壓縮
Linux 學(xué)習(xí)記錄--文件權(quán)限
Linux 命令縮寫
命令與文件的查詢
文件|目錄的默認(rèn)權(quán)限與隱藏權(quán)限
shell script
服務(wù)
Linux 學(xué)習(xí)記錄--程序編譯與函數(shù)庫
正則表達(dá)式與其應(yīng)用
關(guān)機(jī)相關(guān)指令
shell
vim 與 vi 常用命令
系統(tǒng)調(diào)用:進(jìn)程控制
文件系統(tǒng)簡單操作
磁盤掛載與卸載
有名管道通訊
磁盤分區(qū),格式化與檢驗(yàn)
工作管理與進(jìn)程管理
匿名管道通訊
Linux 學(xué)習(xí)記錄--啟動流程
文件與目錄管理
管道命令
命名別名與歷史命令
文件備份|還原
shell變量
Linux 學(xué)習(xí)記錄--ACL 權(quán)限控制
內(nèi)核|內(nèi)核模塊編譯
文件管理相關(guān)系統(tǒng)編程

內(nèi)核|內(nèi)核模塊編譯

(對于內(nèi)核的知識覺得了解不夠,等學(xué)習(xí)完LFS再來詳細(xì)整理下這方面的知識)

內(nèi)核:系統(tǒng)上面的一個(gè)文件,這個(gè)文件包含了驅(qū)動主機(jī)各項(xiàng)硬件的檢測程序和驅(qū)動模塊。
計(jì)算機(jī)真正工作的是硬件,內(nèi)核是用來控制這些硬件工作的(主要通過硬件驅(qū)動),如果我們需要硬件來完成某項(xiàng)工作時(shí)需要內(nèi)核的幫助才能完成
內(nèi)核模塊:編譯成模塊的驅(qū)動程序。既然內(nèi)核中已經(jīng)包括了驅(qū)動程序,那么為什么需要驅(qū)動模塊呢?因?yàn)橛布l(fā)展很快,如果一有新的硬件出現(xiàn),就需要重新編譯內(nèi)核就會很麻煩,因此將部分驅(qū)動編譯成內(nèi)核模塊,在內(nèi)核需要的時(shí)候加載,這樣就既可以保證新硬件的使用,也可以保證內(nèi)核不會一出現(xiàn)新硬件就重新編譯

對于硬件驅(qū)動程序存在以下兩種處理方式

  1. 編譯到內(nèi)核
  2. 編譯成內(nèi)核模塊,內(nèi)核需要時(shí)候進(jìn)行加載
    對于內(nèi)核來說越簡單越好,一些不常用的驅(qū)動可以獨(dú)立成內(nèi)核模塊

內(nèi)核的編譯

  1. 解壓縮內(nèi)核文件
    [root@localhost shared]# tar -jxvf linux-3.12.2.tar.bz2-C /usr/src/kernels/

  2. 打開內(nèi)核配置菜單,開始配置內(nèi)核
    [root@localhost linux-3.12.2]# make menuconfig

http://wiki.jikexueyuan.com/project/learn-linux-step-by-step/images/19.bmp" alt="" />

配置項(xiàng)主要分為3中選擇類型

:不參加編譯 參加編譯 以內(nèi)核模塊形式參加編譯 ![](images/20.bmp) 3. 配置完畢后,會生成一個(gè).config 文件保存剛才的配置信息 ``` [root@localhost linux-3.12.2]# ll -a -rw-r--r-- 1 root root 107133 04-03 15:08 .config ``` 4. 清理上一次緩沖后開始編譯內(nèi)核 ``` [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步選擇的內(nèi)核模塊 ``` [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 =>編譯完成內(nèi)核模塊但未安裝,所以在/lib/modules/下并未產(chǎn)生任何內(nèi)核模塊 ``` 6.安裝內(nèi)核模塊,在/lib/modules/會產(chǎn)生對應(yīng)版本的內(nèi)核模塊庫 ``` [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 =>到處為止內(nèi)核與內(nèi)核模塊已經(jīng)編譯安裝完畢 ``` 7.利用 GRUB 做一個(gè)多重引導(dǎo),新的引導(dǎo)加載剛編好的內(nèi)核 ``` [root@localhost ~]# cp /usr/src/kernels/linux-3.12.2/arch/x86/boot/bzImage /boot/vmlinuz-3.12.2 ``` 8.創(chuàng)建虛擬文件系統(tǒng) ``` [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. 將內(nèi)核配置信息保存以便下回使用 ``` [root@localhost kernels]# cp /usr/src/kernels/linux-3.12.2/.config /boot/config-3.12.2 ``` 10. 編輯 menu.lst 添加新的指向新內(nèi)核的引導(dǎo) ``` [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.重啟之后查看內(nèi)核版本 ``` [root@localhost ~]# uname -r 3.12.2.3 =>已經(jīng)是最新的內(nèi)核了 ``` **總結(jié)起來編譯內(nèi)核主要分為這么幾步** **1. 配置內(nèi)核**make menuconfig **2. 清除緩存**make clean **3. 編譯內(nèi)核**make bzImage **4. 編譯內(nèi)核模塊**make modules **5. 安裝內(nèi)核模塊**make modules_install ## 獨(dú)立內(nèi)核模塊的編譯 在內(nèi)核編譯的時(shí)候我們可以通過內(nèi)核菜單選擇內(nèi)核模塊進(jìn)行編譯。但如果內(nèi)核已經(jīng)編譯完成,此時(shí)有新的硬件產(chǎn)生,但是內(nèi)核菜單并沒有此新硬件對應(yīng)的驅(qū)動,那怎么編譯其對應(yīng)的內(nèi)核模塊,即使內(nèi)核菜單存在此驅(qū)動,難道還需要重新編譯內(nèi)核?這就需要進(jìn)行獨(dú)立內(nèi)核模塊的編譯來解決了。 簡單的說,獨(dú)立內(nèi)核模塊編譯,就是單獨(dú)編譯一個(gè)內(nèi)核模塊,并將內(nèi)核模塊添加到內(nèi)核管理器。這樣內(nèi)核就可以使用新增加內(nèi)核模塊而不需要重新編譯了 ``` [root@bogon shared]# tar -jxvf r8168-8.038.00.tar.bz2 =>解壓縮內(nèi)核模塊 [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 =>編譯內(nèi)核模塊 [root@localhost r8168-8.038.00]# make install =>安裝內(nèi)核模塊 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 =>內(nèi)核模塊已經(jīng)安裝成功 [root@localhost ~]# depmod –a =>建立內(nèi)核模塊依賴關(guān)系 [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 已經(jīng)被修改 ``` **總結(jié)起來編譯獨(dú)立內(nèi)核模塊主要分為這么幾步** **1. 清除緩存** make clean **2. 編譯內(nèi)核模塊** make modules **3. 安裝內(nèi)核模塊** make install **4. 建立依賴關(guān)系** depmod –a **說明:上面只是將內(nèi)核模塊編譯與安裝,還未將內(nèi)核模塊加載到內(nèi)核,因此還需使用 insmod 進(jìn)行內(nèi)核模塊的加載** ## 內(nèi)核模塊管理 ### 內(nèi)核模塊依賴性 內(nèi)核模塊存放在/lib/modules/$(uname –r)/kernel 當(dāng)中,其中內(nèi)核模塊一直是存在依賴性的。這些依賴關(guān)系記錄在/lib/modules/$(uname –r)/modules.dep 當(dāng)我們增加會減少內(nèi)核模塊時(shí)就要修改內(nèi)核模塊之間的依賴關(guān)系。依賴關(guān)系的修改可以通過 depmod 命令來進(jìn)行 語法:depmod depmod [-Anea] 選項(xiàng)與參數(shù): 不加參數(shù):分析目前所有內(nèi)核,模塊并重寫寫入 -A:只分析比 modules.dep 記錄還新的內(nèi)核模塊。才會更新 -n: 不寫入 modules.dep 只輸出到聘雇 -e: 顯示目前已經(jīng)加載的不可執(zhí)行的模塊名稱 -a:分析所有可用模塊 ### 內(nèi)核模塊的查看 **查看所有內(nèi)核模塊** lsmod **查看指定名稱的內(nèi)核模塊** modinfo 模塊名稱 [root@bogon kernels]# lsmod ``` Module Size Used by ppdev 12613 0 autofs4 28997 3 hidp 22977 2 => Used by 代表此內(nèi)核模塊被其他內(nèi)核模塊所使用 [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 ``` ### 內(nèi)核模塊的加載與刪除 **內(nèi)核模塊加載** Insmod 內(nèi)核模塊絕對路徑 ``` [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 ``` **內(nèi)核模塊刪除** rmmod 內(nèi)核模塊絕對路徑 ``` [root@localhost ~]# rmmod /lib/modules/2.6.18-371.el5/kernel/drivers/net/r8168.ko [root@localhost ~]# lsmod|grep r8168 ``` ### modprobe 內(nèi)核模塊處理 使用上面的方法可以管理內(nèi)核模塊,但是需要指定內(nèi)核模塊的完整路徑,同時(shí)如果要刪除某個(gè)內(nèi)核模塊時(shí)如果存在依賴關(guān)系,則無法刪除成功。使用modprobe 可以避免此問題 Modprobe 去 modules.dep 中尋找內(nèi)核模塊因此不需要指定絕對路徑(前提我們已經(jīng)使用的 depmod 將依賴關(guān)系寫入該文件) **語法:**modprobe[-lfr] 內(nèi)核模塊名稱 **選項(xiàng)與參數(shù):** -l:列出所有內(nèi)核模塊 -f:強(qiáng)制加載內(nèi)核模塊 -r:刪除內(nèi)核模塊 **舉例:** ``` [root@localhost ~]# modprobe vfat =>加載內(nèi)核模塊 [root@localhost ~]# lsmod |grep vfat vfat 15937 0 [root@localhost ~]# modprobe -r vfat =>刪除內(nèi)核模塊 ```