為何要把物理記憶體位址對映到核心空間?

2021-05-22 17:53:04 字數 1257 閱讀 2296

提出這個問題是因為32位的x86如果沒有特殊的支援和機制,是無法訪問896m以上的物理記憶體的,這讓我很奇怪。雖然核心所分配到的空間是[3g,4g-1),但是這並不代表核心本身的定址能力是1g呀。

後來看到一篇文章說,linux會在初始化的時候把物理記憶體對映到核心空間。這也讓我很奇怪。linux本身維護了乙個page的陣列來作為物理記憶體的「倉庫」,這個陣列的下標實際上就是物理記憶體的頁面號,linux會在初始化的時候初始化這個陣列。我的理解是,後期的虛存到物理記憶體的對映實際上都落實到了對這個page陣列的操作,這就夠了。為什麼還要把物理記憶體位址對映到核心空間?

並且,為什麼僅僅是896m,剩下的128m核心位址空間去哪兒了?難道剩下的這128m就是核心本身麼?如果是的話,那麼核心中的各種系統呼叫、核心資料結構等就都要擠在這個空間裡,這樣要對這相對所剩無幾的空間進行良好的規劃,而不是像普通程式那樣,一開始就是8開頭的虛存空間位址;如果不是的話,那這128m方的又是什麼東西,核心自己又躲到哪兒去了?

linux這樣做,只是為了簡化核心中虛擬位址和實體地址之間相互轉化的工作,__va()、__pa()輕鬆的就變換過來了,並不是說物理記憶體對映到核心空間就全部被核心佔了對於核心中非動態資料使用的物理記憶體是不可以變了,但是動態的部分,是可以釋放掉的,而釋放掉後這一部分對應的物理記憶體又可以影射到使用者空間。

至於為什麼不完全對映1g的空間,我想是因為還要留一片核心的虛擬位址給ioram用,比如說pci的ioram,通過ioremap對映總得留下點虛擬位址把,而ioram的虛擬位址又必需在核心空間中,也就是3-4g。 

不完全對映1g,是因為要保留出一段空間來供動態對映所使用,比如當記憶體大於1g是,除了前面的890m可以直接對映,後面的空間都需要臨時對映一下,用完解除對映(某些平台下實際解除是個空操作)。

對於剛好1g記憶體的時候,動態對映其實是沒有必要的。www.kerneltrap.org上曾經有文章討論過乙個patch,可以去掉動態對映,但只能用於少於1g的情況,好像現在kernel的配置已經有這個選項了。

核心的位址是從物理記憶體的0位址開始的,而0xc0000000就是這個偏移量

"linux這樣做,只是為了簡化核心中虛擬位址和實體地址之間相互轉化的工作,__va(), __pa()輕鬆的就變換過來了。 "

實體地址 <--> 虛擬位址

#define __pa(x) ((unsigned long)(x) & 0x3fffffff)

#define __va(x) ((void *)((unsigned long)(x) | 0xc0000000))

GPU 共享記憶體位址對映方式

當乙個warp中的不同執行緒訪問乙個bank中的不同的字位址時,就會發生bank衝突。如果沒有bank衝突的話,共享記憶體的訪存速度將會非常的快,大約比全域性記憶體的訪問延遲低100多倍,但是速度沒有暫存器快。然而,如果在使用共享記憶體時發生了bank衝突的話,效能將會降低很多很多。在最壞的情況下,...

S5PV210的記憶體位址對映詳解

s5pv 210 屬於 arm cortex a8架構,32 位cpu cpu 設計時就有 32 根 位址線 32 根 資料線 32 位址線 決定了 cpu 位址空間 為 4g 2 32 次方 sfrs 256m 位址 dram1 記憶體第乙個插槽 1g 外界記憶體 dram2 512m 記憶體 1...

記憶體位址重對映的選項 PE檔案與虛擬記憶體之間的對映

在除錯漏洞時,可能經常需要做這樣兩種操作。1 靜態反彙編工具看到的pe檔案中某條指令的位置是相對於磁碟檔案而言的,即所謂的檔案偏移,我們可能還需要知道這條指令在記憶體中所處的位置,即虛擬記憶體位址 va 2 反之,在除錯時看到的某條指令的位址是虛擬記憶體位址,我們也經常需要回到pe檔案中找到這條指令...