uboot启动linux内核流程分析(三)

uboot启动linux内核流程分析(三)_第1张图片

                                                      uboot bootz命令流程图

Uboot启动linux内核是使用bootz命令,bootz是如何启动linux内核?uboot的生命周期是怎么终止的?linux是如何启动?

启动linux内核的时候都会用到一个重要的局部变量:images,images在文件cmd/bootm.c中有定义。

images是bootm_headers_t类型的全局变量,

bootm_headers_t是个boot头结构体

os是image_info_t类型的,为系统镜像信息

全局变量images在bootz命令的执行中频繁使用,相当于linux内核启动的灵魂。

 

bootz命令的执行函数为do_bootz,在cmd/bootm.c中定义

1、调用bootz_start函数,在cmd/bootm.c中定义(主要是初始化images相关的成员变量)

①调用函数do_bootm_states执行BOOT_STATE_START阶段

②设置images的ep成员变量,也就是系统镜像的入口点,使用bootz命令启动时就会设置系统在DRAM中的存储位置,这个存储位置就是系统镜像的入口点,因此images->ep=0x80800000。

③调用bootz_setup函数,此函数会判断当前的系统镜像文件是否为linux镜像文件,并且打印出镜像的相关信息。

定义宏LINUX_ARM_ZIMAGE_MAGIC为ARMlinux系统魔术数,从传递进来的参数image(也及时系统镜像首地址)中获取zimage头,判断image是否为ARM linux系统镜像文件,并打印相关信息。

调用bootm_find_images查找ramdisk和设备(dtb)文件。

查找设备树的起始地址和长度,并分别写在images的ft_addr和ft_len成员变量中,我们使用bootz启动linux时已经指明设备树在DRAM中的存储地址,因此iamges.ft_addr=0x83000000

 

 

 

2、调用bootm_disable_interrupts函数  关闭中断

3、设置iamges.os.os为IH_OS_LINUX也就是设置系统镜像为linux,表示我们要启动的是linux系统,后面会调用images.os.os来挑选具体的启动函数。

         4、调用函数do_bootm_states来执行不同的BOOT阶段。要执行的BOOT阶段有:

①函数do_bootm_states根据不同的BOOT状态执行不同的代码段,通过

states&&BOOT_STATE_XXX来判断

这个BOOT状态

②通过函数bootm_os_get_boot_func来查找系统启动函数,参数iamges->os.os就是系统类型amges.os.os=IH_OS_LINUX,所以linux系统启动函数为do_bootm_linux=boot_fn

③处理BOOTM_STATE_OS_PREP状态,调用do_bootm_linux,即调用boot_prep_linux,主要处理环境变量bootargs,bootargs保存着传递诶linux kernel的参数。

④调用函数boot_selected_os启动内核,此函数第4个参数是linux系统镜像头,第5个参数是linux系统启动函数do_bootm_linux。

 

 

函数bootm_os_get_boot_func中的boot_os数组里面存放着不同系统对应的启动函数

函数do_bootm_linux

调用boot_jump_linux函数,变量machid保存机器idlinux内核会在自己的机器ID列表中查找是否存在与uboot传递来的machid匹配的项目,如果存在,则linux内核启动,如果使用设备树,这个machid就无效,设备树具有兼容性这个属性。boot_jump_linux函数调用kernel_entry函数,说明此函数进入linux内核,第一个参数为0,第二个参数为机器ID,第三个参数ATAGS(传统的方法)或者设备树的首地址。

获取kernel_entry函数,该函数并不是uboot定义的,而是linux内核定义的,linux内核镜像文件的第一行代码就是函数kernel_entry,而images->ep保存着linux内核镜像的起始地址,也就是linux内核的第一行代码。

最后调用announce_and_cleanup函数打印一些信息并做一些清理工作。

你可能感兴趣的:(内核,linux,嵌入式,c语言)