我們最近在除錯32位產品的時候遇到了這樣的問題:使用ddr虛擬disk做硬碟,來啟動系統(因為32位產品可以訪問的最大位址空間僅為4g,因此核心空間的位址也顯的比較緊張)
我們虛擬的disk的實現是,使用一大塊連續的物理記憶體做disk,並將這塊物理記憶體通過vm_map_ram將物理線性位址對映到vmalloc的虛擬位址空間,那麼此時就會出現乙個問題,當我們對映的區域很大的時候超過vmalloc_end-vmalloc_start的時候就會發現無法對映這麼大的位址空間,對映過程中會報出溢位的log
從上面的**很容易看出是因為 start+size>end,那麼到底vmaloc可以對映多大的位址空間呢,這個我們得從kernel的位址空間說起了,那麼對於32位的處理器,核心空間應該是什麼樣的呢?如下圖
我們可以看到對於核心空間僅僅有1g,而線性對映區佔據了896m,從3g+896m開始為高階記憶體,高階記憶體裡包括了vmalloc區域和一些臨時對映區和永久對映區
那麼對於kernel來說到底能夠給vmalloc多少空間呢,這個我們得結合**看一下了:在arch/arm/mm/mmu.c中有如下**:
上面的**中我們可以分析得出:當cmdline中沒有vmalloc=size的命令是,early_vmalloc是不會執行的,因此vmalloc的大小由1081行的vmalloc_min決定,很明顯當我們沒有設定vmalloc size的時候vmalloc區域只有240m的大小,因此會出現我們開始的問題了。那麼既然太小我們當然要看一下vmalloc到底可以設定成多大(大能大到多少,小能小到多少??),從early_vmalloc中我們不難得出如下結論:vmalloc的最大size只能為984,最小為16m,因此我們設定vmalloc的大小為大於所需的size即可。
到這裡問題是解決了,但是我們肯定有個疑問,整個核心空間就1g,如果900多m都給了vmalloc,那麼**來的這麼多空間呢??這裡我們有得看**分析一下了,這個得看一下sanity_check_meminfo(不喜歡貼這麼多**,但是不得不貼出來了,為了說明問題):
注意一下:高階記憶體的概念這裡不介紹了,自己補習一下就行了(32位機存在這個概念,64的就沒有了)
void __init sanity_check_meminfo(void)
if (reg->size > size_limit)
}if (!highmem) {//這裡就是vmalloc**的關鍵所在了
if (block_end > arm_lowmem_limit) {
if (reg->size > size_limit)
arm_lowmem_limit = vmalloc_limit;//通過vmalloc_limit去更新arm_lowmem_limit
/*因此到這裡我們可以知道,當vmalloc較大時,線性對映區(原來的896m)會被壓縮到很小*/
好了,問題解決了,也知道vmalloc從**來的,到**去的了!!
不正之處,請多多指正!!!
核心空間與使用者空間
1.核心態與使用者態的區別 1 核心態 的 不受任何限制,可以訪問 所有處理器指令集 記憶體位址以及i o空間 2 使用者態的 只能訪問其位址空間的頁表項中規定的虛擬位址。2.使用者態到核心態的切換方式 1 系統呼叫 軟中斷的一種 由使用者程序主動發起 2 異常 當cpu在執行執行在使用者態下的程式...
使用者空間和核心空間
應用程式是從頭到尾執行單個任務。模組只是預先註冊自己以便服務於將來的某個請求,模組初始化函式的任務就是為以後呼叫模組函式預先做準備,就像模組說 我在這,並且我能做這些工作。模組的退出函式將在模組被解除安裝前呼叫,他告訴核心 我要離開了,不要再讓我做任何事了。應用程式在退出時,可以不管資源的釋放或其他...
核心空間與使用者空間
首先,這個概念的由來,我認為跟cpu的發展有很大關係,在目前cpu的保護模式下,系統需要對其賴以執行的資料進行保護,為了保證作業系統核心資料,我們把記憶體空間進行劃分,一部分為作業系統核心執行的空間,另一部分是應用程式執行的空間,所謂空間就是記憶體的位址。因此核心空間和使用者空間的概念就出現了。在3...