自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具
? ? ? ? 1,首先給出一段完整的示例代碼,此代碼只為說(shuō)明引導(dǎo)程序的執(zhí)行流程,不具有加載實(shí)際操作系統(tǒng)的功能,只是在屏幕上打印一段信息。
[cpp] view plaincopy? ? ? ? ? ? ? ? 1).code16偽指令指示匯編器將此段代碼匯編成16位代碼。
? ? ? ? ? ? ? ? 2)ljmp ? ?$BOOTSEG, $start2指令中,BOOTSEG定義為0x07C0,并假設(shè)標(biāo)號(hào)start2在所在代碼段中的偏移為S。我們知道實(shí)模式地址模式為:段基址*16+偏移,那么這條ljmp指令執(zhí)行后,控制會(huì)跳轉(zhuǎn)到0x7C00+S處。又因?yàn)檎麄€(gè)引導(dǎo)代碼在之前會(huì)被加載到0x7C00處,所以此時(shí)控制“正好”跳轉(zhuǎn)到標(biāo)號(hào)start2處代碼。
? ? ? ? ? ? ? ? 3)代碼末端的偽指令.org 510,將位置計(jì)數(shù)器(location counter)設(shè)置為510,那么緊跟其后的0xAA55就被設(shè)置在第511,512字節(jié)。0xAA55是BIOS識(shí)別并加載引導(dǎo)程序的標(biāo)志。
? ? ? ? 2,編譯鏈接此程序
? ? ? ? ? ? ? ?1)用as命令匯編生成目標(biāo)文件。
? ? ? ? ? ? ? ? ? ? ? ?as -gstabs -o boot.o boot.S
? ? ? ? ? ? ? ?2)用ld命令鏈接生成可執(zhí)行文件。
? ? ? ? ? ? ? ? ? ? ? ?ld -o boot boot.o -Tboot.ld
? ? ? ? ? ? ? ? ? ? ? ?boot.ld為鏈接腳本,內(nèi)容如下:
[cpp] view plaincopy? ? ? ? ? ? ? ?此腳本指示ld將目標(biāo)文件boot.o中的.text段鏈接拷貝到可執(zhí)行文件boot中的.boot段,并且.boot段的起始VMA地址為0。.boot代碼段就是我們需要的引導(dǎo)程序代碼。更多鏈接腳本語(yǔ)法參考http://sourceware.org/binutils/docs/ld/index.html。
? ? ? ?3,制作引導(dǎo)軟盤鏡像
? ? ? ? ? ? ? 1)用dd命令新建軟盤鏡像flp.img。
? ? ? ? ? ? ? ? ? ? ? dd if=/dev/zero of=flp.img bs=512 count=2880
? ? ? ? ? ? ? 2)用losetup命令將flp.img與loop設(shè)備關(guān)聯(lián),這樣我們可以通過(guò)/dev/loop3設(shè)備,像操作真實(shí)軟盤樣操作flp.img文件。
? ? ? ? ? ? ? ? ? ? ? losetup /dev/loop0 flp.img
? ? ? ? ? ? ? 3)將可執(zhí)行文件boot中的引導(dǎo)代碼寫入flp.img的第一個(gè)扇區(qū)。首先我們要確定.boot段在可執(zhí)行文件boot中的位置,注意此位置不是指.boot段的VMA地址,而是指其存儲(chǔ)在磁盤文件boot中的物理位置,我們用objdump命令查看:
? ? ? ? ? ? ? ? ? ? ? objdump -h boot
? ? ? ? ? ? ? ? ? ? ? 輸出如下:
? ? ? ? ? ? ? ? ? ? ? 從File off欄可知.boot段位于距boot文件頭0x00001000處。然后用dd命令將.boot段寫入flp.img的第一個(gè)扇區(qū)。
? ? ? ? ? ? ? ? ? ? ? dd if=boot ibs=512 skip=8 of=/dev/loop0 obs=512 seek=0 count=1
? ? ? ? ? ? ? ? ? ? ? 其中skip * ibs = 0x00001000為待寫數(shù)據(jù),即.boot段,在輸入源文件,即boot文件中的偏移距離,seek * obs = 0為待寫數(shù)據(jù)將要被寫入輸出目標(biāo)文件,即flp.img文件的起始位置,即從flp.img文件頭字節(jié)開(kāi)始寫入數(shù)據(jù),count*obs=512為待寫數(shù)據(jù)的長(zhǎng)度。
? ? ? ? ? ? ? ? ? ? ? 到這里,引導(dǎo)軟盤鏡像準(zhǔn)備好了。關(guān)于dd,losetup,objdump命令更多信息可借助man命令,也可參考我前一篇文章。
? ? ? ? 4,借助QEMU從引導(dǎo)軟盤鏡像啟動(dòng)系統(tǒng)。
? ? ? ? ? ? ? ? 運(yùn)行如下命令啟動(dòng)QEMU。
? ? ? ? ? ? ? ? qemu -boot order=a -fda /dev/loop0
? ? ? ? ? ? ? ? 此時(shí),我們應(yīng)該可以在QEMU模擬器的窗口中看到Hello Boot!字樣。
? ? ? ? ? ? ? ? QEMU也提供單步調(diào)試功能。配合GDB,可以方便的調(diào)試引導(dǎo)程序。先用如下命令啟動(dòng)QEMU。
? ? ? ? ? ? ? ? qemu -s -S -boot order=a -fda /dev/loop0
? ? ? ? ? ? ? ? 其中-s -S選項(xiàng)與gdb調(diào)試有關(guān),運(yùn)行此命令后QEMU模擬器會(huì)停止并等待gdb發(fā)送單步執(zhí)行命令。更多QEMU信息可參考http://qemu.weilnetz.de/qemu-doc.html。
? ? ? ? ? ? ? ? 在另一個(gè)終端調(diào)用gdb命令進(jìn)入gdb命令行,依次輸入以下命令。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 操作系统实现(一):从Bootloade
- 下一篇: 跟我一起写操作系统(二)——史上最简单的