日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具

發布時間:2025/6/15 windows 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
引導程序可以認為是PC加電啟動后運行的第一段代碼,它是一段長度為512字節的16位運行于實模式的代碼。事實上,機器啟動后會首先運行0xFFFF0處(也有的資料說是0xFFFFFFF0,BIOS這塊我也不熟:-( )ROM中的BIOS代碼,之后會跳轉到0x07C00處執行引導程序。

? ? ? ? 1,首先給出一段完整的示例代碼,此代碼只為說明引導程序的執行流程,不具有加載實際操作系統的功能,只是在屏幕上打印一段信息。

[cpp] view plaincopy
  • #define?BOOTSEG?0x07C0??
  • ??????????.code16??
  • ??????????.section?".bstext",?"ax"??
  • ??????????.global?bootsect_start??
  • ??bootsect_start:??
  • ????
  • ??????????#?Normalize?the?start?address??
  • ??????????ljmp????$BOOTSEG,?$start2??
  • ????
  • ??start2:??
  • ??????????movw????%cs,?%ax??
  • ??????????movw????%ax,?%ds??
  • ??????????movw????%ax,?%es??
  • ??????????movw????%ax,?%ss??
  • ??????????xorw????%sp,?%sp??
  • ??????????sti??
  • ??????????cld??
  • ????
  • ??????????movw????$bugger_off_msg,?%si??
  • ????
  • ??msg_loop:??
  • ??????????lodsb??
  • ??????????andb????%al,?%al??
  • ??????????jz??????bs_die??
  • ??????????movb????$0xe,?%ah??
  • ??????????movw????$7,?%bx??
  • ??????????int?????$0x10??
  • ??????????jmp?????msg_loop??
  • ????
  • ??bs_die:??
  • ??????????#?Allow?the?user?to?press?a?key,?then?reboot??
  • ??????????xorw????%ax,?%ax??
  • ??????????int?????$0x16??
  • ??????????int?????$0x19??
  • ????
  • ??????????#?int?0x19?should?never?return.??In?case?it?does?anyway,??
  • ??????????#?invoke?the?BIOS?reset?code...??
  • ??????????ljmp????$0xf000,$0xfff0??
  • ????
  • ??bugger_off_msg:??
  • ??????????.ascii??"Hello?Boot!\r\n"??
  • ??????????.ascii??"by?harvey\r\n"??
  • ??????????.ascii??"\n"??
  • ??????????.byte???0??
  • ??
  • ??????????.org?510??
  • ??????????.word?0xAA55??
  • ? ? ? ? ? ? ? ? 這段代碼有幾個地方需要注意:

    ? ? ? ? ? ? ? ? 1).code16偽指令指示匯編器將此段代碼匯編成16位代碼。

    ? ? ? ? ? ? ? ? 2)ljmp ? ?$BOOTSEG, $start2指令中,BOOTSEG定義為0x07C0,并假設標號start2在所在代碼段中的偏移為S。我們知道實模式地址模式為:段基址*16+偏移,那么這條ljmp指令執行后,控制會跳轉到0x7C00+S處。又因為整個引導代碼在之前會被加載到0x7C00處,所以此時控制“正好”跳轉到標號start2處代碼。

    ? ? ? ? ? ? ? ? 3)代碼末端的偽指令.org 510,將位置計數器(location counter)設置為510,那么緊跟其后的0xAA55就被設置在第511,512字節。0xAA55是BIOS識別并加載引導程序的標志。

    ? ? ? ? 2,編譯鏈接此程序

    ? ? ? ? ? ? ? ?1)用as命令匯編生成目標文件。

    ? ? ? ? ? ? ? ? ? ? ? ?as -gstabs -o boot.o boot.S

    ? ? ? ? ? ? ? ?2)用ld命令鏈接生成可執行文件。

    ? ? ? ? ? ? ? ? ? ? ? ?ld -o boot boot.o -Tboot.ld

    ? ? ? ? ? ? ? ? ? ? ? ?boot.ld為鏈接腳本,內容如下:

    [cpp] view plaincopy
  • OUTPUT_FORMAT("elf32-i386",?"elf32-i386",?"elf32-i386")??
  • OUTPUT_ARCH(i386)??
  • ENTRY(bootsect_start)??
  • ??
  • SECTIONS??
  • {??
  • ????.?=?0;??
  • ????.boot?:?{*(.bstext)}??
  • ????.?=?ASSERT(.?<=?512,?"Boot?too?big!");??
  • }?????
  • ? ? ? ? ? ? ? ?此腳本指示ld將目標文件boot.o中的.text段鏈接拷貝到可執行文件boot中的.boot段,并且.boot段的起始VMA地址為0。.boot代碼段就是我們需要的引導程序代碼。更多鏈接腳本語法參考http://sourceware.org/binutils/docs/ld/index.html。

    ? ? ? ?3,制作引導軟盤鏡像

    ? ? ? ? ? ? ? 1)用dd命令新建軟盤鏡像flp.img。

    ? ? ? ? ? ? ? ? ? ? ? dd if=/dev/zero of=flp.img bs=512 count=2880

    ? ? ? ? ? ? ? 2)用losetup命令將flp.img與loop設備關聯,這樣我們可以通過/dev/loop3設備,像操作真實軟盤樣操作flp.img文件。

    ? ? ? ? ? ? ? ? ? ? ? losetup /dev/loop0 flp.img

    ? ? ? ? ? ? ? 3)將可執行文件boot中的引導代碼寫入flp.img的第一個扇區。首先我們要確定.boot段在可執行文件boot中的位置,注意此位置不是指.boot段的VMA地址,而是指其存儲在磁盤文件boot中的物理位置,我們用objdump命令查看:

    ? ? ? ? ? ? ? ? ? ? ? objdump -h boot

    ? ? ? ? ? ? ? ? ? ? ? 輸出如下:

    ? ? ? ? ? ? ? ? ? ? ? 從File off欄可知.boot段位于距boot文件頭0x00001000處。然后用dd命令將.boot段寫入flp.img的第一個扇區。

    ? ? ? ? ? ? ? ? ? ? ? dd if=boot ibs=512 skip=8 of=/dev/loop0 obs=512 seek=0 count=1

    ? ? ? ? ? ? ? ? ? ? ? 其中skip * ibs = 0x00001000為待寫數據,即.boot段,在輸入源文件,即boot文件中的偏移距離,seek * obs = 0為待寫數據將要被寫入輸出目標文件,即flp.img文件的起始位置,即從flp.img文件頭字節開始寫入數據,count*obs=512為待寫數據的長度。

    ? ? ? ? ? ? ? ? ? ? ? 到這里,引導軟盤鏡像準備好了。關于dd,losetup,objdump命令更多信息可借助man命令,也可參考我前一篇文章。

    ? ? ? ? 4,借助QEMU從引導軟盤鏡像啟動系統。

    ? ? ? ? ? ? ? ? 運行如下命令啟動QEMU。

    ? ? ? ? ? ? ? ? qemu -boot order=a -fda /dev/loop0

    ? ? ? ? ? ? ? ? 此時,我們應該可以在QEMU模擬器的窗口中看到Hello Boot!字樣。


    ? ? ? ? ? ? ? ? QEMU也提供單步調試功能。配合GDB,可以方便的調試引導程序。先用如下命令啟動QEMU。

    ? ? ? ? ? ? ? ? qemu -s -S -boot order=a -fda /dev/loop0

    ? ? ? ? ? ? ? ? 其中-s -S選項與gdb調試有關,運行此命令后QEMU模擬器會停止并等待gdb發送單步執行命令。更多QEMU信息可參考http://qemu.weilnetz.de/qemu-doc.html。

    ? ? ? ? ? ? ? ? 在另一個終端調用gdb命令進入gdb命令行,依次輸入以下命令。

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。