歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux Kernel中的編碼技巧:將運行期錯誤提前為鏈接報錯

> 緣起

《深入Linux內核架構》P144頁。讀書存疑,繼而想通。

深入Linux內核架構 PDF(中文版+英文版) 下載見 http://www.linuxidc.com/Linux/2012-06/62984.htm

> 鋪墊

虛擬地址空間一般按3:1劃分為進程地址空間和內核地址空間,32位機器4G的虛擬地址空間就有1G分為內核地址空間。

(1) 內核地址空間前896M是直接映射的物理頁幀,即物理內存上的896M能直接映射(通過線性偏移0xC000000)到內核地址空間的這個區域。

(2) 然後是一小段內存間隙用於內核故障報錯。

(3) 然後是vmalloc區域,用於動態分配,內核自身會盡力避免非連續的物理地址,這段內存區主要用於動態加載模塊時。

(4) 然後是2個頁幀的保護性間隔內存。

(5) 然後是持久映射區,用於將highmemory中的非持久頁映射到內核中。(存疑,暫不求甚解)

(6) 最後是固定映射區,一直到虛擬地址4GB處。對於上面所述的直接映射區,虛擬地址平移__PAGE_OFFSET(IA-32上即為0xC000000)即得到物理地址,而固定映射不同,這個區域中的虛擬地址指向隨機的物理地址,虛擬地址和物理地址的關聯可以自由定義但定義後不能改變。固定映射的優點是:1. 編譯時對此類地址的處理類似常數,內核一啟動即為其分配了物理地址。 2. 此類地址的反引用比普通指針要快。 3. 內核確保在上下文切換時,對應於固定映射的頁表項不會從TLB刷出,在訪問固定映射的內存時,總是通過TLB高速緩存取得對應的物理地址。

> 正文

對每個固定映射地址都會創建一個常數,加入到fixed_addresses枚舉值列表中,__end_of_fixed_addresses是最後一個枚舉成員,定義了最大的可能數字。 linux_kernel_2.6.27.62/include/asm-x86/fixmap_32.h :: fix_to_virt()函數用於根據固定映射的fixed_addresses常數計算虛擬地址

  1. static __always_inline unsigned long fix_to_virt(const unsigned int idx)  
  2. {  
  3.     if(idx >= __end_of_fixed_addresses)  
  4.         __this_fixmap_does_not_exist();  
  5.     return __fix_to_virt(idx);  
  6. }  
Copyright © Linux教程網 All Rights Reserved