0xFFFFFFF0 -> BIOS -> bootloader -> OS
BIOS是固化在主板的程序贮聂,初始化硬件,準(zhǔn)備環(huán)境认臊,為上層軟件提供訪問(wèn)和控制
-
bootloader位于存儲(chǔ)介質(zhì)的引導(dǎo)扇區(qū),切換保護(hù)模式圃庭,啟用分段機(jī)制,讀取ELF格式的操作系統(tǒng)到內(nèi)存
- 保護(hù)模式擁有4GB的尋址空間以及更好的保護(hù)機(jī)制,提供虛擬化支持
- 實(shí)模式只有16位尋址空間剧腻,沒(méi)有保護(hù)機(jī)制
- 分段機(jī)制:將內(nèi)存劃分為以初始地址和長(zhǎng)度限制表示的內(nèi)存塊拘央,稱之為段
- 邏輯地址,段描述符书在,段描述符表灰伟,段選擇子
- 段描述符:是描述段的屬性
- 段描述符表: 段描述符的數(shù)組
- 段選擇子: 段寄存器,定位段描述符表項(xiàng)
- ELF格式文件:
-
分段存儲(chǔ)管理機(jī)制:
- 段寄存器:DS(Data segment) SS(Stack segment) CS(Code segment)
- 段寄存器里存放段選擇子
- 段選擇子由INDEX儒旬,TI栏账,RPL三部分組成
- 段選擇子結(jié)合GDTR里的基地址,來(lái)從GDT中選擇相應(yīng)的segment-descriptor,GDTR的LIMIT為GDT表項(xiàng)(包括第一個(gè)空表項(xiàng))數(shù)目*8-1
- segment-descriptor包含base addr,limit冰单,type艇炎,accessed,avaliable橡伞,granularity,dpl以及segment-present這些部分。由base addr以及l(fā)ogical addr里的offset一起組成linear addr前计,在ucore里便是physical addr,但實(shí)際中還會(huì)再由linear addr生成physical addr垃杖。
-
保護(hù)機(jī)制
- DS和SS里的段選擇子為RPL男杈,CS的段選擇子為CPL,segment-descriptor里的為DPL
- CPL為進(jìn)程當(dāng)前的權(quán)限
- PL分為0-3调俘,最低為3伶棒,最高為0,這些特權(quán)級(jí)稱為環(huán)彩库,最內(nèi)為ring 0肤无,最外為ring 3,在ucore里只使用了兩級(jí)骇钦,ring 0: 內(nèi)核態(tài) ring 3:用戶態(tài)宛渐。
- 兩個(gè)關(guān)節(jié)節(jié)點(diǎn)時(shí)會(huì)檢查特權(quán):
- 當(dāng)一個(gè)段選擇符被加載時(shí)
- 通過(guò)linear addr訪問(wèn)內(nèi)存頁(yè)時(shí)
- MAX(CPL,RPL)<= DPL,如果為真眯搭,通過(guò)檢測(cè)否則不通過(guò)窥翩。即當(dāng)前權(quán)限或者請(qǐng)求權(quán)限的最低的一個(gè)必須比數(shù)據(jù)段的權(quán)限高,才可以通過(guò)鳞仙。
-
地址空間
- 邏輯地址由一個(gè)16bit的segment selector和一個(gè)32bit的offset構(gòu)成
硬盤訪問(wèn)概述
bootloader通過(guò)lba模式PIO(program IO)方式訪問(wèn)硬盤寇蚊。所有的IO操作都是通過(guò)CPU訪問(wèn)硬盤的IO地址寄存器實(shí)現(xiàn)的
具體寄存器的訪問(wèn)方式參考指導(dǎo)書(shū)
流程-
Link addr&Load addr
- Link addr:編譯器和指定代碼和數(shù)據(jù)所需要放置的內(nèi)存地址,由鏈接器配置
- Load addr: 程序?qū)嶋H被加載到內(nèi)存的位置(由程序加載器ld配置)
- 一般由可執(zhí)行文件結(jié)構(gòu)信息和加載器保證這兩個(gè)地址相同
-
中斷與異常
polling較為浪費(fèi)計(jì)算機(jī)資源棍好,因此采用iterrupt機(jī)制來(lái)節(jié)約資源-
interrupt分為三類:
- asynchronous interrupt仗岸,簡(jiǎn)稱interrupt允耿,是由外部事件如IO,timer扒怖,console等異步事件產(chǎn)生的
- synchronous interrupt右犹,簡(jiǎn)稱exception,是由內(nèi)部事件如指令錯(cuò)誤姚垃,或非法條件同步產(chǎn)生的
- trap interrupt念链,簡(jiǎn)稱trap,也稱軟中斷soft interrupt积糯,是由system call產(chǎn)生的
當(dāng)CPU收到中斷信號(hào)時(shí)掂墓,會(huì)根據(jù)idtr的基地址和中斷編號(hào)來(lái)定位到idt,idtr由idt addr以及l(fā)imit組成看成,同gdtr
由idtr+編號(hào)*8即位interrupt-descriptor的地址君编。
lidt(load idt register)根據(jù)內(nèi)存所存放的idtr格式內(nèi)存數(shù)加載idtr,ring 0川慌;sidt(store idt register)拷貝idtr的內(nèi)容到一個(gè)內(nèi)存地址吃嘿,任意特權(quán)級(jí)均可用運(yùn)行
-
id(interrupt descrptor)分為三類
- interrupt Gate: 調(diào)用時(shí)會(huì)禁止interrupt
- trap Gate:不會(huì)禁止interrupt
- task Gate: ucore里沒(méi)有使用
-
id的結(jié)構(gòu):
- selector: 段選擇子,會(huì)根據(jù)CPL和DPL的值確認(rèn)是否發(fā)生了特權(quán)級(jí)別的轉(zhuǎn)換
- offset: 這兩者構(gòu)成了中斷處理程序的入口地址
- dpl
所謂自動(dòng)禁止梦重,是指CPU跳轉(zhuǎn)到Gate里的地址時(shí)兑燥,在將EFLAGS保存到棧上之后,清除EFLAGS里的IF位琴拧,以避免重復(fù)觸發(fā)中斷降瞳。當(dāng)然操作系統(tǒng)可以將EFLAGS里的IF設(shè)上,從而允許嵌套中斷蚓胸。當(dāng)然在此之前必須做好處理嵌套中斷的準(zhǔn)備
而trap往往時(shí)系統(tǒng)調(diào)用挣饥,用戶進(jìn)程在用戶態(tài)不可以禁止中斷,而到達(dá)內(nèi)核態(tài)時(shí)禁止中斷沒(méi)有意義沛膳,因?yàn)椴粫?huì)有嵌套系統(tǒng)調(diào)用
-
-
中斷與異常的流程
- 當(dāng)出發(fā)中斷時(shí)扔枫,根據(jù)CS里的CPL和selector所指向descriptor里的DPL判斷時(shí)是否發(fā)生了特權(quán)級(jí)轉(zhuǎn)換,這里锹安,特權(quán)級(jí)要么保持短荐,內(nèi)核態(tài)到內(nèi)核態(tài),要么提升八毯,用戶態(tài)到內(nèi)核態(tài)搓侄。如果發(fā)生了轉(zhuǎn)化瞄桨,那么會(huì)從當(dāng)前用戶的TSS信息里去的該程序的內(nèi)核棧地址话速,包括ss和esp的值,并且將當(dāng)前使用的棧切換成新的內(nèi)核棧芯侥,再把當(dāng)前用戶棧的ss和esp壓入內(nèi)核棧
- 保存現(xiàn)場(chǎng)信息泊交,像內(nèi)核棧依次壓入EFLAGS乳讥,CS,EIP廓俭,ERRORCODE
- 根據(jù)段選擇子和offset云石,執(zhí)行中斷服務(wù)例程。
-
返回時(shí)
通過(guò)iret(or iretd)指令恢復(fù)被打斷程序的執(zhí)行研乒,具體過(guò)程:- 從內(nèi)核棧里彈出現(xiàn)場(chǎng)信息汹忠,即EFLAGS,CS雹熬,EIP重新開(kāi)始執(zhí)行
- 如果存在特權(quán)轉(zhuǎn)換宽菜,則還需要彈出用戶棧的ss和esp
- CPU在恢復(fù)過(guò)程中不會(huì)彈出errorcode,需要軟件完成
-
中斷與異常保護(hù)機(jī)制
- check DPL in selector <= CPL in CS
- 如果中斷是被用戶態(tài)程序中的指令觸發(fā)竿报,還會(huì)chck DPL in Gate <= CPL in CS铅乡,放置用戶隨意觸發(fā)中斷。
- 如果檢查失敗烈菌,會(huì)產(chǎn)生一個(gè)general-protection exception