PPC U-Boot随读随写(1)
U-Boot目录下,board,cpu,include/configs在移植过程中会涉及。board主要是关于开发板的,flash驱动可以放在此;cpu如同其名,开发板所用的CPU,本文为MPC8260;include/configs一些系统定义,比如boot flash地址,boot参数,boot command等等,比较重要。U-Boot的编译可以参考Readme以及doc目录下的文档.
U-Boot从cpu/mpc8260/start.S启动,调用cpu_init_f初始化IMMR,然后bl board_init_f。
board_init_f中,gd指针指向CFG_INIT_RAM_ADDR+CFG_GBL_DATA_OFFSET,CFG_INIT_RAM_ADDR为CFG_IMMR即cpu内部ram,MPC8260 internal RAM为128K(0x2000),CFG_GBL_DATA_OFFSET=(0x2000 - 128),即为GD分配128bytes,位于internal RAM的(0x2000-128). 调用init_sequence初始化timebase/serial/clocks/console etc.,并把相关信息保存在gd里。接着分配RAM,从最高地址向下,分别分配Kernel log buffer,protected RAM,LCD framebuffer,memory for U-Boot code, data & bss,memory for malloc() arena,Board Info(比较重要),最后是设置新的stack,初始化bd,调用relocate_code(start.S).
main_loop()中,函数abortboot()用于中止auto boot,KEY在include/configs中CONFIG_AUTOBOOT_STOP_STR设置. 若是auto boot模式,获取bootcmd,getenv ("bootcmd"); run_command (s, 0)直接boot image. boot command在include/configs中CONFIG_BOOTCOMMAND定义,例如#define CONFIG_BOOTCOMMAND "bootm ff020000 ff120000" /* autoboot command */。
run_command()调用do_bootm(). do_bootm()中,解析参数个数,从第一个参数获取到kernel image的address,读出image header, CRC效验,hdr->ih_type为IH_TYPE_KERNEL,hdr->ih_comp为IH_COMP_GZIP,gunzip解压缩到hdr->ih_load,根据hdr->ih_os调用do_bootm_linux();do_bootm_linux()中,获取启动参数s = getenv("bootargs"),
strcpy (cmdline, s);
cmd_start = (ulong)&cmdline[0];
cmd_end = cmd_start + strlen(cmdline);
kernel指向(void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep), 参数大于3时,设置结构体kbd(board info),从参数argv[2]获取initrd的地址, data = ddr + sizeof(image_header_t); 设置initrd_start = data; initrd_end = initrd_start + len; 调用(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
Linux Kernel Parameters:
r3: ptr to board info data
r4: initrd_start or 0 if no initrd
r5: initrd_end - unused if r4 is 0
r6: Start of command line string
r7: End of command line string
启动kernel,执行arch/ppc/kernel/head.S.
以上bootloader解压内核到内存,然后跳转到内核入口处开始执行。
另外一种是内核自解压,入口在arch/ppc/boot/simple/head.S