U-Boot初体验

U-Boot初体验

1 引言

U-Boot全称是Universal Boot Loader,即通用Bootloader,可以引导多种类型的操作系统,并支持多种架构的CPU。其本身是开源的,遵循GPL协议,可以看作是一个裸机综合程序,在嵌入式Linux领域被广泛使用。最主要的作用是从存储介质中加载Linux内核到内存中,向Linux内核传递启动参数,并启动Linux内核。

更多详细请参考如下链接:

U-Boot – DENX Software Engineering

The U-Boot Documentation — Das U-Boot unknown version documentation

接下来,我会以TI官方提供的用于BeagleBone Black开发板的U-Boot 2015.07为例,开始U-Boot的初体验。

2 U-Boot源码结构

2.1 整体结构

获得源码后,解压进入源码目录,可以发现U-Boot的源码有很多文件夹和文件组成,根目录下的文件组织如下所示:

image-20240303172634141

根目录下除了文件夹以外,上图中红框所标出的两个文件需要特别注意一下,它们是U-Boot图形化配置和编译的支撑性文件。

  • 除了根目录下,各个子目录基本也都存在Makefile和KConfig文件。

  • Makefile的作用时定义哪些文件被编译、什么条件下被编译、怎么编译等,子目录下的Makefile被顶层Makefile所包含。

  • 分布在各级目录下的KConfig构成了一个分布式的配置数据库,每个Kconfig分别描述了所属目录源文件相关的配置菜单。

  • 执行配置命令时,会读取KConfig文件,并在顶层目录下生成.config文件,该文件会在编译时被Makefile调用,由此知道用户的配置情况。

  • 关于KConfig和Makefile后面会有专题介绍,敬请期待,这里暂且略过。

2.2 目录解读

U-Boot源码根目录下的文件夹、文件按作用可以分为以下三类:

  • 平台依赖类:是与处理器体系结构或开发板硬件直接相关的
  • 通用类:包括通用的函数或者驱动程序
  • 其它类:包括U-Boot应用程序、工具文件或者文档
2.2.1 平台依赖目录
2.2.1.1 arch目录

arch目录下存放的是和处理器架构相关的文件,如下所示。可以看到很多不同的体系架构目录,我们使用的ARM处理器,仅需要关注图中箭头所指的arm目录即可。

image-20240303174723093

进入arm目录,如下所示,其中cpu目录下也是与架构相关的文件

image-20240303180039750

CPU目录的组织,如下图所示,我们使用的BeagleBone Black是Cortex-A8内核的,属于armv7。另外,cpu目录下有个名为u-boot.lds的链接脚本文件,这个就是ARM架构CPU所使用的链接脚本文件。关于链接脚本,后面的会有专题介绍,敬请期待。

image-20240303180147783

2.2.1.2 board目录

board目录是与具体的开发板相关的目录,打开此文件夹,里面是以不同厂商名字命名的目录,BeagleBone Black所使用的CPU是ti公司的,ti公司的名字赫然在列,如下所示:

image-20240303181025097

进入到ti目录下,有各种使用ti芯片的开发板目录,BeagleBone Black的开发板对应的目录是am335x,如箭头所示。

image-20240303181321536

2.2.1.3 configs目录

configs目录下为U-Boot的配置文件,我们知道U-Boot是支持不同架构、不同CPU、不同开发板、不同功能的程序集合,并且是可以配置的。一般来讲,开发者不会从零开始配置,都是基于半导体或者开发板厂商提前制作好的配置文件进行修改和匹配。毕竟实际产品开发过程中为降低风险和提升效率,硬件设计基本是基于半导体或者开发板厂商提供的Demo开发板进行修改的。

我们拿来学习的BeagleBone Black开发板,虽不是ti官方的开发板,但ti官方也是给予了支持,其对应的配置文件如下所示:

image-20240303182546749

2.2.2 通用目录
2.2.2.1 common目录

common目录下是U-Boot所支持的各种命令的实现文件,基本是每个以cmd_开头的文件对应一个具体的命令实现。

image-20240303194111642

2.2.2.2 disk目录

disk目录下是对磁盘操作命令的支持。

image-20240303193724343

2.2.2.3 fs目录

fs目录下是对各种文件系统的支持,如fat、jiffs、yaffs2、ubifs、ext4等,目前嵌入式系统中常用的是ext4。

image-20240303193919732

2.2.2.4 net目录

net目录下是与网络协议栈相关的代码,如基本的ping命令、TFTP、BOOTP、NFS文件系统等。

image-20240303193543247

2.2.2.5 lib目录

lib目录下是使用的公共库或者utils文件,如gzip、环形缓冲circbuf、crc16校验等

image-20240303194345700

2.2.2.6 drivers目录

drivers目录下全是驱动文件,U-Boot对各种网卡、Flash、串口和USB等的支持都在该目录,如下所示:

image-20240303170850379

2.2.2.7 post目录

post目录下是上电自检相关的文件源码,目前没有使用到。

2.2.2.8 dts目录

设备树文件夹,U-Boot后续的版本也会支持设备树。什么,U-Boot也要使用设备树?是的,你没看错,有些比较新的cpu,其使用的U-Boot就会支持设备树,比如ST的STMP15x系列。我们使用的U-Boot版本暂且不支持。

2.2.3 其它类目录
2.2.3.1 doc目录

doc目录下是一些帮助文档,如下所示:

image-20240303171213517

帮助文档的主题可以从文件的名字中看的出来,这里选择README.kconfig进行查看,内容如下:

Kconfig in U-Boot
=================

This document describes the configuration infrastructure of U-Boot.

The conventional configuration was replaced by Kconfig at v2014.10-rc1 release.


Language Specification
----------------------

Kconfig originates in Linux Kernel.
See the file "Documentation/kbuild/kconfig*.txt" in your Linux Kernel
source directory for a basic specification of Kconfig.


Difference from Linux's Kconfig
-------------------------------

Here are some worth-mentioning configuration targets.

- silentoldconfig

  This target updates .config, include/generated/autoconf.h and
  include/configs/* as in Linux.  In U-Boot, it also does the followings
  for the compatibility with the old configuration system:

   * create a symbolic link "arch/${ARCH}/include/asm/arch" pointing to
     the SoC/CPU specific header directory
   * create include/config.h
   * create include/autoconf.mk
   * create spl/include/autoconf.mk (SPL and TPL only)
   * create tpl/include/autoconf.mk (TPL only)

   If we could completely switch to Kconfig in a long run
   (i.e. remove all the include/configs/*.h), those additional processings
   above would be removed.

- defconfig

  In U-Boot, "make defconfig" is a shorthand of "make sandbox_defconfig"

- <board>_defconfig

  Now it works as in Linux.
  The prefixes such as "+S:" in *_defconfig are deprecated.
  You can simply remove the prefixes.  Do not add them for new boards.

- <board>_config

  This does not exist in Linux's Kconfig.
  "make <board>_config" works the same as "make <board>_defconfig".
  Prior to Kconfig, in U-Boot, "make <board>_config" was used for the
  configuration.  It is still supported for backward compatibility, so
  we do not need to update the distro recipes.


The other configuration targets work as in Linux Kernel.


Migration steps to Kconfig
--------------------------

Prior to Kconfig, the C preprocessor based board configuration had been used
in U-Boot.

Although Kconfig was introduced and some configs have been moved to Kconfig,
many of configs are still defined in C header files.  It will take a very
long term to move all of them to Kconfig.  In the interim, the two different
configuration infrastructures should coexist.
The configuration files are generated by both Kconfig and the old preprocessor
based configuration as follows:

Configuration files for use in C sources
  - include/generated/autoconf.h     (generated by Kconfig for Normal)
  - include/configs/<board>.h        (exists for all boards)

Configuration file for use in makefiles
  - include/config/auto.conf         (generated by Kconfig)
  - include/autoconf.mk              (generated by the old config for Normal)
  - spl/include/autoconfig.mk        (generated by the old config for SPL)
  - tpl/include/autoconfig.mk        (generated by the old config for TPL)

When adding a new CONFIG macro, it is highly recommended to add it to Kconfig
rather than to a header file.


Conversion from boards.cfg to Kconfig
-------------------------------------

Prior to Kconfig, boards.cfg was a primary database that contained Arch, CPU,
SoC, etc. of all the supported boards.  It was deleted when switching to
Kconfig.  Each field of boards.cfg was converted as follows:

 Status      ->  "S:" entry of MAINTAINERS
 Arch        ->  CONFIG_SYS_ARCH defined by Kconfig
 CPU         ->  CONFIG_SYS_CPU defined by Kconfig
 SoC         ->  CONFIG_SYS_SOC defined by Kconfig
 Vendor      ->  CONFIG_SYS_VENDOR defined by Kconfig
 Board       ->  CONFIG_SYS_BOARD defined by Kconfig
 Target      ->  File name of defconfig (configs/<target>_defconfig)
 Options     ->  CONFIG_SYS_EXTRA_OPTIONS defined by Kconfig
 Maintainers ->  "M:" entry of MAINTAINERS


Tips to add/remove boards
-------------------------

When adding a new board, the following steps are generally needed:

 [1] Add a header file include/configs/<target>.h
 [2] Make sure to define necessary CONFIG_SYS_* in Kconfig:
       Define CONFIG_SYS_CPU="cpu" to compile arch/<arch>/cpu/<cpu>
       Define CONFIG_SYS_SOC="soc" to compile arch/<arch>/cpu/<cpu>/<soc>
       Define CONFIG_SYS_VENDOR="vendor" to compile board/<vendor>/common/*
         and board/<vendor>/<board>/*
       Define CONFIG_SYS_BOARD="board" to compile board/<board>/*
         (or board/<vendor>/<board>/* if CONFIG_SYS_VENDOR is defined)
       Define CONFIG_SYS_CONFIG_NAME="target" to include
         include/configs/<target>.h
 [3] Add a new entry to the board select menu in Kconfig.
     The board select menu is located in arch/<arch>/Kconfig or
     arch/<arch>/*/Kconfig.
 [4] Add a MAINTAINERS file
     It is generally placed at board/<board>/MAINTAINERS or
     board/<vendor>/<board>/MAINTAINERS
 [5] Add configs/<target>_defconfig

When removing an obsolete board, the following steps are generally needed:

 [1] Remove configs/<target>_defconfig
 [2] Remove include/configs/<target>.h if it is not used by any other boards
 [3] Remove board/<vendor>/<board>/* or board/<board>/* if it is not used
     by any other boards
 [4] Update MAINTAINERS if necessary
 [5] Remove the unused entry from the board select menu in Kconfig
 [6] Add an entry to doc/README.scrapyard


TODO
----

- The option field of boards.cfg, which was used for the pre-Kconfig
  configuration, moved to CONFIG_SYS_EXTRA_OPTIONS verbatim now.
  Board maintainers are expected to implement proper Kconfig options
  and switch over to them.  Eventually CONFIG_SYS_EXTRA_OPTIONS will go away.
  CONFIG_SYS_EXTRA_OPTIONS should not be used for new boards.

- In the pre-Kconfig, a single board had multiple entries in the boards.cfg
  file with differences in the option fields.  The corresponding defconfig
  files were auto-generated when switching to Kconfig.  Now we have too many
  defconfig files compared with the number of the supported boards.  It is
  recommended to have only one defconfig per board and allow users to select
  the config options.

- Move the config macros in header files to Kconfig.  When we move at least
  macros used in makefiles, we can drop include/autoconfig.mk, which makes
  the build scripts much simpler.

接触过旧版本U-Boot的童鞋可能有所了解,以前的U-Boot是不支持KConfig的,从这篇帮助文档可以知道:从v2014.10-rc1才开始向Kernl看齐,引入了KConfig。

2.2.3.2 examples目录

examples目录下是例程,一些独立运行的应用程序,比如helloword,可以借鉴一下。

image-20240303183051902

2.2.3.3 tools目录

tools目录下是一些U-Boot使用的工具,比如mkimage、crc等

image-20240303184138583

2.2.3.4 scripts目录

scripts目录下是一些脚本文件,如下所示:

image-20240303184435550

3 U-Boot编译和启动

3.1 U-Boot编译步骤

(1) 设置交叉编译工具链,确保使用gcc-linaro-4.9-2015.05-x86_64_arm-linux-gnueabihf

(2) 编译之前清除一下,如果之前没有编译过,此步骤可选

make CROSS_COMPILE=arm-linux-gnueabihf- distclean

(3) 配置U-Boot

make CROSS_COMPILE=arm-linux-gnueabihf- O=./BeagleBoneBlack am335x_evm_defconfig
  • 通过***O=***选项指定编译输出目录,也可以不指定,则会在源文件目录下产生输出文件,和源文件混杂在一起。为了清晰,指定输出目录为根目录下的BeagleBoneBlack
  • TI AM335X系列的开发板会板载一个EEPROM,存储开发板类型。U-Boot会从EEPROM中读取信息,判断开发板类型。故不管是am335x_evm还是AM335x GP EVM或者BeagleBone Black采用的均是am335x_evm_defconfig配置文件。如果是自己制做的硬件,要么在EEPROM中写入数据,要么在U-Boot中将读取EEPROM的代码去掉。

执行结果如下所示,执行结束后,会在U-Boot源码根目录下生成BeagleBoneBlack目录

image-20231231211918808

image-20231231212826513

(4) 编译U-Boot

make CROSS_COMPILE=arm-linux-gnueabihf- O=./BeagleBoneBlack

执行编译命令,编译过程需要一定时间,视电脑性能而定。

编译完成后,进入BeagleBoneBlack目录查看,生成最终可用的MLO和U-Boot.img文件,还有很多中间文件、U-Boot map文件和链接脚本等文件,如下所示:

image-20231231212938530

3.2 U-Boot启动

U-Boot编译好之后,将编译生成u-boot.img和MLO放入到已准备好的SD卡的boot分区,如下所示:

image-20240309090852804

如果SD卡中已经有内核镜像和根文件系统,则会顺势启动整个系统。如果需要停留再U-Boot阶段,按箭头所示,在启动时,按下任意按键,如下所示,则表示U-Boot已经正常启动

image-20231231213605862

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序匠小飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值