bootz启动Linux内核过程

bootz启动Linux内核过程_第1张图片

 

 1.image全局变量
不管是 bootz 还是 bootm 命令,在启动 Linux 内核的时候都会用到一个重要的全局变量:
images,images 在文件 cmd/bootm.c 中有如下定义:
 

 bootm_headers_t images;
bootz_start 主要用于初始化 images 的相关成员变量。

 2.announce_and_cleanup定义在文件 arch/arm/lib/bootm.c 中,

 
 static void announce_and_cleanup(int fake)
 {
 printf("\nStarting kernel ...%s\n\n", fake ?
 "(fake run for tracing)" : "");
 bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
......
 cleanup_before_linux();
}

我们通常会看见下图输出,这是announce_and_cleanup函数

bootz启动Linux内核过程_第2张图片

 3.announce_and_cleanup函数结束,就会正式进入kernel_entry 函数,至此,uboot使命就此结束。

 static void boot_jump_linux(bootm_headers_t *images, int flag)
 {
 #ifdef CONFIG_ARM64
......
 #else
 unsigned long machid = gd->bd->bi_arch_number;
 char *s;
 void (*kernel_entry)(int zero, int arch, uint params);
 unsigned long r2;
 int fake = (flag & BOOTM_STATE_OS_FAKE_GO);

 kernel_entry = (void (*)(int, int, uint))images->ep;

 s = getenv("machid");
 if (s) {
 if (strict_strtoul(s, 16, &machid) < 0) {
 debug("strict_strtoul failed!\n");
 return;
 }
 printf("Using machid 0x%lx from environment\n", machid);
 }

 debug("## Transferring control to Linux (at address %08lx)" \
 "...\n", (ulong) kernel_entry);
 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 
 announce_and_cleanup(fake);

 if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
     r2 = (unsigned long)images->ft_addr;//使用设备树的话,r2 应该是设备树的起始地址,而设备树地址保存在 images
 else
    r2 = gd->bd->bi_boot_params;//如果不使用设备树的话,r2 应该是 uboot 传递给 Linux 的参数起始地址,也就是环境变量 bootargs 的值,

......
 kernel_entry(0, machid, r2);
 }
 #endif
 }
调用 kernel_entry 函数进入 Linux 内核,此行将一去不复返, uboot 的使命也就
完成了。

你可能感兴趣的:(linux,运维,服务器)