Linux 相關學習記錄
阿新 • • 發佈:2019-05-15
trac 參考 targe scrip trace max o-k 描述 level
自己學習的備忘,從筆記轉移過來,後面每一項寫一篇對應的理解文章
內核線程和用戶進程異同記錄
- 所有進程的內核地址空間則都是一樣的。對於內核進程,由於其始終運行在內核態,所以沒有用戶地址空間,其對應的tast_struct結構體中的mm域也就被賦值為NULL。而堆的概念應該是只存在於進程的用戶地址空間中,所以內核進程是沒有堆一說的。
- 內核線程只工作在內核態中;而用戶線程則既可以運行在內核態,也可以運行在用戶態; 內核線程沒有用戶空間,所以對於一個內核線程來說,它的0-3G的內存空間是空白的,它的current->mm是空的,與內核使用同一張頁表;而用戶線程則可以看到完整的0-4G內存空間。
- 殺死內核線程:將該task_struct的狀態標誌位改為 KTHREAD_SHOULD_STOP (調kthread_stop函數),內核線程忽略信號,可見 http://lzz5235.github.io/2015/06/23/how-to-kill-a-kthread.html
- 守護進程可被信號殺死,父進程ID為1,內核進程父進程ID為2(kthreadd)
內核空間分布和尋址
-
這裏寫得挺詳細:https://www.cnblogs.com/wuchanming/p/4360277.html
- 分 ZONE_DMA(16M), ZONE_NORMAL(16M-896M), ZONE_HIGHMEN(896M-1G)(32位機器), ZONE_NORMAL 和 ZONE_DMA 直接映射物理內存,ZONE_HIGHMEM 通過內核PTE頁面建立映射,臨時用,用完後歸還
- 進程尋址空間0-4G,進程只有進入內核態才能訪問3G-4G
- 進程通過系統調用進入內核態
- 每個進程虛擬空間的3G~4G部分是相同的
- 進程從用戶態進入內核態不會引起CR3的改變但會引起堆棧的改變
-
從用戶態進入內核態過程(門的判斷)
- 圖參考這裏:https://blog.csdn.net/drshenlei/article/details/4265101
- CPU特權級切換(CPL):是取的CS寄存器的低兩位,在任何時候,不管CPU內部正在發生什麽,只要看一眼cs中的CPL,你就可以知道此刻的特權級了。
- 防止用戶態訪問內核態空間
- 通過分段保護機制,當 RPL 和 CPL 都大於 DPL 時候才可以訪問對應地址的內存
- CPL是當前進程的權限級別(Current Privilege Level),是當前正在執行的代碼所在的段的特權級,存在於cs寄存器的低兩位。
- DPL:描述符特權(Descriptor Privilege Level) 存儲在描述符中的權限位,用於描述代碼的所屬的特權等級,也就是代碼本身真正的特權級。一個程序可以使用多個段(Data,Code,Stack)也可以只用一個code段等。正常的情況下,當程序的環境建立好後,段描述符都不需要改變——當然DPL也不需要改變,因此每個段的DPL值是固定。
- RPL:請求特權級RPL(Request Privilege Level) ,RPL保存在選擇子的最低兩位。RPL說明的是進程對段訪問的請求權限,意思是當前進程想要的請求權限。RPL的值由程序員自己來自由的設置,並不一定RPL>=CPL,但是當RPL<CPL時,實際起作用的就是CPL了,因為訪問時的特權檢查是判斷:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次訪問時的附加限制,RPL=0時附加限制最小,RPL=3時附加限制最大。所以你不要想通過來隨便設置一個rpl來訪問一個比cpl更內層的段。
- 通過分段保護機制,當 RPL 和 CPL 都大於 DPL 時候才可以訪問對應地址的內存
-
用戶態到內核態切換途徑
- 系統調用
- 中斷
- 異常
-
用戶態進入內核態後進程棧如何切換
- 詳細代碼參考這裏:https://www.cnblogs.com/justcxtoworld/p/3155741.html
- 讀取TSS段(保存有用戶棧頂指針和內核棧頂指針)讀取 sp0, ss0
// TSS 結構定義(參考) #ifdef CONFIG_X86_32 /* This is the TSS defined by the hardware. */ struct x86_hw_tss { unsigned short back_link, __blh; unsigned long sp0; //當前進程的內核棧頂指針 unsigned short ss0, __ss0h; //當前進程的內核棧段描述符 unsigned long sp1; /* ss1 caches MSR_IA32_SYSENTER_CS: */ unsigned short ss1, __ss1h; unsigned long sp2; unsigned short ss2, __ss2h; unsigned long __cr3; unsigned long ip; unsigned long flags; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long bx; unsigned long sp; //當前進程用戶態棧頂指針 unsigned long bp; unsigned long si; unsigned long di; unsigned short es, __esh; unsigned short cs, __csh; unsigned short ss, __ssh; unsigned short ds, __dsh; unsigned short fs, __fsh; unsigned short gs, __gsh; unsigned short ldt, __ldth; unsigned short trace; unsigned short io_bitmap_base; } __attribute__((packed));
Linux 相關學習記錄