一、簡介
這就是能在windows環(huán)境下直接編譯的Linux 0.11了,不是在Cygwin,也不是在虛擬機里,而是使用MinGW gcc, 這是GNU gcc在Windows下的移植版本.在oldlinux上的論壇看見有許多人在問怎樣在Windows下直接編譯, 最佳答案應(yīng)該是使用Cygwin,現(xiàn)在看來這個最佳答案該改了。本編譯環(huán)境源代碼加上gcc編譯器壓縮后才4.2兆。 ![]() 二、編譯過程: 1. 解壓后默認(rèn)的文件夾位置是在D:\Linux-0.11,如果你不是將文件解壓到該目錄下, 你要修改MinGW32目錄下的MinGW32.bat文件,將里面的PATH指向MinGW32的bin目錄. 2. 打開Linux-0.11目錄,雙擊MinGW32.bat快捷方式,打開控制臺. 3. make 一下,生成1.44M的Boot.img軟盤鏡像,要清除編譯結(jié)果請"make clean" 4. 如果安裝了bochs,直接雙擊bochsrc.bxrc即可運行Linux-0.11了. 5. 也可用其它虛擬機加載Boot.img后運行,如果出現(xiàn)Kernel panic,請把虛擬機里的硬盤刪了 6. 在出現(xiàn)Insert root floppy and press ENTER以后,將rootimage-0.11.img載入虛擬軟驅(qū),回車 三、在Windows下編譯Linux 0.11會遇到的問題和對原文件作的修改: 1.趙炯博士已經(jīng)將匯編程序中引用的C變量(包括嵌入?yún)R編的C變量)的下劃線去掉了,但MinGW的gcc可能是為了與其它Windows下的編譯器 保持兼容,并不能識別這些不帶下劃線的C變量,因而還得把原先已經(jīng)在匯編程序中去掉下劃線的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函數(shù),編譯成sync.exe 因為類似的原因,make dep會出錯 4.生成的system文件是PE格式的(PE是Portable Executable的簡稱),這是windows下的可執(zhí)行文件的格式,顯然是不能直接執(zhí)行的, 必須加以轉(zhuǎn)化.我實現(xiàn)了通過兩種方式加以轉(zhuǎn)化. 1)寫一個程序Trans.cpp將system.exe里的代碼和數(shù)據(jù)從PE文件里解析出來,生成一個system.bin文件,這個文件是能被setup模塊 加載的.我已經(jīng)將這個程序放在了Linux-0.11的tools目錄下,要微軟的編譯器編譯. 2)自己寫一個PE Loader,這種方式比較麻煩,實現(xiàn)原理卻和Trans.cpp差不多,只是要用匯編來寫. 但是當(dāng)Linux-0.11真的能運行的時候,還是滿有成就感的. 盡管這是一個最簡單的Loader.代碼是加在Linux-0.11-With-PE-Loader\boot目錄下的setup.asm文件里,里面有詳細(xì)的注釋. 5.對tools下的build.c作了修改,使其能在windows下生成可引導(dǎo)的1.44M的軟盤鏡像文件Boot.img 6.在Link的過程中,init目錄下的main.c會出現(xiàn)以下錯誤: 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根本沒有這個函數(shù),在gcc的編譯選項里 也有-nostdinc .有一個解釋是main函數(shù)不是一個普通的函數(shù),為了使main能正常運行,至少要加alloca這個內(nèi)存分配函數(shù).解決的辦法其實也很簡單, 把main.c下面的main函數(shù)改名為_main,或者是干脆把它改成另外一個函數(shù),就改成start吧.記得把head.s里的_main也改了. 在最后,要感謝《自己動手寫操作系統(tǒng)》的作者于淵,其實我也是先將原先只能在Linux下編譯的書里源代碼 用MinGW移植到Windows下編譯的過程中才試著在Windows下編譯Linux 0.11源代碼的. 有了在Windows下編譯Linux 0.11源代碼的經(jīng)驗,移植高版本的源代碼,像0.12,0.95,0.96等等版本應(yīng)該不會有太大的麻煩了。 也要感謝《Linux內(nèi)核完全注釋》的作者趙炯博士,是他寫了這樣一本務(wù)實的書,并且不余余力的對操作系統(tǒng)愛好者加以幫助, 包括建了一個很好的論壇。當(dāng)然,能編譯源代碼并不等于對源代碼都懂了,這離真正完全理解源代碼還很遠(yuǎn)。 我想源代碼還有許多地方是值得我去細(xì)細(xì)深究的。當(dāng)然有了能直接在Windows下編譯的Linux源代碼,我想整個進(jìn)展會快得多。 碰到模糊不清的地方,改改源代碼,加加printf,make ,幾秒鐘的事情。bochs調(diào)試,再make,再調(diào)試。。。 我也非常想和操作系統(tǒng)愛好者們共同交流心得體會,借此也希望能多認(rèn)識一些朋友。 我的網(wǎng)名:flyfish 我的QQ:785606288 E-mail:I2CBus@126.com http://www./oldlinux/viewthread.php?tid=11005&extra=page%3D1 |
|