arm linux虛擬內存佈局【轉】

轉自:https://blog.csdn.net/sxw1002/article/details/52841762

Documentation/arm/memory.txt中的描述:
開始位置 結束位置 使用
0xffff8000 0xffffffff 用於 copy_user_page / clear_user_page。在SA11xx和Xscale平臺,用於建立一個迷你緩存映射
0xffff4000 0xffffffff armv6及以後的CPU cache混淆
0xffff1000 0xffff7fff 保留地址空間,各平臺不能使用
0xffff0000 0xffff0fff cpu中斷向量頁。如果CPU支持向量重定位(控制寄存器V bit),CPU中斷向量表映射到該地址範圍
0xfffe0000 0xfffeffff Xscale緩存沖刷區。在 proc-xscale.S文件中使用這個地址範圍沖刷整個數據緩存(Xscale沒有TCM).
0xfffe8000 0xfffeffff 各平臺的DTCM映射區
0xfffe0000 0xfffe7fff 各平臺的ITCM映射區
0xffc00000 0xffefffff 固定映射區,調用fix_to_virt()函數分配該區域
0xfee00000 0xfeffffff PCI I/O映射空間。是vmalloc空間的靜態映射
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() 空間。 vmalloc/ioremap返回的動態定位的內存區域,機器也可以通過iotable_init()函數指定靜態映射。 VMALLOC_START基於 high_memory的變化值。VMALLOC_END等於 0xff000000。
PAGE_OFFSET high_memory-1 內核直接映射內存區。所有平臺典型的1:1映射關係
PKMAP_BASE PAGE_OFFSET-1 內核持久映射區。映射高端內存頁到內核空間的方法之一
MODULES_VADDR MODULES_END-1 內核模塊映射空間。內核模塊通過insmod安裝並動態映射到此區域
0x00001000 TASK_SIZE-1 用戶進程映射區。每個進程通過mmap()函數映射到這個區域
0x00000000& 0x00000fff CPU向量頁/空指針陷阱。不支持中斷向量重映射的CPUs在此區間進行映射。內核和用戶空間釋放空指針也在此空間捕捉

 

 


以imx6dl爲例看一下具體的虛擬地址空間如何分配的,源碼參考自飛思卡爾基於linux-3.0.35版本發佈的imx6內核代碼),先上具體的映射佈局直觀感受一下:

 

 

                        圖 imx6dl虛擬內存空間佈局
具體地址及定義出處:

中斷向量映射區:
0xffff0000 ~ 0xffff1000 ( 4 kB)
  vector的起始地址在內核默認配置arch/arm/configs/qmx6_deconfig中定義CONFIG_VECTORS_BASE 爲0xffff0000,該映射區佔用一個頁的大小。

固定映射區:
0xfff00000 ~0xfffe0000 ( 896 kB)
  fixmap起始地址FIXADDR_START,結尾地址FIXADDR_TOP均定義在arch/arm/include/asm/fixmap.h,分別固定爲0xfff00000和0xfffe0000

DMA映射區:
0xf4600000 - 0xffe00000 ( 184 MB)
  起始位置CONSISTENT_BASE, 結束位置CONSISTENT_END均定義在 arch/arm/include/asm/memory.h,其中

CONSISTENT_BASE = CONSISTENT_END – CONSISTENT_DMA_ZISE
1
CONSISTENT_END固定爲0xffe00000
CONSISTENT_DMA_ZISE的定義在arch/arm/plat-mxc/include/mach/memory.h中,cpu爲MX6的開發板,大小爲184*SZ_1M

vmalloc映射區與DMA映射區的pages gap
  該區域被I/O映射所佔用,調用ioremap()會映射到這個區域中,具體定義在arch/arm/plat-mxc/include/mach/mx6.h中,外設基地址PERIPABASE_VIRT定義爲0xf2000000,爲I/O映射的起始地址

vmalloc映射區:
0xc0800000 - 0xf2000000 ( 792 MB)
  VMALLOC_START 定義在arch/arm/ include/asm/pgtable.h中,VMALLOC_START具體定義爲

#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
1
high_memory由物理內存的結束地址轉化而來,然後換算成虛擬地址,最後得到0xc0000000,也就是直接映射區(lowmem)的末尾。
  VMALLOC_OFFSET爲直接映射區到vmalloc的偏移量,大小8M,此page gap用於守護內存訪問越界錯誤。VMALLOC_END定義在arch/arm/plat-mxc/include/mach/vmalloc.h中,固定爲0xf2000000

直接內存映射區:
lowmem : 0x80000000 - 0xc0000000 (1024 MB)
  起始地址PAGE_OFFSET,結束地址爲high_memory,PAGE_OFFSET定義在.config中爲0x8000000,high_memory的值在bootmem_init時候計算出來,在vmalloc中計算VMALLOC_START時也應用了該值。

  內核鏡像映射地址空間在lowmem 範圍內,起始地址定義在vmlinx.lds.S中,爲PAGE_OFFSET+TEST_OFFSET,TEST_OFFSET定義在arch/arm/Makefile中,值爲0x00008000, 所以內核鏡像所在的起始地址爲0x80008000,其中又包括.init/.text/.data/.bss段等,就不詳細說了。而0x80000000~0x80008000的空間用於存放內核頁表,。

模塊映射區 :
modules : 0x7f000000 - 0x80000000 ( 16 MB)
起始地址MODULES_VADDR = PAGE_OFFSET – 16*1024*1024
結束地址MODULES_END = PAGE_OFFSET
定義在arch/arm/include/asm/memory.h中

用戶進程映射區
0x00000000 ~0x7f000000

TASK_SIZE = CONFIG_PAGE_OFFSET – 0x01000000
1
  定義在arch/arm/include/asm/memory.h,CONFIG_PAGE_OFFSET在lowmem中已經說明爲0x80000000,所減去的16M空間被modules所佔用,所以TASK_SIZE實際爲0x7f000000,而0x00000000爲起始的第一頁爲CPU向量頁/空指針陷阱。

參考資料:
Documentation/arm/memory.txt
Understanding The Linux Virtual Memory Manager (url https://www.kernel.org/doc/gorman/pdf/understand.pdf)
————————————————
版權聲明:本文爲CSDN博主「sxw1002」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sxw1002/article/details/52841762

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章