一、介绍
二、下载
u-boot源码下载地址
官方uboot下载:https://github.com/u-boot/u-boot、
++++https://ftp.denx.de/pub/u-boot/++++
NXP提供uboot下载 :https://source.codeaurora.org/external/imx/uboot-imx
三、u-boot源码目录分析
1.介绍


我们可以将整个uboot源码目录总结如下:
开发板相关目录 board cpu体系结构相关目录 arch通用的函数 common、lib通用的设备驱动、网络协议
程序 driver、net、disk、fs、postuboot实例程序、工具、文档 doc、examples、tools
2.arch目录
存放与架构有关的文件,这里只关注arch/arm文件夹即可
-- mach开头的文件夹跟具体的设备有关
-- cpu文件夹里是和cpu架构有关的
3.board目录
和具体的板子有关的,打开freescale文件夹,freescale芯片的板子都在此文件夹下
-- mx6ul开头的,表示使用IMX6UL芯片的板子
-- mx6ull开头的,表示使用IMX6ULL芯片的板子
-- mx6ullevk是NXP官方的IMX6ULL开发板
4.configs目录
存放uboot配置文件,一般半导体或开发板厂商会制作好一个配置文件,供用户在此基础上进行修改,配
置文件统一命名为" xxx_defconfig ",xxx表示开发板名字
5.include目录
存放的是uboot源码需要的头文件,这里我们关注** include/configs **目录,这个目录下存放的都是和具
体某一块开发板相关的头文件。如:mx6ullevk.h
四、编译
在u-boot的configs目录下有u-boot支持的开发板的默认配置文件,我们需要根据自己实际开发的开发板和
芯片 来选择相应的配置文件。

我们的小车使用的是imx6ull芯片,NXP官方基于这款芯片做了EVK开发板,我们可以使用** mx6ull_14x1
4_evk_defconfig **配置文件来进行u-boot配置。配置方法如下:

配置完成以后会生成** .config **文件。在u-boot编译的时候,Makefile就会根据.config里面的配置,选
择相关的代码进行编译。
2.菜单配置
u-boot和Linux内核一样支持菜单配置,菜单配置命令如下:
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ make menuconfig
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ make menuconfig

3.源码编译

uboot-imx-rel_imx_4.1.15_2.1.0_ga$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
ARCH :后面用来指定具体的CPU架构
CROSS_COMPILE :后面用来指定交叉开发工具链前缀
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
ARCH :后面用来指定具体的CPU架构-
CROSS_COMPILE :后面用来指定交叉开发工具链前缀
四、u-boot编译生成文件说明
1.u-boot.lds
u-boot.lds 是链接脚本文件,它由 ** arch/arm/cpu/u-boot.lds ** 拷贝而来,编译器根据它链接生成 u-boot
镜像
cpp
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.end :
{
*(.__end)
}
_image_binary_end = .;
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu.hash : { *(.gnu.hash) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}
2.u-boot
u-boot 这个文件是编译后产生的 ELF 格式的最原始的 U-Boot 镜像文件 . 我们可以通过源码录下的 .u-boo
t.cmd 这个命令脚本获取它的生成过程。

3.u-boot-nodtb.bin
这文件是使用编译工具链的 objcopy 工具从 u-boot 这个文件中提取来的,它只包含可执行的二进制代
码。就是把 u-boot 这个文件中对于执行不需要的节区删除后剩余的仅执行需要的部分。
由 .u-boot-nodtb.bin.cmd 这个命令脚本产生。

4.u-boot-dtb.bin
在 u-boot-nodtb.bin 尾部拼接上设备树后形成的文件。由 .u-boot-dtb.bin.cmd 这个命令脚本产生。
cpp
cmd_u-boot-dtb.bin := cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin
5.u-boot.bin
就是把 u-boot-dtb.bin 重命名得到的。由 .u-boot.bin.cmd 这个命令脚本产生。
cpp
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ cat .u-boot.bin.cmd
cmd_u-boot.bin := cp u-boot-nodtb.bin u-boot.bin
u-boot.imx 文件是 NXP 的 IMX 系列芯片使用的一种 u-boot 格式,它是通过在 u-boot.bin 添加一下配置信息
( 如 : 外部内存的配置信息 ,imx6ull 芯片内部的 IROM 代码会根据这个信息初始化外部内存 ) 生成。
cpp
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ cat .u-boot.imx.cmd
cmd_u-boot.imx := ./tools/mkimage -n board/freescale/mx6ullevk/imximage.cfg.cfgtmp
-T imximage -e 0x87800000 -d u-boot.bin u-boot.imx >/dev/null

7.u-boot.srec
"u-boot.srec" 是一个 摩托罗拉 S-Record 格式镜像 。由 .u-boot.srec.cmd 这个命令脚本产生。
cpp
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ cat .u-boot.srec.cmd
cmd_u-boot.srec := arm-linux-gnueabihf-objcopy --gap-fill=0xff -j .text -j .secure_text
-j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list
-j .rel.dyn -O srec u-boot u-boot.srec
8.u-boot.cfg
u-boot.cfg 包含所有用到的宏定义,阅读源码时可以检查 u-boot.cfg 文件 , 它是由 .u-boot.cfg.cmd 命令脚本
生成。
9.u-boot.sym
这个是从 u-boot 中导出的符号表文件。由 .u-boot.sym.cmd 这个命令脚本产生
10.u-boot.map
uboot 映射文件,通过此文件可以知道编译生成的 u-boot 由那些路径下的代码生成
11.System.map
记录 U-Boot 中各个符号 ( 全局变量和函数名 ) 在内存中位置
五、u-boot测试
因为默认情况下我们的开发板上面已经有了一个 u-boot 程序,我们可以用这个 u-boot 程序通过 tftp 把我们
编译生成的 u-boot 下载到内存中,然后通过 go 命令执行,测试编译生成的 u-boot 是否可以正常在内存运行
起来。
1. 拷贝 u-boot.bin 到 tftpboot 目录下
cpp
uboot-imx-rel_imx_4.1.15_2.1.0_ga$ cp u-boot.bin ../../tftpboot/
注意 :
u-boot.imx不能直接下载到内存中运行,因为它的先是配置数据,然后才是代码。这个文件用于烧
写到 emmc 或 sd 卡,通过 imx6ull 内部的 ROM 代码引导启动。
2. 下载到内存中运行 u-boot 程序
我们可以通过 System.map 文件获取 u-boot 在内存中运行的地址。

在开发板的 u-boot 命令行环境通过 tftp 命令下载 u-boot 到内存,然后运行 :
cpp
=> tftp 878000000 u-boot.bin
Using FEC0 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.200
Filename 'u-boot.bin'.
Load address: 0x78000000
Loading: #############################
2.7 MiB/s
done
Bytes transferred = 416472 (65ad8 hex)
=> go 87800000
## Starting application at 0x87800000 ...
