作業系統 Hello World

作業系統 Operating System

 How system boot



一. Hello, World ( 用 qemu & nasm )

>nasm -f bin -o helloWorld helloWorld.asm

>qemu-system-x86_64 -hda C:\Users\BlackTea\Desktop\Code\Assembly\Example\helloWorld

*helloWorld.asm
===================================================================
org 7c00h

jmp short Start

Message: db 'Hello, World!'
Start: 
    mov ax, 3
    int 10h

    mov ax, cs
    mov es, ax
    mov bp, Message
       
    mov cx, 13
    mov ax, 1301h
    mov bx, 000fh
    mov dl, 0
    mov dh, 0
    int 10h

     jmp $

times 510 - ( $ - $$) db 0
dw 0xaa55
====================================================================

二. Hello World

*將機械碼寫入到 硬碟(USB 隨身碟) 的MBR磁區
(參考:https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders)

具體作法:
1.編寫 os.asm
2.使用 nasm 將 os.asm 組譯成 os.bin(一種 flat-form 二進制檔案)
3.將 os.bin 寫入到 硬碟(USB 隨身碟) 的MBR磁區

1. os.asm
========================os.asm====================
org 7C00h

jmp short Start ;Jump over the data (the 'short' keyword makes the jmp instruction smaller)

Msg:    db "Hello World! "
EndMsg:

Start:  mov bx, 000Fh   ;Page 0, colour attribute 15 (white) for the int 10 calls below
        mov cx, 1       ;We will want to write 1 character
        xor dx, dx      ;Start at top left corner
        mov ds, dx      ;Ensure ds = 0 (to let us load the message)
        cld             ;Ensure direction flag is cleared (for LODSB)

Print:  mov si, Msg     ;Loads the address of the first byte of the message, 7C02h in this case

                         ;PC BIOS Interrupt 10 Subfunction 2 - Set cursor position
                         ;AH = 2
Char:   mov ah, 2       ;BH = page, DH = row, DL = column
        int 10h
        lodsb           ;Load a byte of the message into AL.
                         ;Remember that DS is 0 and SI holds the
                         ;offset of one of the bytes of the message.

                         ;PC BIOS Interrupt 10 Subfunction 9 - Write character and colour
                         ;AH = 9
        mov ah, 9       ;BH = page, AL = character, BL = attribute, CX = character count
        int 10h

        inc dl          ;Advance cursor

        cmp dl, 80      ;Wrap around edge of screen if necessary
        jne Skip
        xor dl, dl
        inc dh

        cmp dh, 25      ;Wrap around bottom of screen if necessary
        jne Skip
        xor dh, dh

Skip:   cmp si, EndMsg  ;If we're not at end of message,
        jne Char        ;continue loading characters
        jmp Print       ;otherwise restart from the beginning of the message


times 0200h - 2 - ($ - $$)  db 0    ;Zerofill up to 510 bytes

         dw 0AA55h       ;Boot Sector signature

;OPTIONAL:
;To zerofill up to the size of a standard 1.44MB, 3.5" floppy disk
;times 1474560 - ($ - $$) db 0
===================================================================

2.使用 nasm 將 os.asm 組譯成 os.bin

C:\Users\BlackTea\Desktop\nasm-2.14.02>nasm -f bin -o os.bin os.asm

*你會發現 os.bin剛好是 512 byte (一個磁區的大小)

3.將 os.bin 寫入到 硬碟(USB 隨身碟) 的MBR磁區
(1) 編寫 rawWrite.cpp 並編譯、執行(以 系統管理員 權限)
*執行時需插入要寫入的 硬碟
==============================rawWrite.cpp=======================
#include<iostream>
#include<Windows.h>

using namespace std;

int main(int argc,char** argv){
    char buffer[512];
    DWORD read=0,write=0;
    ZeroMemory(buffer, sizeof buffer);
   
    HANDLE hFile = CreateFile("C:\\Users\\BlackTea\\Desktop\\nasm-2.14.02\\os.bin", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    if(ReadFile(hFile,buffer,512, &read,NULL)){
        if(read!=512){
            cout << "read fail! (" << read << " bytes)" << endl;
            system("pause");
            return 0;
        }else    cout << "read success! " << endl;
    }else{
        cout << "read fail!" << endl;
        system("pause");
        return 0;
    }
    HANDLE hFile2 = CreateFile("\\\\.\\PhysicalDrive1", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    //要寫入的硬碟 是哪個 PhysicalDrive 用工具 wmic
    // C:\>wmic diskdrive list
    //觀察其中 DeviceID 及 Model 欄位 就能知道
    if(WriteFile(hFile2,buffer, 512, &write, NULL)){
        if(write!=512){
            cout << "write fail! (" << write << " bytes)" << endl;
            system("pause");
            return 0;
        }else
        cout << "write success! " << endl;
    }else{
        cout << "write fail!" << endl;
    }
    system("pause");
    return 0;
}
===============================================================

*USB 隨身碟 寫入後插入會出現錯誤:

4.重新啟動並進入 BIOS 調整 boot order 再重新啟動

留言

這個網誌中的熱門文章

組合語言 Assembly Language