天天看點

20130718:Linux核心編譯

最近在學習《作業系統概念》一書,有些實驗需要在系統核心中增加一些新的系統調用,由此便産生了修改核心源碼并重新編譯生成新核心的需求。我的思路是

首先搞定核心編譯的流程,確定有個可用的實驗環境,在此基礎上再按照《作業系統概念》中的方法增加新的系統調用在核心中。

編譯環境簡單介紹下。

編譯用的系統:Fedora core3,對應核心版本為2.6.9-1.677,gcc、make等都是fc3自帶的,gcc是3.4.2,make是3.80,x86平台。

最開始下載下傳了個2.6.36的核心源碼,分别執行指令【make menuconfig】-【make bzImge】-【make modules】-【modules_install】-【make install】後,編譯

生成的核心确實被部署在/boot/下,grub.conf中也增加了相應的啟動項,但選中這一核心啟動時便提示錯誤,目前沒有搞明白到底是為什麼,初步懷疑是新核心和

fc3系統的一些部分不相容導緻,因為目的是為了確定有個編譯核心并可用的環境,便沒有深究。

drivers/scsi/qla2xxx/qla_os.c: In function `qla2x00_queuecommand':
drivers/scsi/qla2xxx/qla_os.c:315: sorry, unimplemented: inlining failed in call to 'qla2x00_callback': function not considered for inlining
drivers/scsi/qla2xxx/qla_os.c:269: sorry, unimplemented: called from here
drivers/scsi/qla2xxx/qla_os.c:315: sorry, unimplemented: inlining failed in call to 'qla2x00_callback': function not considered for inlining
drivers/scsi/qla2xxx/qla_os.c:269: sorry, unimplemented: called from here
make[3]: *** [drivers/scsi/qla2xxx/qla_os.o] 錯誤 1
make[2]: *** [drivers/scsi/qla2xxx] 錯誤 2
make[1]: *** [drivers/scsi] 錯誤 2
make: *** [drivers] 錯誤 2
           

接下來下載下傳了和fc3核心對應的2.6.9的源碼,但在【make modules】時總是不成功,提示資訊大概是與scsi相關的一些函數不是inline類型的,把【make bzImage】

生成的核心拷貝到/boot/下,并在grub.conf中增加相應啟動項,結果啟動菜單中選擇新編譯的核心啟動時提示“unrecognized file format”,仔細檢查發現把核心搞

錯了,把源碼目錄linux-2.6.9下生成的vmlinux檔案當做核心了,(雖然咨詢過朋友說這個也是核心,但很明顯檔案格式都不一樣),正确的應該用linux-2.6.9/arch/i386/

boot/目錄下的bzImage,朋友們千萬記住了哦。很遺憾的是即便用了正确的核心,發現啟動過程中又提示無法加載/lib/modules等,總之依然報錯,隻是錯誤發生在啟動

過程中了,同樣,也沒有時間去找原因。

最後,找了個Fedora Core14的系統,對應核心版本為2.6.35.6,gcc版本是4.5.1,make版本是3.82,依然是x86平台。下載下傳與之對應的2.6.35.6的源碼,解壓至/usr/src下,

便生成了源碼目錄/usr/src/linux-2.6.35.6。編譯核心的過程如下:

[[email protected]]#mv linux-2.6.35.6.tar.gz /usr/src

[[email protected]]#tar -xvzf linux-2.6.35.6.tar.gz

[[email protected]]#cd linux-2.6.35.6

[[email protected]]#make mrproper                           

[[email protected]]#make menuconfig                      # 配置核心

[[email protected]]#make dep                                     # 建立核心配置的依賴關系樹

[roo[email protected]]#make clean                                  # 清楚舊版的*.o檔案

[[email protected]]#make bzImage                            # 制作核心檔案

[[email protected]]#make modules                           # 制作相關子產品

[[email protected]]#make modules_name              # 安裝子產品到/lib/modules/`uname -r` 目錄

[[email protected]]#make install                                # 安裝核心檔案到目錄/boot

這時切換到/boot/下發現新的核心已經在了,grup.conf中也增加了相應的啟動項,重新開機系統,選擇編譯後的新核心,成功啟動。

下面對這個過程中自己所了解的一些東西進行描述,如有不當之處,歡迎各位指正。

make mrproper---這個指令用來確定源代碼目錄下沒有不正确的目标.o檔案以及檔案的互相依賴,同時,還會删除源碼目錄下

的.config檔案。.config檔案中儲存的是核心配置,新下載下傳的源碼包中是沒有的,而且也不會存在不正确的.o檔案等,是以這一步

對新下載下傳的源碼包可以省略。當你要對現有系統更新核心,而不修改核心的相關配置時,可以将目前系統的.config檔案

(如果能找到的話O(∩_∩)O)拷貝到源碼目錄下使用。這一指令建議都執行一下,確定核心源碼包中的内容是幹淨的。

有人說這一步後要確定/usr/include/目錄下的asm、linux、scsi等連接配接是指向要更新的核心源碼的,我沒明白是為什麼,也沒有

做這一步。

make menuconfig---這是最常用來配合核心選項的指令,是基于文本選項的配置界面,字元終端下推薦使用。網上有人說要使用

這個指令必須安裝ncurses-dev和tk4-dev庫,因為我的機器上預設就能用,是以也沒有驗證這一點。當然還有基于文本的【make config】

和基于圖形視窗的【make xconfig】(xwindows下推薦使用)。另外,【make oldconfig】據說是如果隻想在原來核心配置的基礎上

修改一些小地方可以使用,應該和上面說的“更新現有核心”但不修改配置等同,沒有驗證。

配置完成後儲存退出,也會生成.config檔案。

make dep---此指令用啦讀取配置過程生成的.config配置檔案,并建立對應于配置的依賴關系樹,進而确定哪些需要編譯,哪些不需要

編譯。不過大家都說這條指令在2.6及以後的核心編譯中都不再需要,如果執行就會出現“***Warning: make de is unnecessary now”

的提示。我編譯2.6.9和2.6.35.6的核心時都執行過,确實是這個提示。

make bzImage----這個就是編譯核心的指令了。此外還有【make zImage】,但zImage是用gzip壓縮的,适合存儲在軟碟上。bzImage

是更大的超過軟碟空間限制的壓縮核心,我這裡用的是bzImage。這個指令在目錄/usr/src/linux-2.6.35.6/arch/i386/boot/下建立bzImage

檔案,當然,這個檔案是一個連結,指向../../x86/boot/bzImage,也就是真正的核心檔案。

make modules---這個指令用來編譯以生成相應的核心子產品。

make modules_install---這個指令會在/lib/modules/目錄下生成相應的2.6.35.6目錄,該目錄下即為編譯過的核心子產品。

/lib/modules/x.y.z是子產品在系統中的标準目錄。

make install---安裝核心。這一指令會将生成的/usr/src/System.map、/usr/src/linux-2..35.6/arch/i386/boot/bzImage拷貝

到/boot/下,并修改grub.conf啟動菜單配置,實際上就是将編譯出的核心安裝到目前系統中。

至此,編譯核心過程完成,而且已經安裝到目前系統,重新開機系統發現啟動項中多了新核心的啟動項,選擇之,啟動即可。

【make modules】 以及【make modules_install】指令有人說不必要,目前為止我還沒搞清楚它和編譯核心的關系,但

感覺其生成的核心子產品(即*.ko)檔案在核心運作過程中若需要加載時是需要的,是以建議還是一起做了。

補充:

額外子產品的安裝。----------------這是從網上摘抄的,沒有試驗過。

比如我現在給機器加了個Intel 3945的無線網卡,那麼要使其能正常使用,就要安裝其對應的驅動子產品。

tar -xvzf ipw3945-1.2.2.gz

cd ipw3945-1.2.2

将編譯出來的子產品檔案ipw3945.ko一道核心目錄,并更新子產品的依賴屬性:

cp ipw3945.ko /lib/modules/`uname -r`/kernel/drivers/net

cd /lib/modules/`uname -r`

depmod -a

開機自動加載子產品:

cd /etc/sysconfig/modules

echo "modprobe ipw3945" >> my.modules

chmod 755 my.modules

重新開機後檢視子產品是否加載:

lsmod |grep ipw3945

ps:每次更新kernel後需要重新編譯一次額外添加的子產品。

核心子產品管理:

lsmod :列出所有子產品

modinfo:檢視子產品資訊

modprobe:-c      檢視配置檔案

                       -l       列出所有子產品

                       -r      移除子產品

insmod:插入子產品

rmmod:删除子產品