* - protected RAM * - LCD framebuffer * - monitor code * - board info struct */
len = (ulong)&_end - CONFIG_SYS_MONITOR_BASE;
/*
* Subtract specified amount of memory to hide so that it won't * get \ * the Linux kernel should now get passed the now \ * memory size and won't touch it either. This should work * for arch/ppc and arch/powerpc. Only Linux board ports in * arch/powerpc with bootwrapper support, that recalculate the * memory size from the SDRAM controller setup will have to * get fixed. */
gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize();//addr=128M
/* round down to next 4 kB limit */
addr &= ~(4096 - 1);//addr=addr&0xfffff000=0x800_0000;
debug (\
36
/*
* reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */
addr -= len; //len=0x52000; addr &= ~(4096 - 1);
debug (\
//addr =0x07fae000;
addr_sp = addr - TOTAL_MALLOC_LEN;//addr_sp=07f2c000 debug (\
TOTAL_MALLOC_LEN >> 10, addr_sp);
/*
* (permanently) allocate a Board Info struct * and a permanent copy of the \ */
addr_sp -= sizeof (bd_t);//addr_sp=07f2bfbc bd = (bd_t *) addr_sp; gd->bd = bd;
debug (\
sizeof (bd_t), addr_sp);//modify by huangjl
addr_sp -= sizeof (gd_t);
37
id = (gd_t *) addr_sp;//id= 07f2bf4c
debug (\
sizeof (gd_t), addr_sp);//modify by huangjl
/*
* Finally, we set up a new (bigger) stack. *
* Leave some safety gap for SP, force alignment on 16 byte boundary * Clear initial stack frame */
addr_sp -= 16; addr_sp &= ~0xF; s = (ulong *)addr_sp; *s-- = 0; *s-- = 0;
addr_sp = (ulong)s;
debug (\//addr_sp=0x07f2bf28
/*
* Save local variables to board info struct */
bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of DRAM memory */
bd->bi_memsize = gd->ram_size;
/* size of DRAM memory in bytes */
38
bd->bi_sramstart = 0;
/* FIXME */ /* start of SRAM memory /* FIXME */ /* size of SRAM memory
*/ */
bd->bi_sramsize = 0;
#if defined(CONFIG_MPC83xx)
bd->bi_immrbar = CONFIG_SYS_IMMR; #endif bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) WATCHDOG_RESET ();
bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ bd->bi_busfreq = gd->bus_clk;
/* Bus Freq, in Hz */
bd->bi_baudrate = gd->baudrate; /* Console Baudrate */
debug (\
WATCHDOG_RESET ();
WATCHDOG_RESET();
memcpy (id, (void *)gd, sizeof (gd_t));
*/
39
}
所以执行完代码后,几个关键的值为
//addr_sp=07f2bf28, id= 07f2bf4c,addr=07fae000 执行完后内存的分布情况如下图:
/* NOTREACHED - relocate_code() does not return */
relocate_code (addr_sp, id, addr);//addr_sp=07f2bf28, id= 07f2bf4c,addr=07fae000
0x0800_0000UBOOT代码内存空间(328KB)Addr:0x07fae000MALLOC内存空间(520KB)BD内存空间(68Byte)GD内存空间(112Byte)预留栈空间(16Byte)bdId:0x07f2bf4cAddr_sp:0x07f2bf280x0000_0000
其中addr为uboot将要复制到在内存中的起始地址。Bd保存开发板的信息。ID则保存全局变量信息,它是从cache中复制过来的。Addr_sp则指向可用内存的最高端地址。接下来是relocate_code函数,位于start.s汇编文件中,它是文件的精粹。 /*
* void relocate_code (addr_sp, gd, addr_moni) *
40