uboot流程分为第一阶段(芯片初始化、重定位等)和第二阶段(各项功能),在第二阶段的最后,启动内核
1、s = getenv ("bootcmd"); //"nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0"
2、run_command (s, 0);
读内核到SDRAM:
(1)NAND FLASH分区
#define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k@0( bootloader)," \"128k( params)," \
"2m( kernel)," \
"-( root)"
(2)nand read.jffs2不用考虑地址对齐
nand read.jffs2 0x30007FC0 0x60000 0x200000
bootm流程:
1、uImage包含头和真正的内核,头大小64字节,0x30007FC0 + 64 = 0x30008000。
如果当前地址和头里面的装载地址不一致,do_bootm函数会将uImage移动到头里面指定的装载地址,一般不用移动。
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */ //0x30007FC0
uint32_t ih_ep; /* Entry Point Address */ //0x30008000
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
2、do_bootm_linux
(1)theKernel指向头里面的入口地址
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
(2)设置参数,参数存放在gd->bd->bi_boot_params = 0x30000100
setup_start_tag (bd);
setup_memory_tags (bd); //start = 0x30000000, size = 0x4000000(64M)
setup_commandline_tag (bd, commandline); //"noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
setup_end_tag (bd);
(3)跳入内核
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);