參照《王者歸來:和大師一起動手撰寫一個完整的作業系統》,並沒有完全按照書上實作,有問題可以發issue。
- Install boches First
- Before use command
make
You should create a image first:
bximage -hd=60 -imgmode="flat" -q hd60M.img
make
boches
K | 12~15 位元 背景色 K,是否閃爍 RGB,RGB比例 |
R | |
G | |
B | |
I | 8~11 位元 前景色 I,亮度 RGB,RGB比例 |
R | |
G | |
B | |
ASCII | 0~7 位元 |
硬碟控制器主要通訊埠(可參照 AT Attachment with Packet Interface相關手冊 共三冊)
IO 通訊埠 | 通訊埠用途 | ||
---|---|---|---|
Primary Channel | Secondary Channel | 讀取操作時 | 寫入操作時 |
Command Block registers | |||
0x1F0 | 0x170 | Data | Data |
0x1F1 | 0x171 | Error | Features |
0x1F2 | 0x172 | Sector count | Sector count |
0x1F3 | 0x173 | LBA low | LBA low |
0x1F4 | 0x174 | LBA mid | LBA mid |
0x1F5 | 0x175 | LBA high | LBA high |
0x1F6 | 0x176 | Device | Device |
0x1F7 | 0x177 | Status | Command |
Control Block registers | |||
0x3F6 | 0x376 | Alternate status | Device Control |
Segment Descriptor (wiki) :
一個 segment Descriptor 是 64bit,Base Address
和 Segment Limit
非常破碎,是由於 80286(16位元 CPU,擁有保護模式及24位元的位址線)當初做出來試水溫,之後的Intel為了往前兼容,後來的結構才會變成這樣:
31 | — | 24 | 23 | 22 | 21 | 20 | 19 | — | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | — | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Base Address[31:24] | G | D | L | AVL | Segment Limit[19:16] | P | DPL | S | type | Base Address[23:16] | ||||||||||
Base Address[15:0] | Segment Limit[15:0] |
- G: 粒度(Granularity),清零的話表示單位為 1 byte,set 時則表示單位為 4096 byte。
- 實際界限: (Segment Limit + 1) * Granularity - 1
- Descriptor 中的 Segment limit 只是單位,要乘上粒度才能得到真正的界限值
- Segment Limit + 1 是因為 Segment Limit 從0算起
- 最後減1是因為記憶體位址從0開始算起
- S: S位通常為1,為0時做特殊用途(task-gate, interrupt-gate, call gate, etc)
- type: 若S為0,用 type 指定 gate,S 為1時,最低位 A,為 Accessed 位,被 CPU 存取過後會被設為1
- 第二位 R 或 W,可否讀取或可否寫入
- 第三位 E 或 C,擴充方向(堆疊向下,程式資料向上)或一致性(Conforming)
- DPL: Descriptor Privilege Level,特權等級,0~3,0為最高。
- P: Present,該段是否存在於記憶體中,不存在則拋出異常,做 swap。
- AVL: Available,作業系統可以隨意用此位元,無特別用途。
- L: 為1表示64位元程式碼片段,為0為32位元程式碼片段。
- D: 為相容 80286 保護模式還是為 16bit(80286 為16位元的 CPU),因此有 D 來表明運算元和有效位址大小,0為 16bit,1為 32bit。
使用BIOS中斷0x15來取得記憶體大小:
AH | AL | Description |
---|---|---|
88h | 最多偵測到 64MB 的記憶體 | |
E8h | 01h | 檢測低 15MB 及 16MB~4GB 的記憶體 |
E8h | 20h | 可以檢測到全部的記憶體 |
offset | name | Description |
---|---|---|
0 | BaseAddrLOw | 基底位址的低32位 |
4 | BaseAddrHigh | 基底位址的高32位 |
8 | LengthLow | 記憶體的低32位元,byte 為單位 |
12 | LengthHigh | 記憶體的高32位元,byte 為單位 |
16 | Type | 記憶體類型,1:作業系統可使用、2或其他:作業系統不可使用 |
- 分頁目錄項(Page Directory Entry)
bit | 描述 |
---|---|
12~31 | 分頁表實體位址12~31位 |
9~11 | AVL:Available,無特別意義,作業系統可用 |
8 | G:Global,1表示全域分頁,轉址結果會一直被存在 TLB(Translation Lookaside Buffer) |
7 | 0 |
6 | D:Dirty,CPU 對一個頁執行寫入操作後,會 set 此位,僅對 PTE 有效,不會 set PDE 中的 Dirty |
5 | A:Accessed,CPU 存取過後會被 set |
4 | PCD:Page-level Cache Disable,1表示該分頁啟用c ache,反之不開啟 |
3 | PWT:Page-level Write-Through,1表示開啟 cache 的 write-through( write-back 較有效率,不需要經常性寫回 memory) |
2 | US:User/Supervisor,1表 User 級,皆可存取,0表 Supervisor 級,僅特權0、1、2可存取 |
1 | RW:Read/Write,0表讀取不寫入,1表讀取寫入 |
0 | P:Present,0表不存在實體記憶體上,拋出 pagefault 異常 |
- 分頁表項(Page Table Entry)
bit | 描述 |
---|---|
12~31 | 分頁實體位址12~31位 |
9~11 | AVL |
8 | G |
7 | PAT:Page Attibute Table,能以頁為單位設定記憶體屬性 |
6 | D |
5 | A |
4 | PCD |
3 | PWT |
2 | US |
1 | RW |
0 | P |
- cr3
bit | 描述 |
---|---|
12~31 | 分頁目錄表實體位址12~31位 |
5~11 | 沒有用 |
4 | PCD |
3 | PWT |
0~2 | 沒有用 |