uboot核心入口點30008000的由來(50008000同理)
uboot沒有虛擬記憶體管理,其程式直接訪問實體地址,所以30008000是實體地址,跳到這個地址,則核心便可以直接執行起來,而核心執行起來後,會馬上啟動MMU,進行虛擬記憶體對映(幾乎是馬上,之前只是比對了CPU和ARCH兩個引數),然後其程式訪問的便是虛擬記憶體。你之所以有這個困惑,我想是因為沒有弄明白uboot和核心其實是兩個獨立的
映像,核心啟動後uboot映像便不起作用了,而且其空間也會被核心初始化,這時kernel的stext實際上是由
核心對映生成時的連結器來決定的,連結器指定c0008000這麼一個不存在於實體地址空間的地址,是因為核心
是運行於虛擬空間的,因為它馬上就啟動了MMU。
下面先以核心2.6.28為例來先來看一下Linux中這個記憶體地址的由來。
首先看啟動程式碼程式碼arch/arm/kernel/head.S
29 #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)//定義虛擬記憶體首地址
30 #define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)//定義實際實體記憶體地址
PAGE_OFFSET的出處
程式碼arch/arm/include/asm/memory.c
27 #ifdef CONFIG_MMU
28
29 /*
30 * PAGE_OFFSET - the virtual address of the start of the kernel image
31 * TASK_SIZE - the maximum size of a user space task.
32 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
33 */
34 #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
程式碼include/linux/autoconf.h
#define CONFIG_PAGE_OFFSET 0xc0000000
PHYS_OFFSET 的出處
程式碼 arch/arm/mach-s3c6400/include/mach/memory.h //與6400平臺相關的記憶體設定
#define PHYS_OFFSET UL(0x50000000)
TEXT_OFFSET的定義在arch/arm/Makefile中,這個值是核心所在位置的實際偏移量,具體對這個值的說明看檔案arch/arm/kernel/head.S。
38 /*
39 * swapper_pg_dir is the virtual address of the initial page table.
40 * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
41 * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
42 * the least significant 16 bits to be 0x8000, but we could probably
43 * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
44 */
也就是說,從地址KERNEL_RAM_VADDR 開始的至少0x4000用來存放核心頁表,而存放核心頁表的空間值建議是0x8000。