天天看點

自己動手寫作業系統-筆記一

一、CPU工作原理

CPU大體可以分為三個部分:控制單元、運算單元、存儲單元

控制單元大緻由指令寄存器IR(instruction register)、指令譯碼器ID(instruction decoder)、操作控制器OC(operation controller)組成。

控制單元取下一條指令,該指令位址在程式計數器PC中,在X86CPU中就是cs:ip。讀取ip寄存器後将此位址送上位址總線,CPU根據此位址變得到了指令,存入IR中。

ID根據指令格式檢查IR中的指令,先确定操作碼,再檢查操作數類型,若是在記憶體中,就将響應操作數從記憶體中取回放入到自己的存儲單元中,若操作數在寄存器中

就直接使用了。下一步,OC給運算單元下指令開始工作,于是運算單元開始執行真正的指令。ip寄存器被加上目前指令大小,指向下一條指令。接着控制單元取下一條

指令,開始無休止的循環工作。

二、實模式下CPU尋址方式

1.寄存器尋址

mul dx

2.立即數尋址

mov ax, 0xff

3.記憶體尋址

記憶體尋址又分為:

3.1 直接尋址

mov ax, [ds:0x1234]

3.2 基址尋址

sub sp, 2

mov [sp], ax

3.3 變址尋址

mov [si + 0x1234], ax

3.4 基址變址尋址

mov [bx + di], ax

三、IO接口

IO接口是連接配接CPU和外部裝置的邏輯控制部件。

輸入輸出控制中心(I/O control hub,ICH):CPU通路多個IO接口的邏輯需要ICH控制。

in和out指令的目的操作數和源操作數必須是dx,ax

in ax, dx

out dx, ax

根據操作數位數可以選擇使用ax或者al。

1.顯示卡

把需要顯示的内容寫到顯存中即可。

顯示卡各種模式記憶體分布:

顯存位址分布

起始 結束 大小 用途
C0000 C7FFF 32KB 顯示擴充卡BIOS
B8000 BFFFF 32KB 用于文本模式顯示擴充卡
B0000 B7FFF 32KB 用于黑白顯示擴充卡
A0000 AFFFF 64KB 用于彩色顯示擴充卡

在文本模式下每個字元用連續的兩個位元組表示,高位元組用于表示字元的屬性(例如前景色、背景色等等)。

2.硬碟

磁頭、盤片、磁道、柱面、扇區

扇區是硬碟存儲資料的基本機關,固定為512位元組。

各磁道内扇區都是以1為起始編号,并且僅限于本磁道内有效,是以各個磁道内的扇區編号都相同,

磁頭号、磁道号、扇區号定位唯一扇區。

硬碟控制器端口:

硬碟主要端口寄存器command block register

IO端口 端口用途
primary通道 secondary通道 讀操作時 寫操作時
0x1f0 0x170 data data
0x1f1 0x171 error features
0x1f2 0x172 sector count sector count
0x1f3 0x173 LBA low LBA low
ox1f4 0x174 LBA mid LBA mid
0x1f5 0x175 LBA high LBA high
0x1f6 0x176 device device
0x1f7 0x177 status command

LBA有兩種:

一是LBA28使用28bit來描述一個扇區的位址

二是LBA48使用48bit來描述一個扇區的位址

LBA low、mid、high寄存器分别存儲28位位址的0-7、8-15、16-23位,

device寄存器是個雜項,它的低4位用來存儲LBA位址的24-27位。

device寄存器和status寄存器:

自己動手寫作業系統-筆記一

一般硬碟操作順序:

最主要的順序就是command寄存器一定要最後寫,因為一旦command寄存器被寫入後,硬碟就開始幹活了。

①先選擇通道,往該通道的sector count寄存器中寫入帶操作的扇區

②往該通道的三個LBA寄存器中寫入扇區起始位址的低24位

③往device寄存器中寫入LBA位址的24-27位,并置第6位為1,使其成為LBA模式,設定第4位選擇操作的硬碟

④往該通道的command寄存器中寫入操作指令

⑤讀取該通道上的status寄存器,判斷硬碟工作是否完成。

⑥如果以上步驟是讀硬碟,進入下一步驟,否則,完工。

⑦将硬碟資料讀出。

最後送上一段MBR程式中的一個操作硬碟片段,它的作用是将硬碟中的加載器程式讀入記憶體中,首位址為0x900

1 mov eax, 0x2
 2 mov bx, 0x900
 3 mov cx, 1
 4 call rd_disk_m_16
 5 jmp 0x900
 6 
 7 mov esi, eax
 8 mov di, cx
 9 ;設定要讀取的扇區數
10 mov dx, 0x1f2
11 mov al, cl
12 out dx, al
13 
14 mov eax, esi
15 
16 ;将LBA位址存入0x1f3-0x1f6
17 mov dx, 0x1f3
18 out dx, al
19 
20 mov cl, 8
21 shr eax, cl
22 mov dx, 0x1f4
23 out dx, al
24 
25 shr eax, cl
26 mov dx, 0x1f5
27 out dx, al
28 
29 shr eax, cl
30 and al, 0x0f
31 or al, 0xe0
32 mov dx, 0x1f6
33 out dx, al
34 
35 ;向端口寫入讀指令
36 mov dx, 0x1f7
37 mov al, 0x20
38 out dx, al
39 
40 ;檢測硬碟狀态
41 .not_ready:
42 nop
43 in al, dx
44 and al, 0x88
45 cmp al, 0x80
46 jnz .not_ready
47 
48 ;從端口0x1f0讀取資料
49 mov ax, di
50 mov dx, 256
51 mul dx
52 mov cx, ax
53 mov dx, 0x1f0
54 .go_on_read:
55 in ax, dx
56 mov [bx], ax
57 add bx. 2
58 loop .go_on_read
59 ret
60 times 510-($-$$) db 0
61 db 0x55, 0xaa      

轉載于:https://www.cnblogs.com/CLAYJJ/p/8018020.html

繼續閱讀