自己動手實現作業系統引導程式(OS bootloader)——藉助QEMU/GDB/losetup/dd等工具

來源:互聯網
上載者:User

        引導程式可以認為是PC加電啟動後啟動並執行第一段代碼,它是一段長度為512位元組的16位運行於實模式的代碼。事實上,機器啟動後會首先運行0xFFFF0處(也有的資料說是0xFFFFFFF0,BIOS這塊我也不熟:-( )ROM中的BIOS代碼,之後會跳轉到0x07C00處執行引導程式。

        1,首先給出一段完整的範例程式碼,此代碼只為說明引導程式的執行流程,不具有載入實際作業系統的功能,只是在螢幕上列印一段資訊。

#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為連結指令碼,內容如下:

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命令列,依次輸入以下命令。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.