TQ2440开发板,u-boot2014.1,当前为smdk_2410默认配置,SDRAM为64MB。
_main中将sp赋值为CONFIG_SYS_INIT_SP_ADDR= 0x30000f60
sp = sp – 0xa0;//160为gd_t结构的大小
mov r9, sp //r9为gd结构体的地址。从以上可以看出sp入栈时递减,且是[--sp] = data
//gd是一个全局变量,存储一些关键的通用变量,当前位置在0x30000EC0,其定义如下:
typedef struct global_data {
bd_t*bd;
unsignedlong flags;
unsignedint baudrate;
unsignedlong cpu_clk; /* CPU clock in Hz! */
unsignedlong bus_clk;
/*We cannot bracket this with CONFIG_PCI due to mpc5xxx */
unsignedlong pci_clk;
unsignedlong mem_clk;
unsignedlong have_console; /* serial_init() wascalled */
unsignedlong env_addr; /* Address of Environment struct */
unsignedlong env_valid; /* Checksum of Environmentvalid? */
unsignedlong ram_top; /* Top address of RAM usedby U-Boot */
unsignedlong relocaddr; /* Start addressof U-Boot in RAM */
phys_size_tram_size; /* RAM size */
unsignedlong mon_len; /* monitor len */
unsignedlong irq_sp; /* irq stackpointer */
unsignedlong start_addr_sp; /*start_addr_stackpointer */
unsignedlong reloc_off;
structglobal_data *new_gd; /* relocated globaldata */
constvoid *fdt_blob; /* Our device tree,NULL if none */
void*new_fdt; /* RelocatedFDT */
unsignedlong fdt_size; /* Space reserved forrelocated FDT */
void**jt; /* jump table */
charenv_buf[32]; /* buffer for getenv()before reloc. */
unsignedlong timebase_h;
unsignedlong timebase_l;
structarch_global_data arch; /*architecture-specific data */
} gd_t;
进入board_init_f函数主要任务为初始化gd
gd->fdt_blob= (void *)getenv_ulong("fdtcontroladdr", 16,(uintptr_t)gd->fdt_blob);//不懂做什么
gd->mon_len= _bss_end_ofs; //此为u-boot程序占用空间,包含bss段
gd->ram_size //可以理解为SDRAM大小比如64MB
addr= CONFIG_SYS_SDRAM_BASE + gd->ram_size;
gd->arch.tlb_size= PGTABLE_SIZE = 4096 * 4; //为
addr&= ~(0x10000 - 1);
gd->arch.tlb_addr= addr;
debug("TLBtable from %08lx to %08lx\n", addr, addr + gd->arch.tlb_size);
/*reserve memory for LCD display (always full pages) */
addr= lcd_setmem(addr);//管它呢,又是减了一点就对了
gd->fb_base= addr;
addr-= gd->mon_len;
addr&= ~(4096 - 1);
debug("Reserving%ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
/*
* reserve memory for malloc() arena
*/
addr_sp= addr - TOTAL_MALLOC_LEN;
/*
* (permanently) allocate a Board Info struct
* and a permanent copy of the"global" data
*/
addr_sp-= sizeof (bd_t);
bd= (bd_t *) addr_sp;
gd->bd= bd;
addr_sp-= sizeof (gd_t);
id= (gd_t *) addr_sp;
debug("Reserving%zu Bytes for Global Data at: %08lx\n",sizeof (gd_t), addr_sp);
/*setup stackpointer for exeptions */
gd->irq_sp= addr_sp;
/*leave 3 words for abort-stack */
addr_sp-= 12;
/*8-byte alignment for ABI compliance */
addr_sp&= ~0x07;
debug("NewStack Pointer is: %08lx\n", addr_sp);
gd->bd->bi_baudrate= gd->baudrate;
/*Ram ist board specific, so move it to board code ... */
dram_init_banksize();
display_dram_config(); /* and display it */
gd->relocaddr= addr;
gd->start_addr_sp= addr_sp;
gd->reloc_off= addr - _TEXT_BASE;
debug("relocationOffset is: %08lx\n", gd->reloc_off);
if(new_fdt) {
memcpy(new_fdt,gd->fdt_blob, fdt_size);
gd->fdt_blob= new_fdt;
}
memcpy(id,(void *)gd, sizeof(gd_t));
以上程序为地址定位信息,然后打开debug,查看信息如下:
monitor len: 0009E848//此为u-boot程序占用空间,包含bss段
ramsize: 04000000
//即为64MB,所以sdram最后0x30000000+0x4000000-1=0x33ffffff
TLB table from 33ff0000 to 33ff4000//处于SDRAM的最末端
Top of RAM usable for U-Boot at: 33ff0000
Reserving 634k for U-Boot at: 33f51000
Reserving 4160k for malloc() at: 33b41000
Reserving 32 Bytes for Board Info at:33b40fe0
Reserving 160 Bytes for Global Data at:33b40f40//gd结构体新的地址
New Stack Pointer is: 33b40f30//新的堆栈指针,再上面的12个字节留给异常中断
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 33f51000
WARNING: Caches not enabled
monitor flash len: 0005B18C//此为不包含bss段的长度
Now running in RAM - U-Boot at: 33f51000
从上可得,接下来的程序会把原来的堆栈指针和原来的gd结构体指向新的地址,所以比如0x30000f60这个地址只是临时占用。
再接下来的程序会根据以上数据运行relocate_code。
结论为使用u-boot的时候临时使用sdram时用30000000h-330000000h即可。