2008年9月15日 星期一

linux 2.6 模組編譯

在演練Linux driver的過程中,需要一個核心樹來幫助編譯(讓程式可以引用核心function call. struct. type 和 macro等),知道核心提供哪些功能,

在Linux driver聖經版的內容中,作者都建議讀者能編譯一個新核心,給開發系統使用(註一),不過這樣很費時,且CD所附的核心樹常會沒法編譯(kernel-devel-2.6.15-1.2054_FC5.i686.rpm),

在以前linux 2.4的模組的演練上,我會直接從kernel.org 找一個適合的核心(和開發系統最接近的),然後將相關"Inclde 路徑"和 "Define" 設定好,就可以練習了(註二),所以基本上只引用核心樹裡 include/linux 和 include/asm 內的標頭檔,並沒有將開發系統的核心換掉,算是一個省時間且取巧的方法,

不過在linux 2.6上(註三),模組載入進核心,需要透過一個vermagic.o的目的檔去驗證,才可以通過,因此想著,如果可以產生適當的vermagic.o(modinfo所秀出來的資訊),應該就可以騙過核心,載入成功吧,

然而結果是,失敗...,所以只好乖乖的將整個開發系統的核心換掉,才能順利載入和卸載 "Hello world" 的範例,不過這過程也讓我知道核心設定的相關作用,在這裡紀錄一下...

底下是核心設定的細節在FC5上
目標是希望產生的模組,其vermagic : 2.6.15-1.2054_FC5 686 REGPARM 4KSTACKS gcc-4.1,是如此.....
核心盡量在最小的情況下編譯成功,產生所需要的vermagic.o的檔案,讓module可以連結

下載linux-2.6.15.tar.gz
核心設定:

修改核心樹最上層的Makefile(例如/usr/src/linux-2.6.15.1/Makefile),找到 EXTRAVERSION,
修改EXTRAVERSION = -1.2054_FC5

Code maturity level options --->
    [*] Prompt for development and/or incomplete code/drivers (CONFIG_EXPERIMENTAL)
Loadabel module suppoer --->
    [*]Enable loadable module support (CONFIG_MODULES)
為了產生 scripts/mod/modpost

    [*] Module versioning support (EXPERIMENTAL) (CONFIG_MODVERSIONS)
為了 "no version for struct_module found" 的錯誤

    [*] Source checksum for all modules (CONFIG_MODULE_SRCVERSION_ALL)
為了 "srcversion:",在modinfo秀出來

Processor type and features --->
    [*] Use register arguments (EXPERIMENTAL) (CONFIG_PARAM)
為了產生vermagic的 "REGPARAM" 字串

Kernel hacking --->
    [*]Kernel debugging (CONFIG_DEBUG_KERNEL)
        [*] Use 4Kb for kernel stacks instead of 8Kb (CONFIG_4KSTACKS)
為了產生vermagic 的 "4KSTACKS"字串


註一:其實應該說給開發系統和目標系統使用,不過由於是練習,沒有跨平台編譯的問題,所以只提開發系統
註二:linux 2.4的module編譯方法,請參考linux driver 第二版
註三:linux 2.6的module編譯方法,請參考linux driver 第三版


在這裡是參考Gavin's Linux的說明,來做Linux的核心編譯,並置換開發系統的核心
修改核心樹最上層的Makefile,找到EXTRAVERSION,修改EXTRAVERSION = -test

cp -rf /boot/config-2.6.15-1.2054_FC5 /usr/src/linux-2.6.15/.config (用現在使用的核心的設定來覆蓋)

make oldconfig (只對之前沒有的核心選項提問)

make bzImage modules modules-install (這裡很耗時)

make install (將核心的 .config ,map ,vmlinuz 複製到/boot,並增加了grub.conf的選項)

修改/boot/grub/grub.conf, default=0 (因為它會插到最前面)

reboot,uname -r後,秀出 2.6.15-test,完成


相關連結: The Complete Fedora Kernel Headers
註:可惜太晚才找到這文章,這招也可以試試...