2012-07-18 114 views
3

幾乎所有關於Linux內核中HIGHMEM的書籍和文章,他們都說在使用3:1分割時,並不是所有的1GB都可用於內核映射。通常它的大小爲896MB左右,其餘部分用於內核數據結構,內存映射,頁表等。什麼數據結構使用128MB的1GB Linux內核空間?

我的問題是,這些數據結構究竟是什麼?頁表通常通過頁表地址寄存器訪問,對吧?並且頁表的基地址通常被存儲爲物理地址。現在爲什麼需要爲整個表保留一個虛擬地址空間?

同樣,我讀了關於佔用空間的內核代碼本身。這與虛擬地址空間有什麼關係?這不是用於存儲代碼的物理內存嗎?

最後,這些數據結構,爲什麼他們要保留128MB的空間?爲什麼不能按照需要在整個1GB地址空間中使用它們,就像內核中的任何其他正常數據結構一樣?

我已經通過LDD3專業Linux內核架構和幾個帖子在這裏堆棧溢出(如:Why Linux Kernel ZONE_NORMAL is limited to 896 MB?)和一個較舊的LWN article,但沒有找到相同的具體信息。

回答

2

至於頁表,這是真的,如果頁面表本身的虛擬地址空間沒有映射的MMU根本不會在乎 - 爲地址轉換的目的,這將是確定。但是當內核需要修改頁表時,他們需要在虛擬地址空間中映射它們 - 並且內核不能僅僅在「及時」映射它們,因爲它需要自己修改頁表要做到這一點。這是一個雞與雞蛋的問題,這意味着頁表需要始終保持映射。

內核代碼存在類似的問題。對於要執行的代碼,它必須映射到虛擬地址空間中 - 如果執行頁表修改的代碼本身不存在,那麼我們會遇到類似的雞與蛋問題。考慮到這一點,將內核代碼的全部內容隨時映射,以及內核模式堆棧和任何內核數據結構通過代碼進行訪問會更容易,因爲您不希望發生頁面錯誤。這種數據結構的一個大例子是代表每個物理內存頁面的struct page結構數組。

0

128MB的儲備是不針對特定的數據結構,即總是使用它。
它是虛擬內存,爲各種用戶保留,可能會使用它。通常情況下,並未全部使用。

關於物理和虛擬內存:每次分配需要三樣東西 - 一個物理頁面,一個頁面當前虛擬和映射連接兩個。 Linux幾乎不會直接使用物理地址,它總是通過虛擬地址轉換。
對於大多數內核內存分配(稱爲lowmem),這種轉換非常簡單 - 從虛擬地址中減去一些常量以獲得物理內存。但是,仍然使用虛擬地址。

即使在最大的機器上,當虛擬內存空間(4GB)比物理內存大得多 時,也會編寫Linux內存管理。在這種情況下,浪費虛擬地址不是問題。今天,當物理內存很大時,這會導致效率低下和問題。

vmalloc虛擬地址範圍是由vmalloc任何呼叫者使用。例如:
1.加載內核驅動程序(使用modprobeinsmod)。
2.內核模塊通常與vmalloc一起分配。替代函數kmalloc曾經被限制爲128K,並且其大小達到2的冪,所以vmalloc通常是大分配的首選。

+0

如果沒有爲特定數據結構保留128MB,爲什麼我們不能使用整個1G內核虛擬空間映射到某個虛擬地址?這樣,如果一個系統有1GB的物理內存,則根本不需要使用HIGHMEM。在基於896MB的設置中,需要HIGHMEM來利用大於896MB的任何物理內存。同樣,當我們爲某些東西(甚至不使用它)保留128MB時,虛擬地址範圍變得不可用於'vmalloc'。正如你所說的,一切都是通過虛擬地址訪問的。他們爲什麼浪費任何虛擬地址? – codetwiddler 2012-07-19 14:33:06

+0

@codetwiddler,這是相當複雜的......浪費虛擬地址是不好的,但它並非沒有用處。基本點是有兩種方法可以將虛擬地址連接到物理地址 - 直接映射(lowmem)和任意動態映射(vmalloc)。每個人都必須使用一個單獨的虛擬地址範圍,所以他們不會發生衝突。 – ugoren 2012-07-19 14:37:04

+0

同意一切,我知道有兩種方法及其用途。現在,具體來說,如果我有1GB的物理內存,我需要使用HIGHMEM來訪問超過896MB,因爲這個1GB-896MB塊被保留。那是什麼目的,它是多麼複雜?該保留應該有一些結構或與該空間相關的東西,或者至少是指向某個地方的指針,如果該保留是靜態的,我認爲它應該是相當重要的實體。 – codetwiddler 2012-07-19 16:40:35