顯示具有 OS 標籤的文章。 顯示所有文章
顯示具有 OS 標籤的文章。 顯示所有文章

2020年10月21日 星期三

自幹OS筆記 - 03 來個Hello World吧

一樣是寫程式  怎麼能不寫個Hello world呢?

所以接下來就是印個Hello world在螢幕上

BIOS 裡有提供簡單的 interrupt 可以完成這件事情

然後詳細的內容 可以翻閱 wikipedia 

簡單的說就是要設定 ax register 裡面的值 

分為 ah (高位址)和 al (低位址)

ah 設定成 0x0e 代表 Teletype output 會顯示 al 裡面存的ASCII code

--<boot.asm>---------------------------------------------------------------------

mov ah 0x0e

mov al, 'H'

int 0x10

mov al, 'e'

int 0x10

mov al, 'l'

int 0x10

mov al, 'l'

int 0x10

mov al, 'o'

int 0x10

mov al, ' '

int 0x10

mov al, 'w'

int 0x10

mov al, 'o'

int 0x10

mov al, 'r'

int 0x10

mov al, 'l'

int 0x10

mov al, 'd'

int 0x10

jmp $

times 510-($-$$) db 0x00

dw 0xaa55

-----------------------------------------------------------------------------------

簡單的說就是一個字一個字的填上去

然後 interrupt 讓字顯示上去

因為 ah 都一樣所以就不用動

填完之後 一樣一個 infinite loop

最後填上 0 跟 0xaa55就好了~

2020年10月19日 星期一

自幹OS筆記 - 02 用Assembly省點事情

因為不可能整個OS全部用 binary 刻出來(是可以  但我不想XD)

所以用點進階的東西來幫助我們 所以接下來要用 x86 架構的 assembly 來寫


因為向後相容性的關係 所以一開始載入 OS 會是 16-bit mode (查了OSDev的 wiki page 說又叫做 Real Mode)

16-bit mode 之後會切換到 32-bit(或是64-bit) mode (應該

總之就是一開始的是16-bit 的 assembly 模式

那如果照著上一篇的邏輯要把它寫成組合語言會長下面這樣

--<boot.asm>-------------------------------------------------------------

loop:

    jmp loop

times 510-($-$$) db 0x00

dw 0xaa55

------------------------------------------------------------------------------

上面的程式碼中比較奇怪的東西是 $ 跟 $$

$ 代表的是當前的位址(address)

$$ 代表的是當前 segment 的初始位址

然後 times 代表的是後面的東西要重複做好幾次

db 是 pseudo-instruction 代表要宣告 one byte 的內容  後面的b = bytes

dw 相對的就是 one word (其中 1 word = 2 bytes)

在這行指令裡面 times 510-($-$$) db 0x00 就是把 jmp 指令後的空間填滿 0x00

填到第 510 bytes 剩下兩個要填上 0xaa55 (識別boot sector)

然後再用 dw 0xaa55 填好最後 2 bytes


寫好之後  組譯的方式為以下指令

    nasm boot.asm -f bin -o boot.bin

組譯完用 xxd 來換成16進位觀看

    xxd boot.bin

--<boot.bin>----------------------------------------------------------------

ebfe 0000 0000 0000 0000 0000 0000 0000

....

0000 0000 0000 0000 0000 0000 0000 55aa

--------------------------------------------------------------------------------

可以看到開頭幾個 bytes 與上一篇手寫的 jmp 不太一樣

翻閱了之後發現

0xeb 其實也是 jmp 只是為 8-bit 模式

所以後面的 0xfe 代表的是 -1

合起來也是 infinite loop 的意思


後記:

寫這個真的讓我很努力學 Assembly

超想努力看懂每個指令的意思

但是資料好難查QAQ  

光一個 $ 就查好久






2020年10月14日 星期三

自幹OS筆記 - 01 用手寫binary生出來的OS

 開始工作後下班有些時間可以自學東西

終於可以來學之前在學校一直沒時間弄的自幹OS

所以這一系列大概就是自己的筆記加上碎碎念

寫文章紀錄下來,還順便督促自己要有進度

目標是研替新訓前寫完拉  大概到12月中左右


接下來的文章主要是根據Nick Blundell的文件 Writing a Simple Operating System —from Scratch 來開發  後續如果有其他參考文件會陸續補上

進入正題

以前只知道電腦按下開機鍵後  首先會載入主機板上燒好的BIOS(我已經不確定是Assembly還是C寫的)

BIOS會先檢查該有的硬體有沒有(沒記憶體  沒硬碟之類的會嗶嗶叫)

後面的事情就是莫名其妙OS就被載入了(X


所以在BIOS掃完硬體之後做了什麼事情?

目前的理解是 它會掃描所有它認得的儲存裝置(HDD SSD 光碟 軟碟...)

然後查看每個儲存裝置上的第一個sector (512 Bytes)

如果最後 2 Bytes 是 0xaa55 的話!  代表他是開機磁區

(但之後的grub我還不知道在那上場  有機會再補  應該吧)

所以最簡單的可以被認出來的OS(?) 就是 512 Bytes 

裡面的內容只有 最後兩個Bytes設定為 0xaa55 就好

因為要模擬的硬體是x86架構  所以要用little-endian (變成0x55aa)

實際上整個檔案內容長得下面這樣 

        0000 0000 0000 0000 0000 0000 0000 0000

        ....

        0000 0000 0000 0000 0000 0000 0000 55aa


但是!!!  我參考的文件裡面寫的不是這樣

是像下面這樣

        e9fd ff00 0000 0000 0000 0000 0000 0000

        ....

        0000 0000 0000 0000 0000 0000 0000 55aa

解釋是說 e9 fd ff 代表 endless jump (但我還是不清楚在幹麻

也許之後看完會懂吧(?  沒懂再慢慢查QAQ

------------------------------------------------------------------

2020/10/19補充:

0xe9 代表的是 jmp 指令  後面要接上跳到的位置

0xfdff 應該看成 0xfffd 代表的是 16-bit 中的數字 -3

所以整個來說就是 jmp 回 -3 bytes 的位置

等於 jmp 指令的開頭  所以會一直重複執行這個 jmp 指令

-------------------------------------------------------------------


然後因為要跑這個 OS(?)  總不可能準備一台電腦在那給我玩

所以就用 Qemu 來模擬硬體(雖然我不知道Qemu到底是啥)

總之就是用Qemu來模擬x86的硬體跑這個 OS

Ubuntu (Debian 系列的Distro) 用下面指令安裝

        sudo apt install qemu-system

然後執行的時候

        qemu-system-i386 boot.bin

(boot.bin就是我們 512 Bytes 的OS)

執行後出現 "Booting from Hard Disk..." 的字出現就代表成功了!

Go lang 學習筆記 - 17 Pointers

``` package main import "fmt" func zeroval(n int) {         n = 0 } func zeroptr(n *int) {         *n = 0 } func main() {         ...