前面分析了Uboot在启动内核前所做的准备工作,现在针对bootz命令进行分析内核启动的过程。当Uboot启动后,我们可以设置bootcmd为以下内容,当倒计时结束则会启动内核:

不管是 bootz 还是 bootm 命令,在启动 Linux 内核的时候都会用到一个重要的全局变量:images
cmd/bootm.c
bootm_headers_t images; /* pointers to os/initrd/fdt images */
是一个bootm_headers_t的结构体:
typedef struct bootm_headers {
#ifndef USE_HOSTCC
image_info_t os; /* OS 镜像信息 */
ulong ep; /* OS 入口点 */
ulong rd_start, rd_end;/* ramdisk 开始和结束位置 */
char *ft_addr; /* 设备树地址 */
ulong ft_len; /* 设备树长度 */
ulong initrd_start; //initrd 开始位置
ulong initrd_end; //initrd 结束位置
ulong cmdline_start; //cmdline 开始位置
ulong cmdline_end; //cmdline 结束位置
bd_t *kbd;
#endif
int verify; /* getenv("verify")[0] != 'n' */
//表示 BOOT 的不同阶段
#define BOOTM_STATE_START (0x00000001)
#define BOOTM_STATE_FINDOS (0x00000002)
#define BOOTM_STATE_FINDOTHER (0x00000004)
#define BOOTM_STATE_LOADOS (0x00000008)
#define BOOTM_STATE_RAMDISK (0x00000010)
#define BOOTM_STATE_FDT (0x00000020)
#define BOOTM_STATE_OS_CMDLINE (0x00000040)
#define BOOTM_STATE_OS_BD_T (0x00000080)
#define BOOTM_STATE_OS_PREP (0x00000100)
#define BOOTM_STATE_OS_FAKE_GO (0x00000200) /* 'Almost' run the OS */
#define BOOTM_STATE_OS_GO (0x00000400)
int state;
#ifdef CONFIG_LMB
struct lmb lmb; /* for memory mgmt */
#endif
} bootm_headers_t;
typedef struct image_info {
ulong start, end; /* blob 开始和结束位置 */
ulong image_start, image_len; /* 镜像起始地址(包括 blob)和长度 */
ulong load; /* 系统镜像加载地址 */
uint8_t comp, type, os; /* 镜像压缩、类型, OS 类型 */
uint8_t arch; /* CPU 架构 */
} image_info_t;
do_bootz 函数
bootz 命令的执行函数为 do_bootz:
int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int ret;
/* Consume 'bootz' */
argc--; argv++;
if (bootz_start(cmdtp, flag, argc, argv, &images))
return 1;
/*
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
* disable interrupts ourselves
*/
bootm_disable_interrupts();//关闭中断
images.os.os = IH_OS_LINUX; //设置 images.os.os 为 IH_OS_LINUX,也就是设置系统镜像为 Linux
ret = do_bootm_states(cmdtp, flag, argc, argv,
BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
BOOTM_STATE_OS_GO,
&images, 1);//执行不同的 BOOT 阶段,这里要执行的 BOOT 阶段有:
//BOOTM_STATE_OS_PREP 、BOOTM_STATE_OS_FAKE_GO 和BOOTM_STATE_OS_GO
return ret;
}
bootz_start 主要用于初始化 im

文章详细分析了Uboot在启动Linux内核时的步骤,包括bootz命令的执行函数do_bootz,如何设置全局变量images,以及不同BOOT阶段如BOOTM_STATE_START、BOOTM_STATE_LOADOS等的处理。在启动过程中,涉及到内核镜像、ramdisk、设备树的查找和加载,最后通过boot_jump_linux函数跳转到Linux内核入口点执行。
最低0.47元/天 解锁文章
408

被折叠的 条评论
为什么被折叠?



