BasicOS - A Minimal Operating System
Overview
心血來潮,準備寫一個操作系統(tǒng),記錄一下學習過程。主要參考著名的《恐龍書》。從bootloader開始,逐步實現(xiàn)一個最小的操作系統(tǒng)。
既然是操作系統(tǒng),那么就避免不了匯編語言。之后會使用C語言來實現(xiàn)。最后如果有余力的話,會使用Rust來實現(xiàn)。
環(huán)境
- Ubuntu 24.04
- qemu
- nasm
- gcc
- make
安裝環(huán)境
sudo apt-get update
sudo apt-get install nasm qemu gcc gcc-multilib
安裝debug工具
sudo apt-get install xxd gdb
GitHub地址
https://xxxxx。xxx/toronto-andrew/BasicOS.git
先寫一個最簡單的bootloader
BIOS (Basic Input/Output System) 我們每個人都最熟悉了。當然,新的計算機都使用 UEFI(Unified Extensible Firmware Interface)了。
UEFI 和單純使用 BIOS 的區(qū)別在于加載內核的方式、準備工作和高級功能等。這里為了方便起見,我們暫時只考慮 BIOS(因為最簡單)。
電腦剛一開機,BIOS 的作用是告訴計算機從哪里加載操作系統(tǒng)到內存。于是,有人規(guī)定了,操作系統(tǒng)應當放在存儲設備最開始的 512 字節(jié)(例如磁盤第 0 柱面第 0 磁頭第 0 扇區(qū))。這個區(qū)域就是我們的引導扇區(qū)。也就是說,操縱系統(tǒng)運行的第一行代碼就是在引導扇區(qū)中。
然而,一臺計算機可能有多個存儲設備,BIOS 依然不知道哪個設備存儲了引導扇區(qū)。但不知道誰又規(guī)定了,引導扇區(qū)的最后兩個字節(jié)必須是 0xaa55。于是,BIOS 只需要遍歷所有存儲設備,檢查他們的第 511 和 512 字節(jié)是否是 0xaa55。如果是,就說明找到了操作系統(tǒng)的位置,把這一段數(shù)據(jù)加載到內存中,然后跳轉到這段代碼的第一個字節(jié)開始執(zhí)行。
因此,對于手動編寫一個引導扇區(qū)來說,只需要:
1 首先把最后兩個字節(jié)設置為 0xaa55;
2 然后從第一個字節(jié)開始寫上想要的代碼;
3 最后把其它的字節(jié)填充為 0,補滿 512 字節(jié)。
代碼如下boot.asm:
[bits 16] ; 告訴匯編器我們是在 16 位下工作
jmp $ ; $ 表示當前地址,跳轉到當前地址就是死循環(huán)
times 510-($-$$) db 0 ; $ 表示當前地址,$$ 表示當前段的開始地址
; 510-($-$$) 計算出當前位置到 510 字節(jié)的距離,然后全部填充為 0
dw 0xaa55 ; 最后兩個字節(jié)是 0xaa55
編譯
nasm boot.asm -f bin -o boot.bin
運行
qemu-system-x86_64 boot.bin
你會看到窗口中顯示 Booting from Hard Disk...,然后它就開始執(zhí)行死循環(huán)了。