在board_r的启动序列中有
board_late_init
{
load_disk_partitions(这里解析了parameter参数)
board_fbt_preboot()这里检测了按键并且执行了启动流程
}
board_fbt_preboot中对按键进行了检查。随后根据不同按键执行不同的函数。
如果没有进行其他按键。最后正常的启动流程会走入
rkloader_run_misc_cmd函数(在rkloader.c中)
先找到misc的分区信息,这个分区信息是从前面load_disk_partitions里面解析的结构中得到的。
从MISC分区中读取bootload message
const disk_partition_t *ptn = get_disk_partition(MISC_NAME);
bmsg = (struct bootloader_message *)buf;
if (StorageReadLba(ptn->start + MISC_COMMAND_OFFSET, buf, DIV_ROUND_UP(
sizeof(struct bootloader_message), RK_BLK_SIZE)) != 0)
根据bmsg里面的命令执行。由于bmsg->command 既不是boot-recovery 也不是bootloader
所以返回false
最终导致从board_late_init返回了。继续执行
最终到了main_loop
在main_loop里面进入cli_loop前执行了
autoboot_command(s);
只有一条指令。那就是bootrk
接下来执行
do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd)
{
得到内核所在的分区信息默认先从boot分区开始
ptn = get_disk_partition(boot_source);
从分区中读取image到内存。并且取得image信息
hdr = rk_load_image_from_storage(ptn, &images);
设置命令行参数等等。也就是commandline这些 root=xxxxx这样的
rk_commandline_setenv(boot_source, hdr, charge);
接下来执行
do_bootm_linux(0, 0, NULL, &images); 正式启动内核。
}
rk_load_image_from_storage 首先从 boot分区中读取头部。查看头部是不是ANDROID!!
如果是的话。那么加载内核到内存中
如果不是,尝试使用rkimage_load_image从kernel分区和boot分区中读取内核和ramdisk
如果这次还是失败。
表示整个 rk_load_image_from_storage失败
,执行 board_fbt_boot_failed 。再尝试从recovery分区执行do_bootrk
如果从recovery分区执行do_boottk还是失败。尝试从backup分区执行do_bootrk
如果还是失败。执行do_rockusb模式 等待usb刷机。
void board_fbt_boot_failed(const char* boot)
{
printf("Unable to boot:%s\n", boot);
if (!memcmp(BOOT_NAME, boot, sizeof(BOOT_NAME))) {
printf("try to start recovery\n");
char *const boot_cmd[] = {"bootrk", RECOVERY_NAME};
do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd);
} else if (!memcmp(RECOVERY_NAME, boot, sizeof(RECOVERY_NAME))) {
printf("try to start backup\n");
char *const boot_cmd[] = {"bootrk", BACKUP_NAME};
do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd);
}
printf("try to start rockusb\n");
do_rockusb(NULL, 0, 0, NULL);
}
加载linux kernel完毕以后会尝试加载DTB
使用rkimage_load_fdt。
首先尝试从boot分区加载
如果加载失败。尝试从resource分区加载。
如果还是加载失败,则不再加载dtb。但是也不返回错误,认为这个kernel是不使用dtb的而是使用ATAG标记。