//在u-boot中用mtd命令可以看到u-boot的分区,uImage文件放在NAND FLASH的0x60000地址,但是 //uImage文件包括文件头+内核,文件头长64,故实际内核放在0x60000+64的地方,所以要从 //0x60000+64的地方读取内核到0x30008000,在SDRAM中内核存在哪里可以看内核的启动信息,一般 //0x30008000。
// 2. 设置参数 //
setup_start_tag();
setup_memory_tags();
setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
setup_end_tag();
// 3. 跳转执行 //
puts("Boot kernel\n\r");
theKernel = (void (*)(int, int, unsigned int))0x30008000;
theKernel(0, 362, 0x30000100); //第一个参数是0;第二个参数是机器ID,在内核里面用号码表示单板属于 //哪一类,内核里面会保存若干单板的ID;第三个参数表示参数的位置 //0x30000100,把参数的位置作为参数传给内核setup_start_tag函 //数中已经写死。
注意:第二个参数机器ID可以在u-boot函数:boot_jump_linux中unsigned long machid = gd->bd->bi_arch_number;中搜索“bi_arch_number”找到:board/samsung/smdk2440/smdk2410.c中定义:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;根据MACH_TYPE_SMDK2410的定义找到:
#define MACH_TYPE_S3C2440 362
//
* mov r0, #0
* ldr r1, =362
* ldr r2, =0x30000100
* mov pc, #0x30008000
//
// 如果一切正常, 不会执行到这里 //
return -1;
}
===============================================================
链接文件:
SECTIONS {
. = 0x33f80000;
.text : { *(.text) }
. = ALIGN(4);
.rodata : {*(.rodata*)}
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) *(COMMON) }
__bss_end = .;
}
===============================================================
注:
最简单的bootloader的编写步骤:
1. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
2. 如果bootloader比较大,要把它重定位到SDRAM
3. 把内核从NAND FLASH读到SDRAM
4. 设置"要传给内核的参数"
5. 跳转执行内核
改进:
1. 提高CPU频率, 200MHZ ==> 400MHZ
2. 启动ICACHE
存储地址解析:
u-boot文件存在nand flash/nor flash的0地址处,但正式在SDRAM中运行时的链接地址在链接脚本中已经注明,程序运行时应该在的地方:0x33f80000,因此从地址0x33f80000~0x34000000共512K用于存放u-boot。
在外部flash中,u-boot(bootloader)、params、kernel、root等存储地址可以在u-boot启动后用mtd命令可以看到u-boot的分区,uImage文件放在NAND FLASH的0x60000地址,但是uImage文件包括文件头+内核,文件头长64,故实际内核放在0x60000+64的地方,所以要从0x60000+64的地方读取内核到0x30008000,在SDRAM中内核存在哪里可以看内核的启动信息,一般是0x30008000。
栈是往下增长的,即从高地址向低地址增长。
注意:nor flash启动的u-boot既可以烧写nor flash本身也可以烧写nand flash,但是如果是nand flash启动的话就没办法操作nor flash,因为nand flash启动的时候0地址对应片内内存,无法访问nor flash。

