u-boot顶层Makefile分析及u-boot启动流程分析

1. 清理整个u-boot工程

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean

        清理整个u-boot工程,包括编译出来的.o 、.h 、.bin 、 .imx 、.config 等,其中最重要的是.config,它是由使用u-boot的工程师来根据自己需要配置出来的文件,所以在清除时最好备份一下.config

2. 生成.config文件

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_my_emmc_defconfig

        mx6ull_my_emmc_deconfig配置文件是每个开发板都会有自己的配置文件,根据需要来进行配置,如最基本的你是使用的是arm的,就要写CONFIG_ARM=y,其会在条件编译出选择arm。

3. make整个顶层Makefile

 make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12

        编译出所需要的u-boot.bin。

3.1 u-boot.bin的头部信息的作用

        对于imx6ull,还需要u-boot.imx,这是NXP厂商在u-boot.bin的基础上添加一些头部信息,这些头部信息是给imx6ull的boot ROM用的。结构IVT+BOOT DATA+DCD+bin

        当上电后,内部boot ROM会先初始化时钟给各个外设使能,此时中断向量偏移会设置在boot ROM的起始位置,当 boot ROM 启动了用户代码以后就可以重新设置中断向量偏移了。一般是重新设置到我们用户代码的开始地方。

        此时在boot RAM模式下,可以通过GPIO模式下选择从SD卡、EMMC、NAND FLASH启动,这里一般选择从SD卡上启动。 load.imx 最前面的就是 IVT ,内部boot ROM要求IVT应放在指定位置,这个位置就是储存设备(SD卡)起始地址的偏移,偏移表为下图,SD卡的偏移量为1024字节,假如 SD/EMMC 每个扇区为 512 字节,那么 load.imx 应该从第三个扇区开始烧写,前两个扇区要留出来。load.imx 从第 3KByte 开始才是真正的.bin 文件。

        IVR作用:(SD卡是u-boot.imx的储存的地方,DDR是内部boot ROM 将u-boot.imx拷贝到DDR上储存,便于内核寄存器来进行读取指令)

        1. 确定镜像第一行指令的在DDR的位置。此开发板设置链接在DDR上的0x87800000

        2. 确定DCD指令在DDR的位置

        3.确定boot data指令在DDR的位置

        4.确定IVT指令在DDR在DDR的位置

        BOOT DATA作用:设置镜像大小

        DCD(DeviceConfig Data)初始化DDR3

        1.设置 CCGR0~CCGR6 这 7 个外设时钟使能寄存器,默认打开所有的外设时钟。
        2.配置 DDR3 所用的所有 IO。
        3.配置 MMDC 控制器,初始化 DDR3。

小结:

        将u-boot.imx存在SD卡上,在imx6ull的内部boot ROM模式下选择SD卡启动,在此模式下,芯片会执行内部的 boot ROM 代码,这段 boot ROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(就是存放代码的设备、比如 SD/EMMC、 NAND)中将代码拷贝出来复制到指定的 RAM 中,一般是将代码拷贝到DDR上。此时内部BOOT ROM使命结束,接下来启动u-boot代码。(即芯片上电时会现在boot ROM中取指令,当将SD卡的完整代码拷贝到DDR上后,再从DDR上取地址运行)

3.2 分析执行make时,Makefile怎么生成u-boot.bin

        以 u-boot.lds 为链接脚本,将 arch/arm/cpu/armv7/start.o 和各个子目录下的 built-in.o 链接在一起生成 u-boot。

        start.o 由start.S编译得:

        1.设置SVC模式,暂时关闭中断

        2.设置VBAR寄存器得中断偏移地址和SCTLR寄存器的允许软件重定位向量表

        3.初始化CP15

        4.进入_main

        重点就是各子目录下的 built-in.o 是怎么生成的,以 drivers/gpio/built-in.o 为例,在
drivers/gpio/目录下会有个名为.built-in.o.cmd 的文件,此文件内容如下:

1 cmd_drivers/gpio/built-in.o := arm-linux-gnueabihf-ld.bfd -r -o
drivers/gpio/built-in.o drivers/gpio/mxc_gpio.o

        从命令“cmd_drivers/gpio/built-in.o”可以看出, drivers/gpio/built-in.o 这个文件是使用 ld 命
令由文件 drivers/gpio/mxc_gpio.o 生成而来的, mxc_gpio.o 是 mxc_gpio.c 编译生成的.o 文件,
这个是 NXP 的 I.MX 系列的 GPIO 驱动文件。这里用到了 ld 的“-r”参数,参数含义如下:
        -r –relocateable: 产生可重定向的输出,比如,产生一个输出文件它可再次作为‘ld’ 的输入,这经常被叫做“部分链接”,当我们需要将几个小的.o 文件链接成为一个.o 文件的时候,需
要使用此选项

        最终将各个子目录中的 built-in.o 文件链接在一起就形成了 u-boot。

4. u-boot启动流程分析

        前面说到imx6ull的内部boot ROM会从SD卡中将u-boot代码拷贝到DDR中,即芯片内核要从DDR中读取指令来运行u-boot,下面就开始分析一下u-boot的启动流程。

        要分析 uboot 的启动流程,首先要找到“入口”,找到第一行程序在哪里。程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。编译一下 uboot,编译完成以后就会在 uboot 根目录下生成 u-boot.lds文件,可以发现当前代码的入口点为_start。u-boot.map 是 uboot 的映射文件,可以从此文件看到某个文件或者函数链接到了哪个地址。接着就是_image_copy_start为0x87800000,而.text 的起始地址也是0X87800000,.vectors 段保存中断向量表,vectors 段的起始地址也是 0X87800000,说明整个 uboot 的起始地址就是 0X87800000。裸机例程的链接起始地址选择 0X87800000 了,目的就是为了和 uboot 一致。接着将arch/arm/cpu/armv7/start.s 编译出来的代码放到中断向量表后面。start.s的作用3.2已经分析了,.text*放着其他代码。

        在 u-boot.lds 中有一些跟地址有关的“变量”需要我们注意一下,后面分析 u-boot 源码的
时候会用到,这些变量要最终编译完成才能确定的!!!比如我编译完成以后这些“变量”的值如下表。
 

rel_dyn段的分析:        

        程序编译时候我们会指定一个链接地址,编译后,cpu的pc指针指

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值