《操作系统真象还原》-阅读笔记(上)
第一章
配置bochs,進(jìn)入bochs simulator后一直是黑屏,原來(lái)默認(rèn)是調(diào)試模式,需要輸入C(continue)來(lái)讓調(diào)試?yán)^續(xù)。
第二章
主講MBR及進(jìn)入MBR前的步驟
1.實(shí)模式只能訪問1MB的內(nèi)存空間。
2.BIOS在ROM中。
3.開機(jī)上電后CS:IP指向內(nèi)存0xfff0,這里有個(gè)跳轉(zhuǎn)語(yǔ)句,轉(zhuǎn)到fe05b才是真正的BIOS程序,之后檢測(cè)內(nèi)存,顯卡燈,建立數(shù)據(jù)結(jié)構(gòu),中斷向量表和填寫中斷例程。
第三章
主講實(shí)模式
段的大小統(tǒng)一64KB,段基址代表內(nèi)存的起始,偏移地址代表段內(nèi)偏移量。
section:節(jié),只是為了讓程序員在邏輯上將程序劃分為幾個(gè)部分,偽指令
vstart:告訴編譯器以新的數(shù)字作為后面數(shù)據(jù)的地址的起始值
第四章
進(jìn)入保護(hù)模式
段描述符:專門用來(lái)描述一個(gè)內(nèi)存段,大小為8字節(jié)
全局描述符(GDT):
1.相當(dāng)于描述符的數(shù)組,可以用選擇子中提供的下標(biāo)在全局描述符表中索引描述符。
2.位于內(nèi)存中,需要GDTR寄存器指向他CPU才知道在哪。通過lgdt加載GDTR,指令格式是:lgdt48位內(nèi)存數(shù)據(jù),48位前16位是以字節(jié)為單位的界限值,后32位是GDT的起始地址。2^16=65536,65536/8=8192,所以最多存儲(chǔ)8192個(gè)段或門。
3.在保護(hù)模式下由于段基址已經(jīng)存入段描述符,段寄存器沒必要再存段基址了,所以段寄存器存入選擇子,通過選擇子在GDT中找到段描述符從而得到內(nèi)存段起始地址和段界限值。選擇子低2位存儲(chǔ)了RPL(可以表示0、1、2、3四種特權(quán)級(jí)),第2位是TI位用來(lái)選擇是GDT還是LDT索引描述符。而選擇子的索引部分有13位,所以最多索引8192個(gè)段,和GDT存儲(chǔ)的數(shù)量相同
?
注意:GDT中第0個(gè)段描述符是不可用的,原因是如果選擇子忘記初始化則值為0,為避免誤操作如果訪問第0個(gè)描述符處理器將發(fā)出異常。
局部描述符(LDT)
現(xiàn)代操作系統(tǒng)中很少使用LDT
CPU廠商建議每個(gè)任務(wù)的私有內(nèi)存段都應(yīng)該放到自己的段描述符表中,該表就是LDT,即每個(gè)任務(wù)都有自己的LDT,隨著任務(wù)切換,也要切換相應(yīng)任務(wù)的LDT。下面是Linux0.11內(nèi)核中描述符的關(guān)系
從相應(yīng)的內(nèi)核代碼中,我們看到在task_struct的聲明中,有如下內(nèi)容:
struct task_struct {
??? ...
??? struct desc_struct ldt[3];
??? struct tss_struct tss;
};
?
這說(shuō)明ldt是和每個(gè)task有關(guān)。每當(dāng)需要?jiǎng)?chuàng)建新的process時(shí),就需要在內(nèi)存中把一塊相應(yīng)的區(qū)域劃分給這個(gè)process的LDT。
(部分參考自http://blog.csdn.net/aotony_1988/article/details/50935897)
第五章
先回憶下上章內(nèi)容并解釋一些不清楚的地方。
一個(gè)進(jìn)程的地址空間,從用戶的角度看,是由若干的段(segment)組成的,這些段可以分為兩種:私有段(private)、共享段(shared)。cpu也是按照用戶的邏輯進(jìn)行內(nèi)存管理的(分段),Intel Pentium規(guī)定了每種段最多有8K個(gè),每個(gè)segment最大4G。一個(gè)cpu對(duì)應(yīng)有一個(gè)GDT(global descriptor table),該表詳細(xì)描述了shared segment,這個(gè)表為所有進(jìn)程共享的;一個(gè)process對(duì)應(yīng)有一個(gè)LDT(local),該表詳細(xì)描述了該process的private segment,這個(gè)表是進(jìn)程私有的。
我們的程序是處在一個(gè)個(gè)的Segment中的,無(wú)論是指令還是數(shù)據(jù)。我們?cè)诔绦蛑写蛴〕鲆粋€(gè)變量的地址其實(shí)是段內(nèi)的偏移地址(32位),程序的16bit段號(hào)由操作系統(tǒng)分配管理,我們是看不見的,但是的確存在。
注意注意注意:以上的解釋中,為簡(jiǎn)單,沒有說(shuō)明分頁(yè)!
總之,SegmentSelector(16bit) + 段內(nèi)Offset(32bit) = 一個(gè)32bit的地址值
其實(shí)這個(gè)就是虛擬地址。將這個(gè)地址轉(zhuǎn)換為物理地址就需要用他到頁(yè)目錄表中找到頁(yè)表的地址,再到頁(yè)表中找到真實(shí)物理地址。
(部分參考自http://blog.csdn.net/yleek/article/details/8204393)
??????? 如果存儲(chǔ)器采用基本分頁(yè)機(jī)制,那么操作系統(tǒng)會(huì)為每個(gè)進(jìn)程或任務(wù)建立一個(gè)頁(yè)表(這個(gè)頁(yè)表可能是一級(jí)的也可能是多級(jí)的)。整個(gè)操作系統(tǒng)中有多個(gè)進(jìn)程在運(yùn)行,那么系統(tǒng)就會(huì)有多個(gè)頁(yè)表。頁(yè)表在內(nèi)存中的存儲(chǔ)位置由寄存器CR3給出。
??????? 如果存儲(chǔ)器采用基本分段機(jī)制,那么操作系統(tǒng)會(huì)為每個(gè)進(jìn)程或任務(wù)建立一個(gè)段表(一般不用多級(jí)),用于記錄數(shù)據(jù)段、代碼段等各類段在內(nèi)存中的具體位置。
??????? 如果采用段頁(yè)式結(jié)合的機(jī)制,那么一般一個(gè)進(jìn)程或任務(wù),操作系統(tǒng)會(huì)給其建立一個(gè)段表,而段表中的每個(gè)段又會(huì)對(duì)應(yīng)一個(gè)頁(yè)表,也就是說(shuō),段頁(yè)式機(jī)制的每個(gè)進(jìn)程有一個(gè)段表,有多個(gè)頁(yè)表。
??????? 對(duì)于典型的Linux系統(tǒng)而言,操作系統(tǒng)會(huì)維護(hù)一個(gè)全局描述符表(相當(dāng)于系統(tǒng)的段表),全局描述符表中用于記錄系統(tǒng)任務(wù)和用戶任務(wù)的描述符,其中用戶任務(wù)的描述符又指向用戶任務(wù)的局部描述符表(相當(dāng)于用戶任務(wù)的段表)。因此要說(shuō)linux中的分段機(jī)制用的是一張大表,我個(gè)人認(rèn)為也是有道理的。
這本書里采用的是第一種方案,一個(gè)進(jìn)程一個(gè)頁(yè)表,這個(gè)頁(yè)表是二級(jí)的。將頁(yè)目錄表和頁(yè)表緊挨在一起,如下圖所示
?
這里將兩個(gè)表都存在內(nèi)核空間的低端內(nèi)存處,這樣通過cr3的物理地址可以馬上找到頁(yè)表(因?yàn)閮?nèi)核空間是真實(shí)線性的,即虛擬地址和物理地址一樣)。每一個(gè)進(jìn)程的頁(yè)表都放在一起,其實(shí)還有其他的放置方法可見此貼http://bbs.csdn.net/topics/390956135?page=1
快表
虛擬地址到物理地址轉(zhuǎn)換有一個(gè)緩存器,快表,存儲(chǔ)少量的轉(zhuǎn)換關(guān)系,能加快轉(zhuǎn)換速度。轉(zhuǎn)換時(shí)一般先查快表查不到再查頁(yè)表項(xiàng)。
啟動(dòng)分頁(yè)流程
1:準(zhǔn)備好目錄表和頁(yè)表
2:將頁(yè)表地址寫入控制寄存器cr3 (又稱為頁(yè)目錄基址寄存器)
3:寄存器cr0的PG位置1
tips
在64位的Linux下,gcc 編譯 32 位程序需要添加參數(shù) -m32 ,ld需要添加參數(shù)是 -m elf_i386。
第六章
本章講了一些函數(shù)調(diào)用 ,匯編和C語(yǔ)言混合編程等知識(shí)
1.cdecl調(diào)用,由調(diào)用者清理?xiàng)?臻g,即將棧頂往上加。
2.LINUX系統(tǒng)調(diào)用入口只有一個(gè) 0X80 中斷描述符表中的一項(xiàng) 具體調(diào)用子功能由eax指定。
3.調(diào)用函數(shù),當(dāng)輸入的參數(shù)小于等于 5 個(gè)時(shí), Linux 用寄存器傳遞參數(shù)。當(dāng)參數(shù)個(gè)數(shù)大于 5 個(gè)時(shí),把參數(shù)按照順序放入連續(xù)的內(nèi)存區(qū)域,并將該區(qū)域的首地址放到 ebx 寄存器。
tips
fatal error: sys/cdefs.h: No such file or directory|
Try these:
sudo apt-get purge libc6-dev
sudo apt-get install libc6-dev
In case of -m32:
sudo apt-get install libc6-dev-i386
源碼中LOADER_STRAT_SELECTOR一直在boot.inc里定義位0x2 所以Loader.bin應(yīng)放到硬盤第二個(gè)扇區(qū)
--------------------- ?
作者:月黑風(fēng)高云游詩(shī)人 ?
來(lái)源:CSDN ?
原文:https://blog.csdn.net/lqygame/article/details/73801091 ?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的《操作系统真象还原》-阅读笔记(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡怎么快速提额度 信用卡提额最有效方
- 下一篇: 半年躺赚1600,无风险投资来了?今年可