繪圖丟失了一些重要的基本假設。
內核不需要mmap()
來訪問用戶空間內存。如果用戶進程具有內存,則它已按照定義映射到地址空間中。從這個意義上說,內存已經在用戶和內核之間共享。
mmap()
在用戶的虛擬地址空間中創建一個新的區域,這樣如果以後訪問,地址區域可以由物理內存填充。內存的實際分配和修改頁表項是由內核完成的。
mmap()
僅適用於管理用戶一半的虛擬地址空間。內核地址空間的一半是完全不同的。
此外,系統中的所有進程都共享內核的一半。每個進程都有其專用的虛擬地址空間,但對頁表進行編程時,對於所有進程而言,內核半頁的頁表條目設置完全相同。
此外,內核不會mmap()
爲了訪問用戶空間內存。 mmap()
是由內核提供給用戶的一項服務,用於修改用戶虛擬地址空間中的當前映射。
順便說一句,內核實際上有幾種方法來訪問用戶的內存,如果它想。首先,內核具有內核地址空間的專用區域(作爲其內核空間的一部分),其以連續方式映射整個物理內存。 (在所有64位系統中都是如此,在32位系統中,內核必須實時重映射)
其次,如果內核是通過系統調用或異常進入的,而不是通過硬件中斷,你有有效的進程上下文,所以內核可以直接「取消引用」用戶空間指針來獲得正確的值。第三,如果內核想要在借用的上下文(如中斷處理程序)中執行時考慮進程的用戶空間指針,那麼內核可以通過遍歷vm_area_struct
樹以獲取權限並將頁表漫遊到其他目錄,以跟蹤進程的虛擬地址找出實際的物理頁面框架。
是。這基本上是正確的。我會用黑色的箭頭指向右邊。也就是說,它共享相同的物理頁面。它不會獲得與內核相同的虛擬地址,也不會以某種方式「指向」內核數據區域。相反,它會自己獨立映射到相同的物理內存頁面。 –
通常我可以看到Linux中的每個線程都有自己的虛擬內存區域,分爲1GB內核和3GB用戶空間。在這種情況下:內核模塊的某些部分是否位於用戶空間應用程序的內核空間部分? – Alex44
是的。在該模型中,內核虛擬地址空間是最高1GB(x86 32位)。用戶模式空間最低3GB。所以他們共享4GB虛擬地址空間。當存在上下文切換時,將安裝新的頁面表。它與頂部1GB具有相同的映射,但新過程的用戶模式映射爲新映射。但是,用戶模式永遠不能訪問最高1GB(即,如果它嘗試訪問該內存,由於頁表訪問限制,它將收到「SIGSEGV」)。內核模式*可以*技術上直接訪問用戶模式空間,儘管它通常是通過API完成的。 –