一、為什麼要學習內核?
有些人要學習內核,而有些人則可以不學習它。你如果以後要從事系統研發或驅動開發的話,就要學習內核。
剛剛接觸內核,主要學習內核的接口函數。不要深入的去讀內核,因為你讀也讀不懂,內核代碼龐大如野獸一般不可駕馭。
學習內核主要掌握層次學習法,即從頭開始學習,一環緊扣一環。
內核學習的四步學習法:1、核心理論學習-概念與函數原型2、范例程序分析3、思維導圖設計4、親自編寫代碼
二、linux內核簡介
1、linux體系結構
分為兩部分:用戶空間和內核空間
2、linux為什麼要分為用戶空間和內核空間
現代CPU通常實現了不同的工作模式,以ARM為例,實現了7中工作模式。X86實現了4中不同的級別:Ring0-Ring3. Ring0下可以執行特權指令,可以訪問IO設備等,在Ring3則有很多限制。linux系統利用CPU的這一特性,使用了其中兩個級別分別運行linux內核與應用程序,這樣使操作系統本身得到充分的保護。例如:如果使用X86,用戶代碼運行在Ring3,內核代碼運行在Ring0.內核空間與用戶空間是程序執行的兩種不同狀態,通過系統調用和硬件中斷能夠完成從用戶空間到內核空間的轉移。
3.linux的內核構架
系統調用接口
SCI層為用戶空間提供了一套標准的系統調用函數來訪問Linux內核,搭起了用戶空間到內核空間的橋梁。
進程管理(PM)是創建進程,停止進程,並控制它們之間的通信。進程管理還包括控制活動進程如何共享CPU,即進程調度。
內存管理(MM)的主要作用是控制多個進程安全地共享內存區域。
網絡協議棧(Network Stack)為linux提供了豐富的網絡協議實現。
虛擬文件系統(VFS)隱藏各個文件系統的具體細節,為文件操作提供統一的接口。
設備驅動(DD):linux內核中有大量代碼都在設備驅動程序中,它們控制特定的硬件設備。
三、linux內核源代碼結構
1、下載源代碼地址www.kernel.org
2、linux內核源代碼采用樹形結構進行組織,非常合理地把功能相關的文件都放在同一個子目錄下,使得程序更具可讀性。
arch目錄:arch是architecture的縮寫。內核所支持的每種CPU體系,在該目錄下都有對應的子目錄。每個cpu的子目錄,又進一步分解為boot,mm,kernel等子目錄,分別包含控制系統引導,內存管理,系統調用等。/* X86英特爾cpu與之相兼容體系結構的子目錄:boot 引導程序compressed內核解壓縮 tools生成壓縮內核映像的程序 kernel相關內核特性實現方式,如信號處理、時鐘處理 lib 硬件相關工具函數*/
documentation內核文檔
drivers設備驅動文檔
include內核所需要的頭文件。與平台無關的頭文件在include/linux子目錄下,與平台有關的頭文件則放在相應的子目錄中。
fs目錄存放各種文件系統的實現代碼。每個子目錄對應一種文件系統的實現,公用的源程序用於實現虛擬文件系統vfs
"|--devpts是/dev/pts虛擬文件系統
||--ext2是第二擴展文件系統
||--fat是MS的fat32文件系統
||--isofs 是IsO9660光盤cd-rom上的文件系統
net是網絡協議的實現代碼
||--802 802無線通訊協議核心支持代碼
||--appletalk 與蘋果系統連網的協議
||--ax25 AX25無線INTERNET協議
||--bridge 橋接設備
||--ipv4 IP協議族V4版32位尋址模式
||--ipv6 IP協議族V6版
四、linux內核的配置和編譯
代碼是如何轉化為燒寫或安裝到硬件平台中的系統映像文件的?
1、為什麼要配置內核
選出需要的,去掉不要的!1、硬件的需求2、軟件的需求
下載內核後要在linux中解壓縮,不要在windows下解壓縮因為windows下不區分大小寫,而linux操作系統區分大小寫。
進入內核的文件下:
2、內核的配置:
make config:基於文本模式的交互式配置
make menuconfig:基於文本模式的菜單型配置
<*>文件經過編譯由.c文件到.o文件,最後鏈接壓縮為內核鏡像,它存放在內存。
< >表示不選擇該功能
配置結果文件是隱藏文件,可以用ls -a 在內核文件下查看.config version
上面介紹的是一種方法,不過作為初學者我們往往是在一個已有的配置文件基礎上,通過修改得到新的配置文件,linux內核提供了一系列可供參考的內核配置文件,位於Arch/cpu/configs
接下來,我們利用虛擬機上的linux系統的配置文件來創建自己的升級版內核,並在虛擬機上運行該內核。
圖:
3、編譯內核(編譯內核、編譯內核模塊、制作ramdisk)
3.1、編譯內核
make zImage只能編譯小於512K的內核
make bzImage我們一般會使用這種方法編譯內核
如需獲取詳細編譯信息,可使用:
make zImage V=1
make bzImage V=1
編譯好的內核位於arch/cpu/boot/目錄下***
3.2編譯內核模塊
make modules 編譯內核模塊
make modules_install 將編譯好的內核模塊,從內核源代碼目錄復制到/lib/modules下**,為打包做好准備
經過第一步編譯後,散落在各個文件下的.ko文件為內存模塊。需要集中移動到/lib/modules這個就由make modules_install來完成
3.3制作init ramdisk
方法:mkinitrd initrd-$version $version
例如:mkinitrd initrd-2.6.32 2.6.32
通過uname -r 獲得正在運行的內核版本
*$version可以通過查詢/lib/modules下的目錄得到
4、安裝內核
1、cp arch/x86/boot/bzImage
/boot/vmlinuz-$version
2、cp initrd-$version /boot/
3、修改/etc/grub.conf的後四行
5、清理內核
make clean 清理編譯內核生產的.o文件
make distclean 清理編譯內核生產的.o文件和.config $version
記憶幾個命令
rpm -qa | grep kernel 找到內核包信息
rpm -e kernel-內核包名