前文介紹了如果使用bochs來(lái)啟動(dòng)官網(wǎng)提供的鏡像绍载,本文將簡(jiǎn)單介紹如何編寫(xiě)一個(gè)軟盤(pán)啟動(dòng)鏡像诡宗,并通過(guò)bochs啟動(dòng)它,啟動(dòng)完成后击儡,將在屏幕的最下方打印出紅色的"Hello bochs!"塔沃,主要步驟如下:
- 了解BIOS對(duì)軟盤(pán)引導(dǎo)分區(qū)的加載過(guò)程,可以參考這里
- 使用匯編編寫(xiě)程序?qū)?Hello bochs!"輸出到屏幕
- 將上一步編寫(xiě)的程序編譯成二進(jìn)制文件曙痘,寫(xiě)入到軟盤(pán)鏡像中
- 在bochsrc配置中增加上一步的軟盤(pán)鏡像為啟動(dòng)鏡像
下面分別來(lái)看一下各個(gè)步驟:
編寫(xiě)"Hello bochs!"
本文采用nasm匯編器芳悲,代碼如下:
; hello_bochs.asm
org 07c00h ; BIOS會(huì)跳到此處執(zhí)行,但是CS段仍指向0边坤,IP指向0x7c00名扛,因此boot內(nèi)的偏移需要以0x7c00為基準(zhǔn)
mov ax, cs
mov ds, ax
mov es, ax
; 使用BIOS的0x10中斷輸出顯示
mov bp, MessageDisp ; 顯示字符串的地址,最終指向es:bp
mov cx, MessageDispLen ; 假設(shè)待顯示字符個(gè)數(shù)存放在cx寄存器中茧痒,因此此處不需要設(shè)置
mov ah, 13h ; 功能碼13h
mov al, 1 ; 顯示方式為1:字符串中只包含字符肮韧,顯示屬性在bl中,光標(biāo)位置改變
mov bl, 0ch ; 顯示屬性:黑底紅字
mov bh, 0 ; 頁(yè)碼 0,當(dāng)前還沒(méi)有滾屏操作
mov dx, 1800h ; 0x18行弄企,0列位置開(kāi)始顯示
int 10h
jmp $
MessageDisp: db "Hello bochs!"
MessageDispLen equ $ - MessageDisp
times 510-($-$$) db 0
dw 0xaa55
分為幾個(gè)部分:
- 首先超燃,引導(dǎo)扇區(qū)的代碼是從0x7c00處開(kāi)始執(zhí)行,因此要告訴編譯器拘领,所有的地址計(jì)算都要基于0x7c00進(jìn)行偏移意乓,也就是
org 7c00h
這句。 - 接著约素,加載對(duì)應(yīng)的段寄存器届良,主要是數(shù)據(jù)段(ds)和es段,ds段用于定位待顯示的字符內(nèi)容圣猎,es段用于字符顯示需要士葫。
- 接著,調(diào)用BIOS提供的0x10中斷顯示指定的字符:es:bp指向待顯示的字符起始位置送悔;cx為待顯示字符串的長(zhǎng)度慢显;ah=13h是顯示字符串的功能碼;al指定顯示方式欠啤,此處為1荚藻;bl指定顯示屬性,此處為黑底紅字跪妥;bh為頁(yè)碼鞋喇,此處為0声滥;dx指定顯示的起始位置眉撵,實(shí)際為(dh,dl)=(行坐標(biāo),列坐標(biāo)),此處在24行0列落塑,也就是顯示屏的底部進(jìn)行顯示(顯示屏為25*80)纽疟。
- 接著,定義待顯示字符串的內(nèi)容和長(zhǎng)度憾赁。
- 接著污朽,由于引導(dǎo)扇區(qū)是512字節(jié),且引導(dǎo)扇區(qū)需要以0xAA55標(biāo)記作為512字符的最后兩個(gè)字符龙考,因此要將中間不足512字節(jié)的位置填0蟆肆,最后定義0xAA55標(biāo)記,位于511和512字節(jié)處晦款。
使用如下命令編譯程序:
nasm hello_bochs.asm -o hello_bochs.bin
將編譯好的程序?qū)懭氲杰洷P(pán)鏡像
首先炎功,使用安裝bochs時(shí)生成的bximage命令生成一個(gè)軟盤(pán)鏡像a.img,執(zhí)行bximage命令后缓溅,輸入1后會(huì)提示需要?jiǎng)?chuàng)建軟盤(pán)還是硬盤(pán)鏡像蛇损,繼續(xù)輸入fd創(chuàng)建軟盤(pán)鏡像,接著的輸入直接回車使用默認(rèn)即可,最終得到一個(gè)a.img的軟盤(pán)鏡像文件淤齐。
$ bximage
========================================================================
bximage
Disk Image Creation / Conversion / Resize and Commit Tool for Bochs
$Id: bximage.cc 14091 2021-01-30 17:37:42Z sshwarts $
========================================================================
1. Create new floppy or hard disk image
2. Convert hard disk image to other format (mode)
3. Resize hard disk image
4. Commit 'undoable' redolog to base image
5. Disk image info
0. Quit
Please choose one [0] 1
Create image
Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] fd
Choose the size of floppy disk image to create.
Please type 160k, 180k, 320k, 360k, 720k, 1.2M, 1.44M, 1.68M, 1.72M, or 2.88M.
[1.44M]
What should be the name of the image?
[a.img]
Creating floppy image 'a.img' with 2880 sectors
The following line should appear in your bochsrc:
floppya: image="a.img", status=inserted
將hello_bochs.bin寫(xiě)入到軟盤(pán)的第1個(gè)扇區(qū)(也就是引導(dǎo)扇區(qū))股囊,執(zhí)行如下命令:
dd if=hello_bochs.bin of=a.img bs=512 count=1 conv=notrunc
在bochsrc配置中指定啟動(dòng)軟盤(pán)鏡像
bochs的配置文件簡(jiǎn)介可以參考這里,此處我們使用的配置如下更啄,主要是指定了上一步生成的a.img作為我們的啟動(dòng)軟盤(pán)鏡像:
megs: 32
romimage: file=$BXSHARE/BIOS-bochs-latest
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
vga: extension=vbe, update_freq=15
floppya: 1_44=a.img, status=inserted
boot: floppy
log: bochsout.txt
mouse: enabled=0
cpu: ips=15000000
啟動(dòng)鏡像
截止目前稚疹,我們的目錄下包含的目錄樹(shù)結(jié)構(gòu)如下:
test
├── a.img
├── bochsrc
├── hello_bochs.asm
└── hello_bochs.bin
在當(dāng)前的目錄下執(zhí)行bochs -f bochsrc
,輸入6后會(huì)啟動(dòng)調(diào)試祭务,繼續(xù)輸入c后最終得到的界面如下贫堰,可以看到在屏幕底部打印了我們想要的紅色字符"Hello bochs!"。
附錄
本文所使用的環(huán)境信息
軟件名稱 | 軟件版本 |
---|---|
Linux操作系統(tǒng) | Ubuntu 22.04 LTS(X64) |
bochs | 2.7 |
nasm | 2.15.05 |