Linux核心設計的藝術 前三章總結

2021-06-20 17:44:40 字數 3532 閱讀 4620

特權級變化的本質是,cs,ds,es,fs,gs,ss的不同,特權級0從gdt中取得描述符,前面這些暫存器後3位為000,描述符特權級為00,特權級3從ldt中取得描述符,前面這些暫存器後3位為111,描述符特權級為11。中斷int 0x80從特權級3進入特權級0,並把資訊儲存在特權級0的堆疊中,iret從特權級0返回特權級3。

程序切換的本質是在程序核心

態把當前暫存器的值(核心態資料)放入當前程序的tss,把另乙個程序的tss資料恢復到暫存器,開始執行另乙個程序的核心態(已經被切換過)或者使用者態(初始化)。

中斷的本質是把當前cs,ds,es,fs,gs,ss壓入堆疊中(每個特權級有不同的堆疊),切換到核心態執行**,執行完畢後返回到對應的狀態,參考特權級變化。int 0x80中斷和硬

盤中斷區別是int 0x80是使用者態的中斷(dpl=11),壓入堆疊是使用者態的暫存器值;硬碟中斷(dpl=00),隨機的,壓入堆疊的有可能是使用者態的暫存器值,也可能是核心態的

暫存器值。

剛開始核心態是純粹的核心態,後來有了程序,都說成是程序幾的核心態。

get_free_page:目前用於程序核心tast_struct,還有頁表,還有程序執行**(例如shell程序)。

1、通過bootsect.s,setup.s,head.s把軟盤共1+4+240=245個扇區移入主記憶體區,最後形成如下圖:

頁目錄表和4個頁表總共管理16mb的記憶體,中斷描述符表:目前全是0(共256個中斷描述符),全域性描述符表:基位址為0,段界限為

16mb,

dpl=00,dt=1,第乙個描述符為0,第二個描述符為**段描述符,第三個描述符為資料段描述符,其餘全0。

目前暫存器的狀態如下圖及說明:

圖1 cs中0x08,其餘為0x10,cs高速緩衝暫存器中存放的是第二個描述符,**段基位址和段界限,其餘存放的是第三個描述符基位址和段界限

gdtr中存放的是gdt的基位址和段界限,idtr中存放的是ldt的基位址和段界限

所以現在處於核心態

2、開始在核心態執行main函式,設定如下圖的分割槽,初始化一些結構體

設定了中斷描述符(位於0x54b8~0x5cb8),並開啟中斷,具體內容如下:

selector為0x0008,offset為中斷函式的偏移。set_trap_gate,p為1,dpl為00,type為f(陷阱門)。set_intr_gate,p為1,dpl為00,type為e(中斷門)。set_system_gate,p為1,dpl為11,type為f(陷阱門)。只有int 0x80是dpl為11,使用者態,其餘存是核心態。還要注意此時的selector。

設定了tss,ldt

程序0的tss內容如下:

esp0為核心棧,ss0為0x10,cr3指向頁目錄表,其餘的變數沒有什麼用,就不介紹了。

程序0的ldt內容如下:

基位址為0,段界限為640kb,

dpl=11,dt=1,第乙個描述符為0,第二個描述符為**段描述符,第三個描述符為資料段描述符,其餘全0。

tss0:基位址為程序0的tss的首位址,界限為104個位元組,dpl=00,dt=0,type=9,可用386tss。

ldt0:基位址為程序0的ldt的首位址,界限為104個位元組,dpl=00,dt=0,type=2,ldt。

跳轉到0程序的3特權級,只有跳轉到3特權級才能說是程序。

cs為0xf(1111),ss為0x17(10111)其餘都是。從區域性描述符取,特權級為使用者態

ldtr選擇器為4<<3=0x20,ti=0 rpl=00 

tr選擇器為5<<3=0x28,ti=0 rpl=00

ldtr快取記憶體存放的是ldt0的基位址和界限

tr快取記憶體存放的是tss0的基位址和界限

所以此時處於程序0的3特權級

3、fork中int 0x80中斷

所以由程序0的3特權級,變成程序0的0特權級。因為int 0x80中斷,中斷描述符中的selector會把cs置成0x8,ds,es設定為0x10,fs設定為0x17。

設定程序1的task_struct,中斷發生前的所有暫存器的值都儲存在tss中了,ldt的基位址變為64mb,界限為640kb,所以要重新設定的頁目錄表和頁表,又設定了tss1,ldt1

完畢後,pop指令,讓fs,es,ds恢復原來的值,iret把ss、esp、eflags、cs、eip恢復成原值,從程序0的0特權級又轉換到程序0的3特權級

__res為1,所以fork返回1,那麼會執行for(;;) pause();又從程序0的3特權級又轉換到程序0的0特權級,

在sys_pause中使程序0設定為task_interruptible,開始程序調

度,切換到程序1的3特權級,此時變化的暫存器tr選擇器,ldtr選擇器(從tss中獲取),還有其他所有的暫存器(從tss中獲取)。目前的暫存器資訊儲存在程序0的tss中。

4、開始執行init函式

執行setup函式,從程序1的3特權級切換到程序1的0特權級,開始讀硬碟0x300,0號盤(共1024個位元組)的資料,等待讀盤的時候把程序1設定了task_uninterruptible

此時排程,已經沒有程序處於就緒態了,所以又切換到程序0的0特權級,就是上面sys_pause中的某個位置繼續執行,可能執行到上面迴圈pause( )、sys_pause( )、schedule( )、

switch_to (n) 的任何一句,硬碟已經把乙個扇區讀入到了硬碟緩衝區,發出中斷,把當前的**段描述符和資料段描述符放入堆疊中(不同的特權級有不同的堆疊),切換到了內

核態,開始執行中斷操作,把硬碟緩衝區的資料讀到記憶體中來。然後中斷返回(有可能處於程序0的0特權級,也可能處於程序0的1特權級)。兩次類似的過程後已經讀入到了內

存,然後解鎖,喚醒程序1,設定為就緒態,又進行程序排程,由程序0核心態切換到程序1的0特權(當前暫存器的值儲存在程序0的tss中),繼續執行bread函式,之後執行rd_load,從軟盤256塊後讀取虛擬盤資料到記憶體中

的虛擬盤區域,然後執行mount_root(),掛在根檔案系統,執行完sys_setup後又從程序1的0特權,變成了程序1的3特權級。

通訊之道的前三章學習筆記

今天通訊之道的書終於到了,作者簡直太逗了 非常之有意思 比如說他說我在完成博士後研究工作的時候對通訊依然一竅不通,或者在讀博士階段,我曾經想每個月讀一篇ieee的 但是讀了一篇沒有讀懂,換了一篇還沒有讀懂,半年下來一篇也沒有讀懂,於是就放棄了 希望我也能像大佬一樣,一開始一毛不懂,最後成功變成大佬。...

《構建之法》前三章的讀後感

1.第一章概論給我最大的感覺就是介在紹軟體工程這門功課時的語言。風趣又不失辯證思維的引導。並沒有過多的去照搬生澀難懂的理論。比較系統的介紹了軟體工程的定義及其與電腦科學的關係。2.第二章介紹了單元測試 回歸測試 效能分析 個人軟體開發流程 psp 理論與效用。說明了單元測試是程式設計師對自己本職模組...

最美麗的程式語言Scheme 前三章複習

今天這講,我們將複習一下前三章學過的內容。我們可以試試以下幾個問題,看看有沒有好的解決方案。1 請將下列表示式變換為字首形式。5 4 2 3 6 4 5 3 6 2 2 7 呵呵,這種問題,我們處理起來可以借用分治處理方法。我們首先對整個表示式進行劃分,這裡比較明顯的是乙個除法操作將兩個表示式隔開。...