参考:U-Boot工程目录介绍
作者:一只青木呀
发布时间: 2020-10-21 14:47:30
网址:https://blog.csdn.net/weixin_45309916/article/details/109199081
首先得下载好uboot文件,并进行编译。
uboot下载:https://blog.csdn.net/weixin_45309916/article/details/109176510
进行编译后再进行分析
类型 | 名字 | 描述 | 备注 |
---|---|---|---|
文件夹 | api | 与硬件无关的API函数 | uboot自带 |
文件夹 | arch(架构) | 与架构有关的代码 | uboot自带 |
文件夹 | board | 不同板子(开发板)的定制代码 | uboot自带 |
文件夹 | cmd | 命令相关代码 | uboot自带 |
文件夹 | common | 通用代码 | uboot自带 |
文件夹 | config | 配置文件 | uboot自带 |
文件夹 | disk | 与磁盘分区相关代码 | uboot自带 |
文件夹 | doc | 文档 | uboot自带 |
文件夹 | drivers | 驱动代码 | uboot自带 |
文件夹 | dts | 设备树 | uboot自带 |
文件夹 | example | 示例代码 | uboot自带 |
文件夹 | fs | 文件系统 | uboot自带 |
文件夹 | include | 头文件数 | uboot自带 |
文件夹 | lib | 与库文件 | uboot自带 |
文件夹 | Licenses | 许可证相关文件 | uboot自带 |
文件夹 | net | 网络相关文件 | uboot自带 |
文件夹 | post | 上电自检程序 | uboot自带 |
文件夹 | scripts | 脚本文件 | uboot自带 |
文件夹 | test | 测试代码 | uboot自带 |
文件夹 | tools | 工具文件夹 | uboot自带 |
文件 | .config | 配置文件,重要的文件 | 编译成成的文件 |
文件 | .gitignore | git工具相关文件 | uboot自带 |
文件 | .mailmap | 邮件列表 | uboot自带 |
文件 | .u-boot.xxx.cmd(一系列) | 这是一系列的文件,用于保存着一些命令 | 编译生成的文件 |
文件 | config.mk | 某个Makefile会调用此文件 | uboot自带 |
文件 | Kbuild | 用于生成一些和汇编有关的文件。 | uboot自带 |
文件 | Kconfig | 图形配置界面描述文件 | uboot自带 |
文件 | MAINTAINERS | 维护者联系方式文件 | uboot自带 |
文件 | MAKEALL | 一个shell脚本,帮助生成uboot的 | uboot自带 |
文件 | Makefile | 主 Makefile,重要文件! | uboot自带 |
文件 | README | 相当于帮助文档。 | uboot自带 |
文件 | System.map | 系统映射文件 | 编译成成的文件 |
文件 | u-boot | 系统映射文件 | 编译成成的文件 |
文件 | u-boot.xxx(一系列) | 生成的一些 u-boot 相关文件,包括u-boot.bin、 u-boot.imx.等 | 编译成成的文件 |
上表中的很多文件夹和文件我们都不需要去关心,我们要关注的文件夹或文件如下:
先在Ubuntu 下编译一下uboot,然后将编译后的uboot 文件夹复制到windows 下,并创建VScode 工程。打开VScode,选择:文件->打开文件夹…,选中uboot 文件夹,如图31.2.1 所示:
打开uboot 目录以后,VSCode 界面如图31.2.2 所示:
点击“文件->将工作区另存为…”,打开保存工作区对话框,将工作区保存到uboot 源码根目录下,设置文件名为“uboot”,如图31.2.3 所示:
保存成功以后就会在uboot 源码根目录下存在一个名为uboot.code-workspace 的文件。这样一个完整的VSCode 工程就建立起来了。但是这个VSCode 工程包含了uboot 的所有文件,uboot中有些文件是不需要的,比如arch 目录下是各种架构的文件夹,如图31.2.4 所示:
在arch 目录下,我们只需要arm 文件夹,所以需要将其它的目录从VSCode 中给屏蔽掉,比如将arch/avr32 这个目录给屏蔽掉。
在VSCode 上建名为“.vscode”的文件夹,如图31.2.5 所示:
在.vscode 文件夹中新建一个名为“settings.json”的文件,然后在settings.json 中输入如下内容:
1 {
2 "search.exclude": {
3 "**/node_modules": true,
4 "**/bower_components": true,
5 },
6 "files.exclude": {
7 "**/.git": true,
8 "**/.svn": true,
9 "**/.hg": true,
10 "**/CVS": true,
11 "**/.DS_Store": true,
12 }
13 }
结果如图31.2.7 所示:
其中"search.exclude"里面是需要在搜索结果中排除的文件或者文件夹,"files.exclude"是左侧工程目录中需要排除的文件或者文件夹。我们需要将arch/avr32 文件夹下的所有文件从搜索结果和左侧的工程目录中都排除掉,因此在"search.exclude"和"files.exclude"中输入如图31.2.8 所示内容:
保存一下settings.json 文件,然后再看一下左侧的工程目录,发现arch 目录下没有avr32 这个文件夹了,说明avr32 这个文件夹被排除掉了,如图31.2.9 所示:
我们只是在"search.exclude"和"files.exclude"中加入了:“arch/avr32”: true,冒号前面的是要排除的文件或者文件夹,冒号后面为是否将文件排除,true 表示排除,false 表示不排除。用这种方法即可将不需要的文件,或者文件夹排除掉,对于本章我们分析uboot 而言,"search.exclude"和"files.exclude"中需要输入的完成的内容如下:
1 "**/*.o":true,
2 "**/*.su":true,
3 "**/*.cmd":true,
4 "arch/arc":true,
5 "arch/avr32":true,
6 "arch/blackfin":true,
7 "arch/m68k":true,
8 "arch/microblaze":true,
9 "arch/mips":true,
10 "arch/nds32":true,
11 "arch/nios2":true,
12 "arch/openrisc":true,
13 "arch/powerpc":true,
14 "arch/sandbox":true,
15 "arch/sh":true,
16 "arch/sparc":true,
17 "arch/x86":true,
18 "arch/arm/mach*":true,
19 "arch/arm/cpu/arm11*":true,
20 "arch/arm/cpu/arm720t":true,
21 "arch/arm/cpu/arm9*":true,
22 "arch/arm/cpu/armv7m":true,
23 "arch/arm/cpu/armv8":true,
24 "arch/arm/cpu/pxa":true,
25 "arch/arm/cpu/sa1100":true,
26 "board/[a-e]*":true,
27 "board/[g-z]*":true,
28 "board/[0-9]*":true,
29 "board/[A-Z]*":true,
30 "board/fir*":true,
31 "board/freescale/b*":true,
32 "board/freescale/l*":true,
33 "board/freescale/m5*":true,
34 "board/freescale/mp*":true,
35 "board/freescale/c29*":true,
36 "board/freescale/cor*":true,
37 "board/freescale/mx7*":true,
38 "board/freescale/mx2*":true,
39 "board/freescale/mx3*":true,
40 "board/freescale/mx5*":true,
41 "board/freescale/p*":true,
42 "board/freescale/q*":true,
43 "board/freescale/t*":true,
44 "board/freescale/v*":true,
45 "configs/[a-l]*":true,
46 "configs/[n-z]*":true,
47 "configs/[A-Z]*":true,
48 "configs/M[a-z]*":true,
49 "configs/M[A-Z]*":true,
50 "configs/M[0-9]*":true,
51 "configs/m[a-w]*":true,
52 "configs/m[0-9]*":true,
53 "configs/[0-9]*":true,
54 "include/configs/[a-l]*":true,
55 "include/configs/[n-z]*":true,
56 "include/configs/[A-Z]*":true,
57 "include/configs/m[a-w]*":true,
上述代码用到了通配符“ * ”,比如 “ * * / * .o”表示所有.o 结尾的文件。“configs/[a-l] *”表示configs 目录下所有以‘a’~‘l’开头的文件或者文件夹。上述配置只是排除了一部分文件夹,大家在实际的使用中可以根据自己的实际需求来选择将哪些文件或者文件夹排除掉。排除以后我们的工程就会清爽很多,搜索的时候也不会跳出很多文件了。
这个文件夹里面存放着和架构有关的文件,如下图所示:
从上图可以看出有很多架构,比如 arm、 avr32、 m68k 等,我们现在用的是 ARM 芯片,所以只需要关心 arm 文件夹即可,打开 arm 文件夹里面内容如下图所示:
mach 开头的文件夹是跟具体的设备有关的,比如“mach-exynos”就是跟三星的 exyons 系列 CPU 有关的文件、还有树莓派使用的mach-bcm283x。我们使用的是 I.MX6ULL,所以要关注“imx-common”这个文件夹。另外“cpu”这个文件夹也是和 cpu 架构有关的,打开以后如下图所示:
从上图可以看出有多种 ARM 架构相关的文件夹, I.MX6ULL 使用的 Cortex-A7 内核,Cortex-A7 属于 armv7,所以我们要关心“armv7”这个文件夹。 cpu 文件夹里面有个名为“uboot.lds”的链接脚本文件,这个就是 ARM 芯所使用的 u-boot 链接脚本文件! armv7 这个文件夹里面的文件都是跟 ARMV7 架构有关的,是我们分析 uboot 启动源码的时候需要重点关注的,里面还有一些dts设备树文件信息。
board 文件夹就是和具体的板子有关的,打开此文件夹,里面全是不同的板子,毫无疑问正点原子的开发板肯定也在里面(正点原子添加的), borad 文件夹里面有个名为“freescale”的文件夹(恩智浦里找不到,I.MX6ull以前是属于飞思卡尔的),如下图所示:
所有使用 freescale 芯片的板子都放到此文件夹中, I.MX 系列以前属于 freescale,只是freescale 后来被 NXP 收购了。打开此 freescale 文件夹,在里面找到和 mx6u(I.MX6UL/ULL)有关的文件夹,如下图所示:
上图中有 5 个文件夹,这 5 个文件夹对应 5 种板子,以“mx6ul”开头的表示使用I.MX6UL 芯片的板子,以 mx6ull 开头的表示使用 I.MX6ULL 芯片的板子。 mx6ullevk 是 NXP官方的I.MX6ULL开发板,正点原子的ALPHA开发板就是在这个基础上开发的,因此mx6ullevk也是正点原子的开发板。我们后面移植 uboot 到时候就是参考 NXP 官方的开发板,也就是要参考 mx6ullevk 这个文件夹来定义我们的板子。
此文件夹为 uboot 配置文件, uboot 是可配置的,但是你要是自己从头开始一个一个项目的配置,那就太麻烦了,因此一般半导体或者开发板厂商都会制作好一个配置文件。我们可以在这个做好的配置文件基础上来添加自己想要的功能,这些半导体厂商或者开发板厂商制作好的配置文件统一命名为“xxx_defconfig”, xxx 表示开发板名字,这些 defconfig 文件都存放在 configs文件夹,因此, NXP 官方开发板和正点原子的开发板配置文件肯定也在这个文件夹中,如下图所示:
上图中文件就是正点原子 I.MX6U-ALPHA 开发板所对应的 uboot 默认配置文件。我们只关心 mx6ull_14x14_ddr512_emmc_defconfig 和 mx6ull_14x14_ddr256_nand_defconfig这两个文件,分别是正点原子 I.MX6ULL EMMC 核心板和 NAND 核心板的配置文件。使用“make xxx_defconfig”命令即可配置 uboot,比如:
make mx6ull_14x14_ddr512_emmc_defconfig
上述命令就是配置正点原子的 I.MX6ULL EMMC 核心板所使用的 uboot。
在编译 uboot 之前一定要使用 defconfig 来配置 uboot!
在 mx6ull_alientek_emmc.sh 中就有下面这一句:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
这个就是调用 mx6ull_14x14_ddr512_emmc_defconfig 来配置 uboot,只是这个命令还带了一些其它参数而已。
.u-boot.xxx_cmd 是一系列的文件,这些文件都是编译生成的,都是一些命令文件,比如文件.u-boot.bin.cmd,看名字应该是和 u-boot.bin 有关的,此文件的内容如下:
cmd_u-boot.bin := cp u-boot-nodtb.bin u-boot.bin
.u-boot.bin.cmd 里面定义了一个变量: cmd_u-boot.bin,此变量的值为“cp u-boot-nodtb.binu-boot.bin”,也就是拷贝一份 u-boot-nodtb.bin 文件,并且重命名为 u-boot.bin,这个就是 u-boot.bin的来源,来自于文件 u-boot-nodtb.bin。
那 么 u-boot-nodtb.bin 是 怎 么 来 的 呢 ? 文 件 .u-boot-nodtb.bin.cmd 就 是 用 于 生 成 uboot.nodtb.bin 的,此文件内容如下:
cmd_u-boot-nodtb.bin := 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 binary u-boot u-bootnodtb.bin
这里用到了 arm-linux-gnueabihf-objcopy,使用 objcopy 将 ELF 格式的 u-boot 文件转换为二进制的 u-boot-nodtb.bin 文件。
文件 u-boot 是 ELF 格式的文件,文件.u-boot.cmd 用于生成 u-boot,文件内容如下:
cmd_u-boot := arm-linux-gnueabihf-ld.bfd -pie --gc-sections -
Bstatic -Ttext 0x87800000 -o u-boot -T u-boot.lds
arch/arm/cpu/armv7/start.o --start-group arch/arm/cpu/built-in.o
arch/arm/cpu/armv7/built-in.o arch/arm/imx-common/built-in.o
arch/arm/lib/built-in.o board/freescale/common/built-in.o
board/freescale/mx6ull_alientek_emmc/built-in.o cmd/built-in.o
common/built-in.o disk/built-in.o drivers/built-in.o
drivers/dma/built-in.o drivers/gpio/built-in.o drivers/i2c/builtin.o drivers/mmc/built-in.o drivers/mtd/built-in.o
drivers/mtd/onenand/built-in.o drivers/mtd/spi/built-in.o
drivers/net/built-in.o drivers/net/phy/built-in.o drivers/pci/builtin.o drivers/power/built-in.o drivers/power/battery/built-in.o
drivers/power/fuel_gauge/built-in.o drivers/power/mfd/built-in.o
drivers/power/pmic/built-in.o drivers/power/regulator/built-in.o
drivers/serial/built-in.o drivers/spi/built-in.o
drivers/usb/dwc3/built-in.o drivers/usb/emul/built-in.o
drivers/usb/eth/built-in.o drivers/usb/gadget/built-in.o
drivers/usb/gadget/udc/built-in.o drivers/usb/host/built-in.o
drivers/usb/musb-new/built-in.o drivers/usb/musb/built-in.o
drivers/usb/phy/built-in.o drivers/usb/ulpi/built-in.o fs/built-in.o
lib/built-in.o net/built-in.o test/built-in.o test/dm/built-in.o --
end-group arch/arm/lib/eabi_compat.o -L /usr/local/arm/gcc-linaro-
4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linuxgnueabihf/4.9.4 -lgcc -Map u-boot.map
.u-boot.cmd 使用到了 arm-linux-gnueabihf-ld.bfd,也就是链接工具,使用 ld.bfd 将各个 builtin.o 文件链接在一就形成了 u-boot 文件。 uboot 在编译的时候会将同一个目录中的所有.c 文件都编译在一起,并命名为 built-in.o,相当于将众多的.c 文件对应的.o 文件集合在一起,这个就是 u-boot 文件的来源。
如果我们要用 NXP 提供的 MFGTools 工具向开发板烧写 uboot,此时烧写的是 u-boot.imx文件,而不是 u-boot.bin 文件。 u-boot.imx 是在 u-boot.bin 文件的头部添加了 IVT、 DCD 等信息。这个工作是由文件.u-boot.imx.cmd 来完成的,此文件内容如下:
cmd_u-boot.imx := ./tools/mkimage -n
board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp -T imximage -
e 0x87800000 -d u-boot.bin u-boot.imx
可以看出,这里用到了工具 tools/mkimage,而 IVT、 DCD 等数据保存在了文件board/freescale/mx6ullevk/imximage-ddr512.cfg.cfgtmp 中 ( 如 果 是 NAND 核 心 板 的 话 就 是imximage-ddr256.cfg.cfgtmp),工具 mkimage 就是读取文件 imximage-ddr512.cfg.cfgtmp 里面的信息,然后将其添加到文件 u-boot.bin 的头部,最终生成 u-boot.imx。
文件.u-boot.lds.cmd 就是用于生成 u-boot.lds 链接脚本的
这个是顶层 Makefile 文件, Makefile 是支持嵌套的,也就是顶层 Makefile 可以调用子目录中的 Makefile 文件。 Makefile 嵌套在大项目中很常见,一般大项目里面所有的源代码都不会放到同一个目录中,各个功能模块的源代码都是分开的,各自存放在各自的目录中。每个功能模块目录下都有一个 Makefile,这个 Makefile 只处理本模块的编译链接工作,这样所有的编译链接工作就不用全部放到一个 Makefile 中,可以使得 Makefile 变得简洁明了。uboot 源码根目录下的 Makefile 是顶层 Makefile,他会调用其它的模块的 Makefile 文件,比如 drivers/adc/Makefile。当然了,顶层 Makefile 要做的工作可远不止调用子目录 Makefile 这么简单。
u-boot.xxx 同样也是一系列文件,包括 u-boot、 u-boot.bin、 u-boot.cfg、 u-boot.imx、 u-boot.lds、u-boot.map、 u-boot.srec、 u-boot.sym 和 u-boot-nodtb.bin,这些文件的含义如下:
文件 | 描述 |
---|---|
u-boot | 编译出来的 ELF 格式的 uboot 镜像文件。 |
u-boot.bin | 编译出来的二进制格式的 uboot 可执行镜像文件。 |
u-boot.cfg | uboot 的另外一种配置文件。 |
u-boot.imx | u-boot.bin 添加头部信息以后的文件, NXP 的 CPU 专用文件。 |
u-boot.lds | 链接脚本。 |
u-boot.map | uboot 映射文件,通过查看此文件可以知道某个函数被链接到了哪个地址上。 |
u-boot.srec | S-Record 格式的镜像文件。 |
u-boot.sym | uboot 符号文件。 |
u-boot-nodtb.bin | 和 u-boot.bin 一样, u-boot.bin 就是 u-boot-nodtb.bin 的复制文件。 |
uboot 配置文件, 使用命令“make xxx_defconfig”配置 uboot 以后就会自动生成, .config 内容如下:
可以看出.config 文件中都是以“CONFIG_”开始的配置项,这些配置项就是 Makefile 中的变量,因此后面都跟有相应的值, uboot 的顶层 Makefile 或子 Makefile 会调用这些变量值(前面树莓派的时候学过,.config文件引导Makefile把有用的东西组织成内核)。在.config 中会有大量的变量值为‘y’,这些为‘y’的变量一般用于控制某项功能是否使能,为‘y’的话就表示功能使能,比如:
CONFIG_CMD_BOOTD=y
如果使能了 bootd 这个命令的话, CONFIG_CMD_BOOTM 就为‘y’。在 cmd/Makefile 中有如下代码:
ifndef CONFIG_SPL_BUILD
# core command
obj-y += boot.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-y += help.o
obj-y += version.o
在示例代码中,有如下所示一行代码:
obj-$(CONFIG_CMD_BOOTM) += bootm.o
CONFIG_CMD_BOOTM=y,将其展开就是:
obj-y += bootm.o
也就是给 obj-y 追加了一个“bootm.o”, obj-y 包含着所有要编译的文件对应的.o 文件,这里表示需要编译文件 cmd/bootm.c。相当于通过“CONFIG_CMD_BOOTD=y”来使能 bootm 这个命令,进而编译 cmd/bootm.c 这个文件,这个文件实现了命令 bootm。在 uboot 和 Linux 内核中都是采用这种方法来选择使能某个功能,编译对应的源码文件
README 文件描述了 uboot 的详细信息,包括 uboot 该如何编译、 uboot 中各文件夹的含义、相应的命令等等。建议大家详细的阅读此文件,可以进一步增加对 uboot 的认识。