嵌入式linux驱动之路17:U-Boot 启动流程(2)

bootz 启动 Linux 内核过程

在这里插入图片描述

在执行do_bootm_state函数之前设置images.os.os = IH_OS_LINUX设置镜像的操作系统类型为Linux,后面do_bootm_states函数启动内核时会根据它来找到对应的启动函数,do_bootm_states函数主要是将全局变量image清零并且设置一下它的几个成员就返回了。
通过函数 bootm_os_get_boot_func 来查找系统启动函数,参数 images->os.os 就是系统类型,根据这个系统类型来选择对应的启动函数, boot_os 是个数组,这个数组里面存放着不同的系统对应的启动函数,在 do_bootz 中设置 images.os.os= IH_OS_LINUX。函数返回值就是找到的系统启动函数,这里找到的 Linux 系统启动函数为 do_bootm_linux,do_bootm_linux也是调用 boot_prep_linux 来完成具体的处理过程。boot_prep_linux 主要用于处理环境变量bootargs,bootargs 保存着传递给 Linux kernel 的参数。
在函数 boot_jump_linux中变量 machid 保存机器 ID,如果不使用设备树的话这个机器 ID 会被传递给 Linux内核,Linux 内核会在自己的机器 ID 列表里面查找是否存在与 uboot 传递进来的 machid 匹配的项目,如果存在就说明 Linux 内核支持这个机器,那么 Linux 就会启动!如果使用设备树的话这个 machid 就无效了。
函数 kernel_entry,此函数是进入 Linux 内核的,此函数有三个参数,第一个参数 zero 同样为 0;第二个参数为机器 ID;第三个参数 ATAGS 或者设备树(DTB)首地址,ATAGS 是传统的方法,用于传递一些命令行信息啥的,如果使用设备树的话就要传递设备树(DTB)。
获取 kernel_entry 函数,函数 kernel_entry 并不是 uboot 定义的,而是 Linux 内
核定义的,Linux 内核镜像文件的第一行代码就是函数 kernel_entry,而 images->ep 保存着 Linux内核镜像的起始地址,起始地址保存的正是 Linux 内核第一行代码!
在这里插入图片描述
Linux 内核一开始是汇编代码,因此函数 kernel_entry 就是个汇编函数。向汇编函数传递参数要使用 r0、r1 和 r2(参数数量不超过 3 个的时候),所以 r2 寄存器就是函数 kernel_entry 的第三个参数。如果使用设备树的话,r2 应该是设备树的起始地址,而设备树地址保存在 images的 ftd_addr 成员变量中。如果不使用设备树的话,r2 应该是 uboot 传递给 Linux 的参数起始地址,也就是环境变量 bootargs 的值,然后调用 kernel_entry 函数进入 Linux 内核,此行将一去不复返,uboot 的使命也就完成了。
在这里插入图片描述
当缕清了 uboot 的启动流程以后,后面移植 uboot 就会轻松很多。其实在工作中我们基本不需要这么详细的去了解 uboot,半导体厂商提供给我们的 uboot 一般是可以直接用的,只要能跑起来,可以使用就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值