windows下編譯linux0.11內核

真正能在windows下編譯的linux 0.11,不是在Cygwin,也不是在虛擬機裏!
2008年09月18日 星期四 21:30
一、簡介  
這就是能在windows環境下直接編譯的Linux 0.11了,不是在Cygwin,也不是在虛擬機裏,而是使用MinGW gcc,
這是GNU gcc在Windows下的移植版本.在oldlinux上的論壇看見有許多人在問怎樣在Windows下直接編譯,
最佳答案應該是使用Cygwin,現在看來這個最佳答案該改了。本編譯環境源代碼加上gcc編譯器壓縮後才4.2兆。
二、編譯過程:

1.   解壓後默認的文件夾位置是在D:\Linux-0.11,如果你不是將文件解壓到該目錄下,
    你要修改MinGW32目錄下的MinGW32.bat文件,將裏面的PATH指向MinGW32的bin目錄.
2.   打開Linux-0.11目錄,雙擊MinGW32.bat快捷方式,打開控制檯.
3.   make 一下,生成1.44M的Boot.img軟盤鏡像,要清除編譯結果請"make clean"
4.   如果安裝了bochs,直接雙擊bochsrc.bxrc即可運行Linux-0.11了.
5.   也可用其它虛擬機加載Boot.img後運行,如果出現Kernel panic,請把虛擬機裏的硬盤刪了
6.   在出現Insert root floppy and press ENTER以後,將rootimage-0.11.img載入虛擬軟驅,回車


三、在Windows下編譯Linux 0.11會遇到的問題和對原文件作的修改:

1.趙炯博士已經將彙編程序中引用的C變量(包括嵌入彙編的C變量)的下劃線去掉了,但MinGW的gcc可能是爲了與其它Windows下的編譯器
   保持兼容,並不能識別這些不帶下劃線的C變量,因而還得把原先已經在彙編程序中去掉下劃線的C變量加上下劃線,同時也要把被C程序
   引用的彙編程序中的變量加上下劃線.

2.MinGW中不帶as86編譯器,因而把boot目錄下原先用as86編譯的bootsect.s和setup.s兩個程序修改成能用nasm編譯的程序.
   並且更名爲bootsect.asm和setup.asm.

3.在Makefile作的主要修改:
   在LDFLAGS中加了--image-base 0x0000   將elf_i386改成i386pe
   將cd 與 make 之間的;改成&,如cd kernel ; make 改成cd kernel & make
   MinGW中沒有sync這個程序,可以把它註釋掉,更簡單的辦法是寫一個sync.c,這個sync.c只包含一個空的main函數,編譯成sync.exe
   因爲類似的原因,make dep會出錯

4.生成的system文件是PE格式的(PE是Portable Executable的簡稱),這是windows下的可執行文件的格式,顯然是不能直接執行的,
   必須加以轉化.我實現了通過兩種方式加以轉化.
1)寫一個程序Trans.cpp將system.exe裏的代碼和數據從PE文件裏解析出來,生成一個system.bin文件,這個文件是能被setup模塊
   加載的.我已經將這個程序放在了Linux-0.11的tools目錄下,要微軟的編譯器編譯.
2)自己寫一個PE Loader,這種方式比較麻煩,實現原理卻和Trans.cpp差不多,只是要用匯編來寫.
   但是當Linux-0.11真的能運行的時候,還是滿有成就感的.
   儘管這是一個最簡單的Loader.代碼是加在Linux-0.11-With-PE-Loader\boot目錄下的setup.asm文件裏,裏面有詳細的註釋.

5.對tools下的build.c作了修改,使其能在windows下生成可引導的1.44M的軟盤鏡像文件Boot.img

6.在Link的過程中,init目錄下的main.c會出現以下錯誤:
boot/head.o(.text+0x540c):fake: undefined reference to `_main'
init/main.o(.text+0x16f):main.c: undefined reference to `_alloca'
init/main.o(.text+0x174):main.c: undefined reference to `__main'
make: *** [tools/system.exe] Error 1
第一個和最後一個錯誤還好理解,但中間那個錯誤那就莫明其妙了,因爲Linux 0.11根本沒有這個函數,在gcc的編譯選項裏
也有-nostdinc .有一個解釋是main函數不是一個普通的函數,爲了使main能正常運行,至少要加alloca這個內存分配函數.解決的辦法其實也很簡單,
把main.c下面的main函數改名爲_main,或者是乾脆把它改成另外一個函數,就改成start吧.記得把head.s裏的_main也改了.

在最後,要感謝《自己動手寫操作系統》的作者於淵,其實我也是先將原先只能在Linux下編譯的書裏源代碼
用MinGW移植到Windows下編譯的過程中才試着在Windows下編譯Linux 0.11源代碼的.
有了在Windows下編譯Linux 0.11源代碼的經驗,移植高版本的源代碼,像0.12,0.95,0.96等等版本應該不會有太大的麻煩了。
也要感謝《Linux內核完全註釋》的作者趙炯博士,是他寫了這樣一本務實的書,並且不余余力的對操作系統愛好者加以幫助,
包括建了一個很好的論壇。當然,能編譯源代碼並不等於對源代碼都懂了,這離真正完全理解源代碼還很遠。
我想源代碼還有許多地方是值得我去細細深究的。當然有了能直接在Windows下編譯的Linux源代碼,我想整個進展會快得多。
碰到模糊不清的地方,改改源代碼,加加printf,make ,幾秒鐘的事情。bochs調試,再make,再調試。。。
發佈了10 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章