1. user space virtual address
2. physical address (hardware)
3. bus address (IO)
4. kernel logical address
5. kernel virtual address
__pa(x) 與 __va(x) 是用來轉換 kernel logical address 與 <-> physical address 用的 macro, 由 <asm/page.h> 定義。->
<->
通常 logical 跟 physical 只差在一個固定量的常數,以 ARM 為例為 PAGE_OFFSET,往下追蹤這兩個 macro 可找到:
->
<-><arch/arm/include/asm/memory.h>
->
#define __pa(x) __virt_to_phys((unsigned long)(x)) #define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
可知:
__pa(x) ==> __virt_to_phys, __va(x) ==> __phys_to_virt.
繼續追蹤,可以在同一個檔案看到如下這些定義:
#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
在較舊版本 Linux 中, PAGE_OFFSET 可能會直接指定, 但在較新版本 Linux 如 2.6.36 中可能會看到如下定義:
#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
看到 "CONFIG_" 開頭就不用想了, 這表示會在 autoconf.h 裡, 以 2.6.36 版為例可在 include/generated/autoconf.h 找到如下定義:
(舊版本 autoconf.h 路徑會有所不同)
#define CONFIG_PAGE_OFFSET 0xC0000000
而 PHYS_OFFSET 則依照平台不同而有所變化, 以 PXA 系列為例可以在下面檔案找到:
arch/arm/mach-pxa/include/mach/memory.h
定義內容如下:
#define PHYS_OFFSET UL(0xa0000000)
所以我們可以由此推算 logical 轉 physical 公式為:
physical = logical - 0xc0000000 + 0xa0000000
以 linux kernel 進入點為 0xc0008000 來說, 其對應的 physical address 就是 0xa0008000
然後我們就可以對照 System.map 這檔案的列表, 把想要的東西 dump 出來看,
如 Embedded Linux Primer 裡提到的利用 __log_buf 來除錯.
實際上來說, 0xa0000000 是 PXA270 的 physical address (Partitoin 0),
在 Marvell PXA310 EVM 中定義的 physical address 是 0x80000000,
Marvell PXA3xx Datasheet 的定義:
1.6.2.2 Dynamic Memory Controller Memory Map
Chip Select Address Space
nSDCS<1> (PXA32x processor only) 0xC000_0000 – 0xFFFF_FFFF
nSDCS<1> (PXA30x and PXA31x Only) 0xC000_0000 – 0xDFFF_FFFF
nSDCS<0> (PXA32x processor only) 0x8000_0000 – 0xBFFF_FFFF
nSDCS<0> (PXA30x and PXA31x only) 0x8000_0000 – 0x9FFF_FFFF
也因此如果自己拿新版 kernel 來 build 放到 EVM 上, 基本上只會看到
Uncompressing Linux... done, booting the kernel. 然後就當了.
知道原因之後, 只要把 0xa0000000 改成 0x80000000 就好了, 如下:
修改 #define PHYS_OFFSET UL(0xa0000000) 變成 #ifdef CONFIG_PXA3xx #define PHYS_OFFSET UL(0x80000000) #else #define PHYS_OFFSET UL(0xa0000000) #endif0>0>1>1>
沒有留言:
張貼留言