自 http://bbs.pediy.com/showthread.php?t=123767&highlight=bochs
一、環境配置:
操作系統:Microsoft Windows XP Professional Service Pack 3
調試工具:bochs 2.4.0.0
1、安裝:Bochs
Bochs是一種十分輕便的使用c++編寫的開源IA-32(x86)電腦模擬器,可以運行在最受歡迎的平臺上。它仿真英特爾x86 CPU、常見的I/O設備、和定製的BIOS。目前,Bochs可以被編譯仿真386、486、Pentium/PentiumII/PentiumIII/Pentium4或x86-64位的CPU,包括可選的MMX,SSEx和3DNow指令。在Bochs仿真環境裏能夠運行許多操作系統,比如Linux、DOS、Windows 95/98/NT/2000/XP或者Windows Vista。Bochs是由凱文·勞頓編寫的,目前由“http://bochs.sourceforge.net”的Bochs項目組維護。
如果論性能的話bochs遠不及VMware等其他虛擬機,但在調試方面,bochs卻有其它虛擬機所不及的優越之處。本文主要介紹如何配置bochs調試環境以及如何用bochs調試MBR程序。重點介紹調試環境配置方法和簡單的MBR實例調試。並不對調試MBR做詳細分析。主要是做一個文檔型的記錄。因爲本人在使用bochs調試這個過程中摸索了相當長時間,也走了不少彎路。所以如果這個文檔能給一些人帶來些許幫助,也算是助人爲樂,再者,幾乎每次重新搭建bochs時總是很亂,所以寫此文以備將來再次配置調試環境做參考!
Bochs的最新發布版本可以從它的主頁下載,也可以從該主頁獲取到相關說明文檔以及源代碼。本例使用版本爲bochs2.4.0.0。
配置Bochs需要相關的文件有bochs.exe、bochsdbg.exe、bximage.exe、DEBUG32.EXE以及一些原本沒有可能需要自己下載的文件niclist.exe和WinPcap_4_0_2.exe。既然bochs本身是虛擬機那首先要裝一個系統,本例使用win 2k系統。
1)創建虛擬硬盤:
雙擊運行bximage.exe創建一個4G、flat模式的虛擬硬盤文件disk.img;這樣就會在當前目錄下生成大小爲4G的disk.img文件。具體操作如圖:
2)安裝系統:
用win 2k系統盤直接安裝或者創建一個ISO鏡像的文件,鑑於bochs虛擬機的速度,還是不推介自己安裝系統,最好和別人直接拷貝一份已經安裝好操作系統disk.img文件。
3)創建win2k.bxrc:
主要內容:
#win2k.bxrc配置信息
#設置默認系統BIOS ROM模塊
romimage: file=$BXSHARE/BIOS-bochs-latest
#設置CPU參數
cpu:count=1,ips=22100000, reset_on_triple_fault=1, cpuid_limit_winnt=0, msrs="msrs.def"
#設置內存,可以選擇8、16、32、64、128或者512
megs: 512
#設置默認VGA ROM模塊
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
#vga: extension
vga: extension=vbe
#選擇並設置軟驅A,注意此處設置,在調試時將mbr文件改爲a.img即可進行調試
floppya: 1_44=a.img, status=inserted
#ATA controller for hard disks and cdroms
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
#選擇引導設備
boot: floppy, disk
# Enables or disables the 0xaa55 signature check on boot floppies
floppy_bootsig_check: disabled=0
#關閉日誌
log:nul
# LOG CONTROLS
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
# DEBUGGER_LOG:
debugger_log: -
#設置建立串口通道,可以與windbg相連.本例中不需要可以註釋掉
com2: enabled=1, mode=pipe-server, dev=\\.\pipe\com_2
# VGA_UPDATE_INTERVAL
vga_update_interval: 300000
# KEYBOARD_SERIAL_DELAY
keyboard_serial_delay: 250
# KEYBOARD_PASTE_DELAY
keyboard_paste_delay: 100000
# MOUSE
mouse: enabled=0
#private_colormap
private_colormap: enabled=0
#設置網卡信息
ne2k:ioaddr=0x300,irq=10,mac=00:1B:77:59:AC:28,ethmod=win32,
ethdev=\Device\NPF_{5175FF64-AD7E-4B75-A4E0-540FA4AAF493}
# pnic: Bochs/Etherboot pseudo-NIC
pnic: enabled=1, mac=00:26:55:36:ec:ae, ethmod=vnet
# KEYBOARD_MAPPING
keyboard_mapping: enabled=0, map=
# #設置硬件設備顯卡、網卡.
i440fxsupport: enabled=1, slot1=pcivga, slot2=ne2k
#設置PCI設備碼、廠商碼.貌似可以隨便寫
pcidev: vendor=0x1234, device=0x5678
#end of win2k.bxrc配置信息
上面關於win2k.bxrc配置信息的內容中有一處需要設置網卡信息,這個就可以使用我上面提到的niclist.exe這個程序了,而使用這個程序需要安裝WinPcap,本例使用WinPcap_4_0_2.exe;雙擊niclist.exe即可獲得相關信息,本例使用本機的網卡信息,圖上顯示數條網卡信息因安裝VMware緣故。如圖:
4)創建運行bochs的批處理文件
創建運行bochs批處理文件"運行.bat",主要內容:
set BXSHARE=F:\bochs #此處爲bochs調試器bochs.exe的路徑
%BXSHARE%\bochsdbg.exe -q -f win2k.bxrc
rem %BXSHARE%\debug32.exe -q -f win2k.bxrc
#win2k.bxrc爲上一步創建的win2k.bxrc配置信息文件
5)使用bochs開始調試:
到這一步就可以使用bochs進行調試了,雙擊"運行.bat"批處理文件即可打開bochs調試器,如果有a.img文件,bochs會以光盤啓動方式啓動操作系統;如果沒有a.img文件,bochs會以硬盤形式啓動操作系統,當然a.img的名稱可以在win2k.bxrc配置信息文件中按照個人喜好隨意修改。
二、使用bochs調試MBR
1)編寫MBR程序:
本例中使用我之前寫過的一個MBR小程序"基於MBR的系統登錄密碼驗證程序"進行演示使用bochs調試MBR的方法,具體可參見http://bbs.pediy.com/showthread.php?...��作系統。
2)Bochs調試命令:
鑑於文章主題,這裏只簡單介紹一些最常用的bochs調試命令,作爲入門這些就足夠了,更多的可以參考bochs相關的說明文檔。網上也有很多bochs調試命令的資料。下面只介紹本例中用到的若干命令;
命令 c 運行程序,相當於windbg的g以及OD的F9
命令 s 即step,單步執行程序
命令 p 單步執行,步過函數
命令 q 退出bochs並關閉虛擬機
命令 b 下斷點命令,如本例中:b 0x7c00
命令blist 顯示斷點狀態
命令 watch 顯示當前所有讀寫斷點
命令 r 顯示寄存器的值
命令 u 反彙編代碼,可設定起始和結束位置
命令 info 根據參數不同顯示相關信息
3)開始調試MBR
將第一步編寫的MBR程序拷貝到bochs調試器文件夾下並更名爲a.img,雙擊運行.bat開始調試,看到如下界面就說明一切工作正常,就可以開始調試了;
下面是具體的調試代碼:
F:\bochs>set BXSHARE=F:\bochs
F:\bochs>F:\bochs\bochsdbg.exe -q -f win2k.bxrc
00000000000i[APIC0] local apic 0 initializing
==================================================================
Bochs x86 Emulator 2.4
Build from CVS snapshot on May 3, 2009
==================================================================
00000000000i[ ] reading configuration from win2k.bxrc
00000000000i[ ] installing win32 module as the Bochs GUI
00000000000i[ ] using log file nul
Next at t=0
(0) context not implemented because BX_HAVE_HASH_MAP=0
[0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0
<bochs:1> b 0x7c00 //此處MBR被加載到0x7c00處斷點
<bochs:2> c //運行程序
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=72597973
(0) [0x00007c00] 0000:7c00 (unk. ctxt): xor ebx, ebx ; 6631db
<bochs:3> s //單步執行
Next at t=72597974
(0) [0x00007c03] 0000:7c03 (unk. ctxt): mov ds, bx ; 8edb
<bochs:4> s
Next at t=72597975
(0) [0x00007c05] 0000:7c05 (unk. ctxt): mov ax, word ptr ds:0x413 ; a11304
<bochs:5> s
Next at t=72597976 //40:13,BIOS數據區保存常規的內存大小
(0) [0x00007c08] 0000:7c08 (unk. ctxt): and al, 0xfc ; 24fc
<bochs:6> s
Next at t=72597977
(0) [0x00007c0a] 0000:7c0a (unk. ctxt): sub ax, 0x0004 ; 2d0400
<bochs:7> s
Next at t=72597978 //開闢一段內存,實現程序的駐留
(0) [0x00007c0d] 0000:7c0d (unk. ctxt): mov word ptr ds:0x413, ax ; a31304
<bochs:8> s
Next at t=72597979
(0) [0x00007c10] 0000:7c10 (unk. ctxt): shl ax, 0x06 ; c1e006
<bochs:9> s
Next at t=72597980
(0) [0x00007c13] 0000:7c13 (unk. ctxt): mov es, ax ; 8ec0
<bochs:10> s
Next at t=72597981
(0) [0x00007c15] 0000:7c15 (unk. ctxt): mov si, 0x7c00 ; be007c
<bochs:11> s
Next at t=72597982
(0) [0x00007c18] 0000:7c18 (unk. ctxt): xor di, di ; 31ff
<bochs:12> s
Next at t=72597983 //拷貝512
(0) [0x00007c1a] 0000:7c1a (unk. ctxt): mov cx, 0x0100 ; b90001
<bochs:13> s
Next at t=72597984 //拷貝代碼到駐留內存中執行
(0) [0x00007c1d] 0000:7c1d (unk. ctxt): rep movsw word ptr es:[di], word ptr ds:
[si] ; f3a5
<bochs:14> p //單步步過
Next at t=72598240
(0) [0x00007c1f] 0000:7c1f (unk. ctxt): mov ax, 0x0201 ; b80102
<bochs:15> s
Next at t=72598241
(0) [0x00007c22] 0000:7c22 (unk. ctxt): mov cl, 0x02 ; b102
<bochs:16> s
Next at t=72598242
(0) [0x00007c24] 0000:7c24 (unk. ctxt): cdq ; 6699
<bochs:17> s
Next at t=72598243
(0) [0x00007c26] 0000:7c26 (unk. ctxt): push es ; 06
<bochs:18> s
Next at t=72598244
(0) [0x00007c27] 0000:7c27 (unk. ctxt): push 0x002b ; 682b00
<bochs:19> s
Next at t=72598245
(0) [0x00007c2a] 0000:7c2a (unk. ctxt): retf ; cb
<bochs:20> p //單步步過
Next at t=72598246
(0) [0x0009e02b] 9e00:002b (unk. ctxt): mov si, 0x00db ; bedb00
<bochs:21> s
Next at t=72598247
(0) [0x0009e02e] 9e00:002e (unk. ctxt): call .+0x0070 (0x0009e0a1) ; e87000
<bochs:22> p //單步步過顯示信息的函數
Next at t=72607917
(0) [0x0009e031] 9e00:0031 (unk. ctxt): mov si, 0x00ea ; beea00
<bochs:23> s
Next at t=72607918
(0) [0x0009e034] 9e00:0034 (unk. ctxt): call .+0x006a (0x0009e0a1) ; e86a00
<bochs:24> p //單步步過顯示信息的函數
Next at t=72619688
(0) [0x0009e037] 9e00:0037 (unk. ctxt): call .+0x0077 (0x0009e0b1) ; e87700
<bochs:25> //此時系統要求輸入密碼
程序執行到這裏,系統要求用戶輸入密碼,如圖所示虛擬機界面:
在虛擬機裏面輸入自己在MBR程序裏面設置的密碼就可以接着在bochs裏面一步一步繼續往下面調試了!從MBR被載入並執行開始到NTLDR被載入並執行一直到操作系統開啓的整個過程都可以一步步跟蹤調試。系統啓動後bochs就想別的虛擬機一樣進入一個虛擬的操作系統中了,如圖:
最後,如果自己動手開發操作系統,那麼使用bochs調試是必不可缺少的。網上有很多幾十行的一個hello world的最小的操作系統的代碼,現在就可以來調試看看,也可以通過慢慢調試自己親自動手寫一個操作系統!