bootz启动linux内核——uboot生命的终点——学习笔记
Posted 西邮菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bootz启动linux内核——uboot生命的终点——学习笔记相关的知识,希望对你有一定的参考价值。
Image全局变量,里面保存着和启动有关的信息:存放这os结构体的各种变量,镜像起始地址、镜像长度、CPU的架构、系统的入口、设备树的相关信息。
在uboot命令行中敲入bootz命令后,开始启动内核。bootz对应的函数就是do_bootz。这个函数会依次执行以下三个函数:bootz_start、bootm_disable_interrupts、do_bootm_states。
一、bootz_start:
do_bootm_states(cmdtp, flag, argc, argv, 585 BOOTM_STATE_START, images, 1);BOOT 状态为BOOTM_STATE_START
上面就是调用do_bootm_states初始化Image全局变量,设置Image的ep成员变量,也就是系统镜像的入口点此 images->ep=0X80800000。
调用bootz_setup函数,此函数判断当前的系统镜像文件是否为Linux的镜像文件,并打印信息,通过image变量来判断。
调用函数 bootm_find_images 查找 ramdisk 和设备树(dtb)文件,但是我们没有 用到 ramdisk,因此此函数在这里仅仅用于查找设备树(dtb)文件。查找设备树(dtb)文件,找到以后就将设备树的起始地址和长度分别写到 images 的 ft_addr 和 ft_len 成员变量中。我们使用 bootz 启动 Linux 的时候已经指明了设备树在 DRAM 中的存储地址,因此 images.ft_addr=0X83000000,长度根据具体的设备树文件而定,比 如我现在使用的设备树文件长度为 0X8C81,因此 images.ft_len=0X8C81。
二、bootm_disable_interrupts
关闭中断。
三、do_bootm_states
do_bootm_states 根据不同的 BOOT 状态执行不同的代码段,这里只会用到三种BOOT状态:BOOTM_STATE_OS_PREP 、BOOTM_STATE_OS_FAKE_GO 和 BOOTM_STATE_OS_GO。
通过 函数 bootm_os_get_boot_func 来查找系统启动函数,参数 images->os.os 就是系统类型,根据这 个系统类型来选择对应的启动函数,在 do_bootz 中设置 images.os.os= IH_OS_LINUX。函数返 回值就是找到的系统启动函数,这里找到的 Linux 系统启动函数为 do_bootm_linux,所以boot_fn=do_bootm_linux。
BOOT=BOOTM_STATE_OS_PREP 状态时调用函数 do_bootm_linux,do_bootm_linux 也是调用 boot_prep_linux 来完成具体的处理过程。boot_prep_linux 主要用于处理环境变量 bootargs,bootargs 保存着传递给 Linux kernel 的参数。
BOOT=BOOTM_STATE_OS_FAKE_GO 状态时调用,不干啥!!!
调用函数 boot_selected_os 启动 Linux 内核,BOOT=BOOTM_STATE_OS_GO,执行boot_fn就是do_boot_linux。他调用了两个函数:
boot_prep_linux(images);
boot_jump_linux(images, flag);
boot_prep_linux 主要用于处理环境变量 bootargs,bootargs 保存着传递给 Linux kernel 的参数。上面已经写过了。
就只剩boot_jump_linux了,名字就可以看出,他是uboot进入内核的最后一步,先定义kernel_entry函数,再获取这个函数,这个函数是linux内核定义的!调用函数announce_and_cleanup 来打印一些信息并做一些清理工作。之后kernal_entry进入内核。
void (*kernel_entry)(int zero, int arch, uint params);
kernel_entry = (void (*)(int, int, uint))images->ep;
下面还是一个大神的图:
以上是关于bootz启动linux内核——uboot生命的终点——学习笔记的主要内容,如果未能解决你的问题,请参考以下文章