2012-05-23 38 views
2

我繼承了一些Linux內核驅動程序(我的經驗非常有限)。我的問題如下。這是一個嵌入式環境,硬件有512MB的物理內存。但是,通過使用變量linuxMem = mem = 256M,傳遞給內核的引導參數將內存限制爲256MB。在我對這個環境變量的研究中,我的理解是,這限制了內核可以管理的內存量爲256MB。 然而,在我的目標上運行的某些應用程序代碼中,我看到打開的/ dev/mem和返回的文件描述符的後續mmap,並且mmap調用的offset參數位於物理內存的上部256MB中。 而事情似乎工作正常。所以我的問題是「如果內核據說不知道256MB以上的內存,爲什麼它能工作?」限制內核可以使用「mem」環境變量管理多少物理內存

+0

您究竟如何將mmap返回的偏移量映射到物理內存? –

+0

一定有這個選擇的原因。可能是上面的256MB不可尋址,或者不適合標記寄存器。 (它是否有MMU?) – wildplasser

+0

這是實際的mmap調用。 mmap(NULL,size,PROT_READ | PROT_WRITE,MAP_SHARED,fdDevMem,(off_t)physMemPtr)。還有一個MMU。 – kook

回答

2

mmap()返回虛擬地址,而不是物理地址。

設備完全有可能只有64MB內存,並且mmap()可以映射大約1GB的內容。

+0

但是,mmap調用的「偏移量」參數是高於256MB,我猜測內核由於「linuxmem = mem = 256MB」環境變量而一無所知。也許我錯過了你的觀點,克里斯托夫。 – kook

+0

不,您的**虛擬**地址爲0,將抵消256MB。有關虛擬內存的維基百科文章解釋得比我更好。 –

+0

'mmap()'返回的地址是虛擬的,但映射文件'/ dev/mem'是物理內存的接口,而不是虛擬內存(幀vs頁面)。所以對於這個文件來說,'虛擬'偏移量(我覺得這個名字有點誤導,但是讓我們暫時略過)將一對一地轉換爲物理地址的差異。 kook的問題不是返回的地址是一個很大的值,而是從'/ dev/mem'以大於內核中設置的限制(但小於物理內存)的偏移量讀取而不導致分段錯誤是合法的。請參閱我的答案以獲得解釋。 –

3

嚴格地說,mem = 256M是一個內核參數,而不是一個環境變量。這個參數只告訴內核使用這麼多的內存,但是它不會使系統完全對安裝在機器中的物理芯片視而不見。它可以用來模擬比實際可用的物理內存更少的系統,但它不完全等同於打開盒子並拔出其中一個內存芯片。

看着the docs for this parameter,你可以明確地看到的有限範圍之外的地址,可以在某些情況下使用,這就是爲什麼他們還建議在某些情況下使用memmap=。所以,你不能爲你的應用程序分配超過限制的內存,但你可以看看在某些物理地址找到了什麼,並且似乎有些設備驅動程序利用了這種可能性。

+1

所以我對驅動程序代碼做了一些更多的調查,發現其中一個驅動程序的init函數正在執行一個高於256MB的request_mem_region,然後是一個相同的256MB的ioremap_nocache。所以它聞起來就像內核知道256MB的上限。看起來,該驅動程序的「寫入」功能也在執行copy_from_user調用,以實際寫入該內存。 – kook