本帖讨论在usb启动模式中,uboot为何能在能在0x23e00000地址处运行。
先从nand启动模式说起。
x210因为只有512MB内存,nand启动模式下,初始化后内存物理地址空间为0x3000 0000 ~ 0x4FFF FFFF。
在x210_nand.h中有代码基址的定义:
#define MEMORY_BASE_ADDRESS 0x30000000
/* base address for uboot */
#ifdef CONFIG_ENABLE_MMU
#define CFG_UBOOT_BASE 0xc3e00000
#else
#define CFG_UBOOT_BASE 0x33e00000 /*yan*/
//#define CFG_UBOOT_BASE 0x23e00000 /*yan*/
#endif
#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x3e00000
#define CFG_PHY_KERNEL_BASE MEMORY_BASE_ADDRESS + 0x8000
一、nand启动
上电启动后,加载运行BL1,初始化硬件后,执行uboot中的 copy_uboot_to_ram 函数:
int copy_uboot_to_ram (void)
{
int large_block = 0;
int i;
vu_char id;
int rv;
NAND_CONTROL_ENABLE();
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READID;
NFADDR_REG = 0x00;
/* wait for a while */
for (i=0; i<200; i++);
id = NFDATA8_REG;
id = NFDATA8_REG;
if (id > 0x80)
large_block = 1;
else
return -1; // Do not support small page (512B) any more
/* read NAND blocks */
rv = nandll_read_blocks(CFG_PHY_UBOOT_BASE, COPY_BL2_SIZE);
#if defined(CONFIG_SECURE_BOOT)
rv = Check_Signature((SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
(unsigned char *)CFG_PHY_UBOOT_BASE,
(1024*512 - 128),
(unsigned char *)(CFG_PHY_UBOOT_BASE + (1024*512-128)),
128);
if (rv != SB_OK)
while(1);
#endif
return rv;
}
这里拷贝从nand flash 拷贝 uboot.bin到0x33e0 0000,大小为COPY_BL2_SIZE = 0x80000。
那么问题来了,nand启动时uboot 在0x33e0 0000处运行,然而,首次下载uboot时,使用dnw下载uboot.bin到0x23e0 0000,此时uboot位于0x23e0 0000,运行地址如何对应得上?不同的物理地址能运行同一个uboot?
我猜测是因为启用了MMU的关系.
在start.S中,配置MMU的代码如下
after_copy:
#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
/* enable domain access */
ldr r5, =0x0000ffff
mcr p15, 0, r5, c3, c0, 0 @load domain access register
/* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CFG_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0
/* Enable the MMU */
首先利用_mmu_table_base和0xfff00000进行位清除,得到当前uboot运行状态下,_mmu_table_base的低地址,存到r0。 r1存放CFG_PHY_UBOOT_BASE
CFG_PHY_UBOOT_BASE即0x33e00000和_mmu_table_base低地址进行或运算,得到0x33e_____,存入协处理器的转换表基址。
但依然分析不出代码如何能在0x23e00000运行。
第二篇:
我的板子是512M的s5pv210,在usb启动模式下,可以通过dnw直接下载到三星的官方uboot中运行,
具体步骤参考Sate210 android使用手册V1.0,百度文库就有。
我查看了源码,对链接地址有些疑惑。三星的uboot在aftercopy之后开启了MMU功能,
我的板子是512M内存,物理内存地址空间为0x3000 0000 ~0x4FFF FFFF,uboot源码设置的链接地址为0xc3e00000
根据uboot的mmu映射表:
#ifdef CONFIG_ENABLE_MMU
#ifdef CONFIG_MCP_SINGLE
/*
* MMU Table for SMDKC110
* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed
* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF VA = PA
* 0xC000_0000 -- 0xCFFF_FFFF => A:0x3000_0000 -- 0x3FFF_FFFF 256M
* 0xD000_0000 -- 0xDFFF_FFFF => Not Allowed
* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF VA = PA
*/
/* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
.word (\base << 20) | (\ap << 10) | \
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
.align 14
// the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0
// Access for iRAM
.rept 0x100 //对应虚拟地址0 ~ 256M
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
// Not Allowed
.rept 0x200 - 0x100 //对应虚拟地址256M ~ 512M
.word 0x00000000
.endr
.set __base,0x200
// should be accessed
.rept 0x600 - 0x200//对应虚拟地址512M ~ 1.5G
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
.rept 0x800 - 0x600//对应虚拟地址1.5G ~ 2G
.word 0x00000000
.endr
.set __base,0x800
// should be accessed
.rept 0xb00 - 0x800//对应虚拟地址2 ~ 2.75G
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
/* .rept 0xc00 - 0xb00
.word 0x00000000
.endr */
.set __base,0xB00
.rept 0xc00 - 0xb00//对应虚拟地址2.75G ~ 3G 256MB
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
.set __base,0x300
// 256MB for SDRAM with cacheable
.rept 0xD00 - 0xC00//对应虚拟地址3G ~ 3.25G, 256MB
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
// access is not allowed.
@.rept 0xD00 - 0xC80//对应虚拟地址3G ~ 3.125G
@.word 0x00000000
@.endr
.set __base,0xD00
// 1:1 mapping for debugging with non-cacheable
.rept 0x1000 - 0xD00//对应虚拟地址3.125G ~ 4G,
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
#else // CONFIG_MCP_AC, CONFIG_MCP_H, CONFIG_MCP_B
内存映射后的地址为:0xC0000000~0xCFFF FFFF请教各位前辈,dnw下载uboot到DDR中,
链接地址(MMU转换后为0x33e00000)与0x23e0 0000并不对应,后面的代码为什么还能正常运行呢?
我猜测是DDR初始化配置造成的,当CPU访问0x2000 0000的时候,其实和访问0x3000 0000是访问同一个DDR真实地址,
因为MENCONFIG0寄存器可以屏蔽地址高位,恩,应该是因为这个。这不是MMU映射造成的,
是cpuDDR初始化配置时屏蔽了地址高位。呵呵,三星的cpu真是方便阉割啊,1G内存变成512M还能用dnw下载uboot。
唉,求人不如求己啊,虽然想通了这是很简单的问题,但是毕竟板子和程序都不是自己设计的,谁能想起还有这个细节。蛋疼。
我烧写三星uboot后重启执行md 20000000,此时死机了,
比对uboot源码,说明uboot的DDR配置和x210_usb.bin(原名V210_USB.BL2.bin)的DDR配置是不同的,
如果相同后面跑内核就有问题了。
猜测x210_usb.bin(原名V210_USB.BL2.bin)的DDR应该配MENCONFIG0 = 0x30E01313,
这样无论访问0x23e0 0000还是访问0x33e0 0000,都会打开Xm1_CS0片选。