第五回 | 進(jìn)入保護(hù)模式前的最后一次折騰內(nèi)存
新讀者看這里,老讀者直接跳過。
本系列會以一個讀小說的心態(tài),從開機(jī)啟動后的代碼執(zhí)行順序,帶著大家閱讀和賞析 Linux 0.11 全部核心代碼,了解操作系統(tǒng)的技術(shù)細(xì)節(jié)和設(shè)計思想。

你會跟著我一起,看著一個操作系統(tǒng)從啥都沒有開始,一步一步最終實現(xiàn)它復(fù)雜又精巧的設(shè)計,讀完這個系列后希望你能發(fā)出感嘆,原來操作系統(tǒng)源碼就是這破玩意。
以下是已發(fā)布文章的列表,詳細(xì)了解本系列可以先從開篇詞看起。
本系列的 GitHub 地址如下(文末閱讀原文可直接跳轉(zhuǎn))
https://github.com/sunym1993/flash-linux0.11-talk
------- 正文開始?-------
書接上回,上回書咱們說到,操作系統(tǒng)已經(jīng)完成了各種從硬盤到內(nèi)存的加載,以及內(nèi)存到內(nèi)存的復(fù)制。

start:
????mov?ax,#0x9000??;?this?is?done?in?bootsect?already,?but...
????mov?ds,ax
????mov?ah,#0x03????;?read?cursor?pos
????xor?bh,bh
????int?0x10????????;?save?it?in?known?place,?con_init?fetches
????mov?[0],dx??????;?it?from?0x90000.
比如獲取內(nèi)存信息。
; Get memory size (extended mem, kB)
mov ah,#0x88
int 0x15
mov [2],ax
獲取顯卡顯示模式。
; Get video-card data:
mov ah,#0x0f
int 0x10
mov [4],bx ; bh = display page
mov [6],ax ; al = video mode, ah = window width
檢查顯示方式并取參數(shù)
; check for EGA/VGA and some config parameters
mov ah,#0x12
mov bl,#0x10
int 0x10
mov [8],ax
mov [10],bx
mov [12],cx
獲取第一塊硬盤的信息。
; Get hd0 data
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0080
mov cx,#0x10
rep
movsb
獲取第二塊硬盤的信息。
; Get hd1 data
mov ax,#0x0000
mov ds,ax
lds si,[4*0x46]
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
rep
movsb
| 內(nèi)存地址 | 長度(字節(jié)) | 名稱 |
|---|---|---|
| 0x90000 | 2 | 光標(biāo)位置 |
| 0x90002 | 2 | 擴(kuò)展內(nèi)存數(shù) |
| 0x90004 | 2 | 顯示頁面 |
| 0x90006 | 1 | 顯示模式 |
| 0x90007 | 1 | 字符列數(shù) |
| 0x90008 | 2 | 未知 |
| 0x9000A | 1 | 顯示內(nèi)存 |
| 0x9000B | 1 | 顯示狀態(tài) |
| 0x9000C | 2 | 顯卡特性參數(shù) |
| 0x9000E | 1 | 屏幕行數(shù) |
| 0x9000F | 1 | 屏幕列數(shù) |
| 0x90080 | 16 | 硬盤1參數(shù)表 |
| 0x90090 | 16 | 硬盤2參數(shù)表 |
| 0x901FC | 2 | 根設(shè)備號 |
cli?????????;?no?interrupts?allowed?;
;?first?we?move?the?system?to?it's?rightful?place
????mov?ax,#0x0000
????cld?????????;?'direction'=0,?movs?moves?forward
do_move:
????mov?es,ax???????;?destination?segment
????add?ax,#0x1000
????cmp?ax,#0x9000
????jz??end_move
????mov?ds,ax???????;?source?segment
????sub?di,di
????sub?si,si
????mov?cx,#0x8000
????rep?movsw
????jmp?do_move
;?then?we?load?the?segment?descriptors
end_move:
????...



后面的世界越來越精彩,欲知后事如何,且聽下回分解。
------- 本回擴(kuò)展與延伸 -------
嘗試在文本模式下,用直接寫顯存的方式,把自己的名字輸出在屏幕上。實驗源碼請自行到 GitHub 上尋找。
------- 關(guān)于本系列?-------
本系列的開篇詞看這
本系列的擴(kuò)展資料看這(也可點擊閱讀原文),這里有很多有趣的資料、答疑、互動參與項目,持續(xù)更新中,希望有你的參與。
https://github.com/sunym1993/flash-linux0.11-talk
本系列全局視角

最后,祝大家都能追更到系列結(jié)束,只要你敢持續(xù)追更,并且把每一回的內(nèi)容搞懂,我就敢讓你在系列結(jié)束后說一句,我對 Linux 0.11 很熟悉。
另外,本系列完全免費(fèi),希望大家能多多傳播給同樣喜歡的人,同時給我的 GitHub 項目點個 star,就在閱讀原文處,這些就足夠讓我堅持寫下去了!我們下回見。
