1 用戶態(tài)與內(nèi)核態(tài)切換
1.1 概念
- 用戶態(tài):ring3, 在應(yīng)用程序中運(yùn)行丐巫,代碼沒有對硬件的直接控制權(quán)限谈况,程序通過調(diào)用系統(tǒng)接口來達(dá)到訪問硬件和內(nèi)存,在這種模式下递胧,程序發(fā)生崩潰也是可以恢復(fù)的碑韵。
- 內(nèi)核態(tài):ring0,完全在操作系統(tǒng)的內(nèi)核中運(yùn)行,對硬件有所有操作權(quán)限谓着,可以執(zhí)行所有cpu指令集泼诱,訪問任意地址的內(nèi)存,在內(nèi)核模式下異常會(huì)導(dǎo)致整臺(tái)機(jī)器停機(jī)赊锚。
1.2 用戶態(tài)和內(nèi)核態(tài)的區(qū)別
cpu指令集
cpu指令集有權(quán)限劃分治筒,分為了ring0到ring3,ring3只能使用常規(guī)cpu指令集舷蒲,不能使用操作硬件資源的cpu指令集耸袜,比如IO讀寫,網(wǎng)卡訪問牲平,申請內(nèi)存等堤框。
用戶程序想要讀寫io,必然會(huì)用到ring 0級別的cpu指令集纵柿,而此時(shí)cpu的指令集在ring3級別蜈抓,需要切換指令集操作權(quán)限級別為ring0,cpu再執(zhí)行相應(yīng)的ring 0級別的cpu指令集昂儒,執(zhí)行對應(yīng)的內(nèi)核代碼沟使,會(huì)使用到當(dāng)前進(jìn)程的內(nèi)核棧。這里感覺執(zhí)行操作系統(tǒng)的內(nèi)核代碼其實(shí)和用戶代碼并沒有本質(zhì)區(qū)別渊跋,權(quán)限不同而已腊嗡。
每個(gè)進(jìn)程都有兩個(gè)棧,分別是用戶棧和內(nèi)核棧拾酝,對應(yīng)用戶態(tài)和內(nèi)核態(tài)使用
內(nèi)存空間
以linux 32位為例燕少,尋址空間是4G,操作系統(tǒng)會(huì)把內(nèi)存空間分配為2部分蒿囤,一部分為內(nèi)核空間客们,另一部分為用戶空間,高位的1G由內(nèi)核使用,低位的3G由各個(gè)進(jìn)程使用底挫,內(nèi)核態(tài)可以操作整個(gè)4G的空間嗽桩,用戶態(tài)只能操作3G空間。
1.3 用戶態(tài)和內(nèi)核態(tài)的切換
用戶態(tài)和內(nèi)核態(tài)切換的主要開銷如下:
- 保留用戶態(tài)現(xiàn)場(上下文凄敢、寄存器、用戶棧等)
- 用戶棧切到內(nèi)核棧湿痢,進(jìn)入內(nèi)核態(tài)
- 額外的檢查(內(nèi)核代碼對用戶不信任)
- 執(zhí)行內(nèi)核態(tài)代碼
- 復(fù)制內(nèi)核態(tài)代碼執(zhí)行結(jié)果涝缝,回到用戶態(tài)
- 恢復(fù)用戶態(tài)現(xiàn)場(上下文、寄存器譬重、用戶棧等)
我們可以發(fā)現(xiàn)一次切換經(jīng)歷了用戶態(tài)->內(nèi)核態(tài)->用戶態(tài)拒逮。
用戶態(tài)切換到內(nèi)核態(tài)的場景:
- 系統(tǒng)調(diào)用:用戶態(tài)進(jìn)程主動(dòng)切換到內(nèi)核態(tài)的方式,用戶態(tài)進(jìn)程通過系統(tǒng)調(diào)用向操作系統(tǒng)申請資源完成工作臀规,比如fork()就是創(chuàng)建新進(jìn)程的系統(tǒng)調(diào)用滩援。
- 異常:當(dāng)cpu在執(zhí)行用戶態(tài)進(jìn)程時(shí),發(fā)生了一些沒有預(yù)知的異常塔嬉,這時(shí)當(dāng)前運(yùn)行進(jìn)程會(huì)切換到處理此異常的內(nèi)核相關(guān)進(jìn)程中玩徊,也就是切換到了內(nèi)核態(tài)。
- 中斷: 當(dāng)cpu執(zhí)行用戶態(tài)進(jìn)程時(shí)谨究,外圍設(shè)備完成用戶請求操作后恩袱,會(huì)向cpu發(fā)出中斷信號,這時(shí)cpu會(huì)暫停執(zhí)行即將執(zhí)行的指令胶哲,轉(zhuǎn)到與中斷信號對應(yīng)的處理程序去執(zhí)行畔塔。