寫一個引導程序(boot loader)(翻譯)

原文連接segmentfault

環境

首先,你須要安裝NASM彙編器和QEMU來模擬一個虛擬機。用QEMU很好,由於咱們不用擔憂有時候不當心寫了爛的OS代碼而把硬件給搞壞了;) 。在win 10的wsl或Ubuntu上你能夠用這個命令來安裝它們(以前能夠用sudo apt-get update更新一下軟件源):bash

sudo apt-get install nasm qemu
複製代碼

在Mac上你可使用homebrew:ide

brew install nasm
複製代碼

在win 10上,你還要安裝X Server,這樣QEMU就能夠從WSL中打開一個窗口。oop

Hello World的Bootloader

咱們將編寫一個軟盤引導加載程序,它不須要咱們處理文件系統,這有助於使事情儘量簡單。 測試

圖片描述
當你按下電源鍵時候,計算機從存儲在主板上的閃存加載BIOS。BIOS對硬件進行初始化和自測試,而後將第一個512字節從媒體設備(即CDROM或軟盤)加載到存儲器中。若是最後兩個字節等於0xAA55,那麼BIOS將跳轉到位置0x7C00,有效地將控制轉移到引導加載程序。 此時CPU以16位模式運行,這意味着只有16位寄存器可用。此外,因爲BIOS只加載前512個字節,這意味着咱們的引導加載代碼必須保持在該限制之下,不然咱們將擊中未初始化的內存!

讓咱們把Help World World打印到屏幕上。要作到這一點,咱們將使用「TTY模式下的寫入字符」BIOS中斷調用和加載字符串字節指令LoBSB,將地址DS:SI中的字節加載到AL中。下面是:ui

bits 16 ; tell NASM this is 16 bit code
org 0x7c00 ; tell NASM to start outputting stuff at offset 0x7c00
boot:
    mov si,hello ; point si register to hello label memory location
    mov ah,0x0e ; 0x0e means 'Write Character in TTY mode'
.loop:
    lodsb
    or al,al ; is al == 0 ?
    jz halt  ; if (al == 0) jump to halt label
    int 0x10 ; runs BIOS interrupt 0x10 - Video Services
    jmp .loop
halt:
    cli ; clear interrupt flag
    hlt ; halt execution
hello: db "Hello world!",0

times 510 - ($-$$) db 0 ; pad remaining 510 bytes with zeroes
dw 0xaa55 ; magic bootloader magic - marks this 512 byte sector bootable!
複製代碼

你可使用nasm來編譯它(把它保存爲boot1.asmthis

nasm -f bin boot1.asm -o boot1.bin
複製代碼

若是咱們運行hexdump boot1.bin,咱們能夠看到NASM建立了一些代碼,填充了一些零點,而後將最後兩個字節設置爲幻數。spa

0000000 10be b47c ac0e c008 0474 10cd f7eb f4fa
0000010 6548 6c6c 206f 6f77 6c72 2164 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200
複製代碼

如今咱們能夠運行這個東西!你能夠告訴QEMU使用qemu-system-x86_64 -fda boot1.bin引導軟盤。在win 10上,你以前還應該設置環境變量SET DISPLAY=:0(這個實際上是指定了X Server的地址)。 你應該獲得這樣的東西! .net

圖片描述

原文連接code

相關文章
相關標籤/搜索