天天日天天干天天搞_亚洲性色AV无码久久精品色欲_亚洲精品免费在线观看_午夜视频在线免费观看

時代商業(yè)網(wǎng)
ad2

Linux0.11第五回進(jìn)入保護(hù)模式前的最后一次折騰內(nèi)存

來源:IT之家  時間:2022-10-04 16:45  編輯:張璠   閱讀量:6456   

本系列將以一種新奇的閱讀心態(tài)閱讀和欣賞Linux 0.11的所有核心代碼,從啟動后的代碼執(zhí)行序列中了解操作系統(tǒng)的技術(shù)細(xì)節(jié)和設(shè)計思路。

Linux0.11第五回進(jìn)入保護(hù)模式前的最后一次折騰內(nèi)存

你會跟著我,看著一個操作系統(tǒng)從無到有,最后一步一步實現(xiàn)它復(fù)雜而精致的設(shè)計看完這個系列,希望你能感嘆原來操作系統(tǒng)源代碼就是這個蠢東西

以下是已發(fā)表文章的列表想詳細(xì)了解這個系列,可以從開篇的話開始

開場白

前兩行代碼

給自己挪個位置。

做好最基本的準(zhǔn)備工作。

將硬盤的其他部分放入內(nèi)存。

這個系列的GitHub地址如下:

—正文開始—

上一次,上一次,我們說操作系統(tǒng)已經(jīng)完成了從硬盤到內(nèi)存的各種加載,從內(nèi)存到內(nèi)存的復(fù)制。

至此,bootsect.s的整個使命已經(jīng)完成,也是我們看完的第一個操作系統(tǒng)源文件然后跳轉(zhuǎn)到0x90200,這里的代碼在安裝程序的開始處

start:movax,# 0x9000thisisdoneinbootsectalready,butmovds,axmovah,# 0x03readcursorposxorbh,BH,saveitinknownplace,con_initfetchesmov,dx,itfrom0x90000。

還有一個int指令。

如果你仔細(xì)閱讀前面的文章,你就能猜到它要做什么還記得有一個int 0x13觸發(fā)了BIOS提供的磁盤讀取中斷嗎這個int 0x10也是如此,同樣觸發(fā)BIOS提供的顯示服務(wù)中斷處理程序,ah寄存器賦給0x03,表示顯示服務(wù)中具體的光標(biāo)位置讀取功能

具體來說,BIOS提供了哪些中斷服務(wù),如何調(diào)用并獲取返回值請自行尋找資料,這里只說結(jié)果

當(dāng)int 0x10中斷程序完成并返回時,dx寄存器中的值指示光標(biāo)的位置具體地說,高八位dh存儲行號,低八位dl存儲列號

這里說明一下:電腦開機(jī)自檢后會自動初始化為文本模式在這種模式下,屏幕可以顯示25行,每行80個字符,即80列

下一個mov,dx將在這個內(nèi)存地址存儲這個光標(biāo)位置注意,我們前面說過,這個內(nèi)存地址只是一個偏移地址,需要加上ds寄存器中存儲的段基址最終的內(nèi)存地址是0x90000,其中存儲了光標(biāo)位置,供以后初始化控制臺時使用

所以從這里可以看出,這和平時調(diào)用一個方法沒什么區(qū)別,只不過這里寄存器的用法相當(dāng)于參數(shù)和返回值,這里的0x10中斷號相當(dāng)于方法名。

這里應(yīng)該是之前說過的一句話操作系統(tǒng)內(nèi)核初期,到處都是BIOS調(diào)試器如果有現(xiàn)成的,就用吧

接下來幾行代碼的邏輯和剛才一樣調(diào)用BIOS中斷來獲取一些信息,然后將其存儲在內(nèi)存中的某個位置讓我們快速瀏覽一下

例如獲得存儲器信息Getmemorysemovah,# 0x88int 0x15mov ,ax獲取顯卡的顯示模式Getvideo—carddata:movah,#0x0fint0x10mov,bx,bh=displaypagemov,ax,Al=videomode,ah=windowwidth檢查顯示模式,獲取參數(shù),檢查forega/vgaandsomeconfigparametersmovah,# 0x12movbl,# 0x10int 0x10mov ,axmov ,bxmov ,CX得到第一塊硬盤的信息Gethd0datamovax,# 0x0000movds,axldssi, movax,# initsegmoves,axmovdi,# 0x0080movcx,# 0x10repmovsb獲取第二塊硬盤的信息

以上原理都一樣。

我們沒有必要去思考理解操作系統(tǒng)沒多大區(qū)別我們只需要知道存儲在內(nèi)存中的信息是什么,在哪里,然后我們就會使用它們

內(nèi)存長度名稱0x900002光標(biāo)位置0x90022

擴(kuò)展內(nèi)存號0x900042顯示頁面0x900061。

顯示模式0x900071字符列數(shù)0x900082未知0x9000A1

顯示內(nèi)存0x9000B1。

顯示狀態(tài)0x9000C2顯卡特性參數(shù)0x9000E1。

屏幕行0x9000F1屏幕列0x9008016

1硬盤參數(shù)表0x9009016硬盤2參數(shù)表0x901FC2

根號

由于之后很快就會使用C語言進(jìn)行編程,雖然匯編和C語言也可以以變量的形式傳遞數(shù)據(jù),但這需要編譯器在鏈接時做一些額外的工作,所以雙方約定一個內(nèi)存地址會更方便我把它放在這里,你可以從這里拿走,它就完成了這恐怕是最原始最直觀的變量傳遞方式了

存儲了這些信息之后,操作系統(tǒng)會做什么我們繼續(xù)往下看

cli不允許中斷,

只有一行cli,意思是關(guān)閉中斷。

后來因為要重寫原來寫在BIOS里的中斷向量表,也就是銷毀它,自己寫中斷向量表,這時候就不允許中斷了。

繼續(xù)看。

firstwemovethesystemtoit ' srightfulplacemovax,#0x0000cld'direction'=0,movsmovesforwarddo_move:moves,axdestinationsegmentaddax,#0x1000cmpax,#0x9000jzend_movemovds,axsourcesegmentsubdi,disubsi,simovcx,# 0x8000jmpdo _ move然后weloadthesegmentdescriptorsend _ move:...

你熟悉后面的代表movsw嗎最初,我們在將操作系統(tǒng)代碼從0x7c00移動到0x90000時使用了這條指令我們來回憶一下

與前面的原理一樣,也要進(jìn)行內(nèi)存復(fù)制操作最后的結(jié)果就是從內(nèi)存地址0x10000到0x90000的所有內(nèi)容都被復(fù)制到內(nèi)存的初始0位置,大概就是這樣的效果

由于之前的各種加載復(fù)制,內(nèi)存看起來很亂又到了一波取舍和排序的時候了現(xiàn)在我們重新安排一下內(nèi)存布局

棧頂?shù)刂啡匀皇?x9FF00,沒有改變。

0x90000向上開始的位置原來是bootsect和setup程序的代碼現(xiàn)在,為了記錄內(nèi)存,硬盤,顯卡等一些臨時存儲的數(shù)據(jù),bootsect的部分代碼已經(jīng)被操作系統(tǒng)部分覆蓋

內(nèi)存512K的前0到0x80000由系統(tǒng)模塊占用如前所述,這個系統(tǒng)模塊是鏈接除bootsect和setup之外的所有程序的結(jié)果,可以理解為操作系統(tǒng)的整體

所以現(xiàn)在的內(nèi)存布局是這樣的。

好了,記住上圖就行了這次又清楚了嗎

接下來要做一些技術(shù)工作,就是模式轉(zhuǎn)換,需要從現(xiàn)在的16位實模式轉(zhuǎn)換到下一個32位保護(hù)模式這是一個大工程!我認(rèn)為這也是操作系統(tǒng)源代碼之旅的第一個精彩之處

我們身后的世界越來越精彩欲知后事如何,且聽下回分解

。

鄭重聲明:此文內(nèi)容為本網(wǎng)站轉(zhuǎn)載企業(yè)宣傳資訊,目的在于傳播更多信息,與本站立場無關(guān)。僅供讀者參考,并請自行核實相關(guān)內(nèi)容。