最近在看《x86_x64體系探索及程式設計》,在制作可供bochs使用的硬碟鏡像時出了一些問題,主要有以下幾個:
步驟
如書中所說,做了:
- 使用bximage生成了硬碟鏡像

- 對bochs的配置檔案進行了配置
- 利用dd工具将uboot, setup, lib16二進制檔案導入到hello.img中,使用的指令為:
dd if=uboot of=hello.img seek=63 count=1 conv=notrunc
dd if=setup of=hello.img seek=1 count=1 conv=notrunc
dd if=lib16 of=hello.img seek=20 count=1 conv=notrunc
這裡需要說明, dd的if選項為輸入, of選項為輸出,seek跳過輸出的幾個單元開始寫,一個單元512個位元組,count是寫的單元數,尤其要注意的是conv選項,鄧志的書中并未加conv選項,這導緻輸出檔案被截斷,不能保持原本的大小,notrunc的意思就是不要截斷。
- 使用以下語句啟動bochs
bochs -f bxrc
# 執行上面的語句後需要在terminal中輸入c,意為continue,bochs才會繼續執行
現象
Boot failed: not a bootable disk.
分析
- 能夠進入最後一個界面,說明bochs的配置檔案沒有問題,那麼問題一定出在鏡像hello.img上,hello.img和随書提供的源碼中的c.img有何不同呢?我用hex軟體看了一下,hello.img的前512個位元組是空的,而c.img中有一些内容,書上說硬碟的第一個單元是用來存放MBR的,當從硬碟啟動時,先将MBR載入到0x7C00,再由MBR讀取位于第64個單元的boot程式,是以MBR非常重要。仔細分析後發現原來我們使用bximage産生的hello.img并不自帶MBR,是以我将c.img中的前512個位元組寫入了hello.img,使用下面的代碼:
dd if=c.img of=hello.img seek=0 count=1 conv=notrunc
但是運作
bochs -f bxrc
# 執行上面的語句後需要在terminal中輸入c,意為continue,bochs才會繼續執行
之後仍然出現Boot failed: not a bootable disk.
- 那麼出問題一定在setup二進制檔案了,因為這個實驗中最後起作用的就是setup檔案,在螢幕上顯示。是以我使用nasm重新編譯了setup.asm,編譯過程中出現了類似于can’t open xxx.inc之類的錯誤,原因就是linux使用…/作為上級目錄的代替,而windows使用的是…\,隻要将…\換為…/…/就可以編譯通過。重新編譯setup.asm,将新生成的setup寫入hello.img,運作bochs
結果
成功了!!!
總結
1、MBR
2、重新編譯
3、帶有MBR的硬碟鏡像,1M大
注意,使用該鏡像時,除了sector0中的MBR,之後每次實驗時都應該更新鏡像中的其它sector,如boot(如果你需要調試boot),setup等。