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生命的终点——学习笔记_第1张图片

 

你可能感兴趣的:(linux,Linux驱动开发,BootLoader,linux)