最近在看《x86_x64體系探索及編程》,在制作可供bochs使用的硬盤鏡像時出了一些問題,主要有以下幾個:
步驟
如書中所說,做了:
- [x] 使用bximage生成了硬盤鏡像
- [x] 對bochs的配置文件進行了配置
- [x] 利用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的意思就是不要截斷。
- [x] 使用以下語句啟動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、重新編譯