U-Boot

来自资料库(何亚红)
跳转到导航 跳转到搜索

源代码

主要

https://source.denx.de/u-boot/u-boot

备用

https://github.com/u-boot/u-boot.git

说明

通用引导加载器。通常用于加载Linux

常用编译命令参数如下(适用于截止编辑时的最新版u-boot):

项目 类型 说明 备注
menuconfig Makefile目标 使用菜单配置u-boot 必须先加载某个默认配置再使用菜单配置。默认配置在configs目录,可使用make 默认配置名加载。
all Makefile目标 构建 这是默认目标,也可省略不带任何目标
ARCH 环境变量/Makefile变量 指定架构 可在arch目录中查看支持的架构,如32位arm则可指定ARCH=arm
CROSS_COMPILE 环境变量/Makefile变量 指定交叉编译工具链前缀 如若要使用arm-none-eabi-gcc则可指定CROSS_COMPILE=arm-none-eabi-

环境变量(Env)

注意:若未特殊说明,此说明仅适用于截至编辑时的u-boot,不包括旧版u-boot。

Env表示环境变量,很多u-boot的操作及脚本都靠环境变量调控。

默认环境变量主要有以下方式生成:

  • Kconfig配置生成。
  • 直接文件生成。

默认情况下使用Kconfig配置生成默认Env,默认环境变量具体定义的头文件/目录/机制如下:

  • include/env_default.h文件:定义默认的环境变量与Kconfig配置的关系。
  • include/configs目录:各个SOC厂商的配置头文件,一般使用CFG_EXTRA_ENV_SETTINGS宏定义在厂商头文件定义厂商自己的环境变量。

直接使用文件生成默认Env的机制如下:

  • 厂商的配置文件:默认目录为board/<vendor>/<board>/,文件名可以由CONFIG_ENV_SOURCE_FILESYS_BOARD指定,后缀名为.env。
  • 外部的配置文件:使用CONFIG_USE_DEFAULT_ENV_FILE使能,使用CONFIG_DEFAULT_ENV_FILE指定位置。注意:若启用外部的配置文件将导致Kconfig中的相关选项不可用,直接完全由用户管理。

启动介质

注意:若未特殊说明,此说明仅适用于截至编辑时的u-boot,不包括旧版u-boot。

u-boot可从多种存储介质上启动,具体支持的启动方式根据硬件方案的不同而不同,本章只描述本人常用的方式。

SD卡/TF卡

采用MMC接口,常见于各种开发板。

通常会有一个完整的镜像,采用MBR磁盘分区或者GPT磁盘分区,包含一个FAT分区(方便在Windows更新相关文件)及若干个其他分区,U-boot的启动脚本与Linux内核放在FAT分区。

可使用以下方式烧录镜像:

  • dd:在Linux或其他(类)unix中可使用dd命令直接将镜像写入SD卡/TF卡。
  • win32diskimager:在windows下可使用此工具写入镜像文件。

对于本人而言,除了开发板厂商提供的方式,本人还可使用Buildroot产生镜像。

分区

分区采用MBR磁盘分区或者GPT磁盘分区,编辑同pc机一样,有广泛的工具可供使用。

由于磁盘镜像一般都是尽量做小,故烧录后的rootfs可能不是很大,则对于大容量SD卡/TF卡则需要调整rootfs分区。

对于采用ext2/ext3/ext4的rootfs分区而言,可采用以下步骤调整分区:

  • 调整分区表:采用各种通用工具调整rootfs的分区表(Linux下可采用fdisk),扩大分区大小。调整完成后最好进行一次重启。
  • 调整文件系统:当分区表调整完成后只是分区大小发生改变,文件系统中的信息并未发生改变,故应当使用resize2fs命令将文件系统调整为分区大小。
数据加载

对于传统的u-boot启动过程而言,所有数据都需要加载到内存中才能继续操作(如启动等)。

可使用mmc命令读取SD卡/TF卡数据,但一般不使用此命令加载数据。

SD卡/TF卡一般采用了MBR磁盘分区或者GPT磁盘分区,并且使用常用的文件系统(如fat、ext2、ext4),各种文件也是放在文件系统中的.

因此更加常用的是采用文件系统相关命令加载数据到内存,常用的的命令如下:

文件系统 数据加载命令 说明
fat32 fatload 从fat文件系统加载数据,如启动脚本、Linux内核、设备树dtb、环境变量文件等
ext2 ext2load 从ext2文件系统加载数据。
ext4 ext4load 从ext4文件系统加载数据。
- load 从文件系统中加载数据。这是一个通用版本,可方便脚本的编写。
移植提示

如需操作mmc设备,需要在 > Command line interface > Device access commands使能 CONFIG_CMD_MMC以启用mmc命令。

如需操作fat文件系统 ,需要在> Command line interface > Filesystem commands使能CONFIG_CMD_FAT启用相关命令。

如需操作ext2文件系统 ,需要在> Command line interface > Filesystem commands使能CONFIG_CMD_EXT2启用相关命令。

如需操作ext4文件系统 ,需要在> Command line interface > Filesystem commands使能CONFIG_CMD_EXT4启用相关命令。

如需使用通用方式操作文件系统,需要在> Command line interface > Filesystem commands使能CONFIG_CMD_FS_GENERIC启用相关命令。

SPI Nor Flash

采用SPI接口。若未说明,本人一般使用容量大于等于16MBytes的Nor Flash。

Nor Flash的烧录方式根据SOC的不同而不同,具体如下:

  • 对于全志SOC而言,可进入FEL模式采用Xfel烧录。

由于Nor Flash容量较小,一般分区使用固定分区,即没有任何分区表与磁盘信息存储在介质上,直接在代码或配置(如设备树dts)中写死分区信息数据。

分区

MTD设备的分区使用环境变量决定,具体如下:

环境变量名称 u-boot中的注释 说明
partition 'partition' - keeps current partition identifier

*

* partition  := <part-id>

* <part-id>  := <dev-id>,part_num

相当于其它分区表的激活分区。

dev-id同mtdids中的dev-id。

mtdids 'mtdids' - linux kernel mtd device id <-> u-boot device id mapping

*

* mtdids=<idmap>[,<idmap>,...]

*

* <idmap>    := <dev-id>=<mtd-id>

* <dev-id>   := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>

* <dev-num>  := mtd device number, 0...

* <mtd-id>   := unique device tag used by linux kernel to find mtd device (mtd->name)

mtd设备id列表。

dev-id的格式是固定(如第一个nor flash的dev-id为nor0)。

此环境变量相当于将mtd设备与linux中的标签对应,使得mtdparts可以直接传给Linux内核。

mtdparts 'mtdparts' - partition list

*

* mtdparts=[mtdparts=]<mtd-def>[;<mtd-def>...]

*

* <mtd-def>  := <mtd-id>:<part-def>[,<part-def>...]

* <mtd-id>   := unique device tag used by linux kernel to find mtd device (mtd->name)

* <part-def> := <size>[@<offset>][<name>][<ro-flag>]

* <size>     := standard linux memsize OR '-' to denote all remaining space

* <offset>   := partition start offset within the device

* <name>     := '(' NAME ')'

* <ro-flag>  := when set to 'ro' makes partition read-only (not used, passed to kernel)

mtd设备分区表。

u-boot的mtd分区信息可以通过内核命令行传给启用了命令行传MTD分区参数的Linux内核,但更加常见的是使用设备树dts传MTD分区参数给Linux内核。

u-boot中mtd分区的例子如下:

/*
 * Examples:
 *
 * 1 NOR Flash, with 1 single writable partition:
 * mtdids=nor0=edb7312-nor
 * mtdparts=[mtdparts=]edb7312-nor:-
 *
 * 1 NOR Flash with 2 partitions, 1 NAND with one
 * mtdids=nor0=edb7312-nor,nand0=edb7312-nand
 * mtdparts=[mtdparts=]edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
 *
 */

默认分区信息的Kconfig在启用mtdparts命令时可填写,如下:

Kconfig项 环境变量项
CONFIG_MTDIDS_DEFAULT mtdids
CONFIG_MTDPARTS_DEFAULT mtdparts
全志SOC

默认情况下(u-boot在全志SOC默认设置),采用以下分区:

起始地址 大小(字节) 名称 说明
0 0xF0000(960KBytes) u-boot u-boot二进制代码所在位置
0xF0000 0x10000(64KBytes) u-boot-env u-boot的env数据,可保存一些u-boot使用的环境变量,可保存修改后的启动行为。
0x100000 - - 剩余位置,可继续划分分区。

数据加载

对于传统的u-boot启动过程而言,所有数据都需要加载到内存中才能继续操作(如启动等)。

一般使用mtd命令加载mtd设备或mtd分区数据到内存中,一般通过偏移加大小确定数据位置。

由于SPI Nor Flash一般不包含传统分区表,如需使用文件系统也是特殊的文件系统,所以一般不使用文件系统相关命令加载数据。

移植提示

SPI Nor Flash使用条件:

  • SOC支持从SPI Nor Flash启动。
  • u-boot已经移植有对应SOC的spi驱动。

配置SPI Nor Flash的支持如下:

  • 配置Kconfig
    启用属于MTD设备的SPI Nor Flash
        Kconfig路径: > Device Drivers > MTD Support > SPI Flash Support 
        选中CONFIG_SPI_FLASH并CONFIG_BOOTDEV_SPI_FLASH且选中需要支持的Nor Flash。
    
    启用SPI驱动设备(只需要选中对应SOC的驱动)
        Kconfig路径:> Device Drivers > SPI Support
    
  • 配置设备树(同Linux一样)。
    /*以下代码主要用于启用spi0上的flash*/
    &spi0 {
            flash@0 {
                    compatible = "jedec,spi-nor";
                    reg = <0>;
                    spi-max-frequency = <40000000>;
            };
    };
    

若u-boot需要使用spl则需要在spl中启用spi nor flash支持(具体方法根据芯片及板子的不同而不同),粗略配置如下:

  • 配置Kconfig
    启用属于MTD设备的SPI Nor Flash的SPL支持
        Kconfig路径: > Device Drivers > MTD Support > SPI Flash Support 
        选中CONFIG_SPL_SPI_FLASH_MTD。
    
    在SPL中选中MTD支持
        Kconfig路径: > SPL configuration options
        选中SPI FLASH相关选项。
    

有些spi nor flash的jedec id可能不在u-boot的支持列表中,可能需要手动向drivers/mtd/spi/spi-nor-ids.c中添加需要支持的id。

如需操作mtd设备,需要在 > Command line interface > Device access commands使能CONFIG_CMD_MTD以启用mtd命令。

如需使用mtd分区,需要在> Command line interface > Filesystem commands使能CONFIG_CMD_MTDPARTS 以启用mtdparts命令。

SPI Nand Flash

采用SPI接口。若未说明,本人一般使用容量大于等于128MBytes的Nand Flash。

SPI Nand Flash的绝大多数操作均可参考SPI Nor Flash,在u-boot也属于mtd设备,只是相关子项需要选择Nand Flash。

一般情况下,SPI Nand Flash的容量可以做得比SPI Nor Flash大,对于32MBytes以上(不含32MBytes)的SPI存储需求,可使用SPI Nand Flash,另外SPI Nand Flash不支持XIP技术,如需此技术则不可使用SPI Nand Flash。

启动设置

注意:若未特殊说明,此说明仅适用于截至编辑时的u-boot,不包括旧版u-boot。

启动设置的Kconfig菜单在> Boot options ,实际主要通过环境变量影响启动行为(若使用外部文件作为默认环境变量可能使设置无效)。

所有的启动过程其实都是使用u-boot脚本,将对应的脚本内容写入对应的环境变量即可启动,常用的启动相关环境变量如下:

环境变量 Kconfig项 说明
bootargs CONFIG_BOOTARGS Linux内核命令行参数,但现在更加常用的是使用设备树dts传参。
bootcmd CONFIG_BOOTCOMMAND 启动脚本,当使用自动启动时自动执行此环境变量中的命令。
preboot CONFIG_PREBOOT 在自动启动前运行的脚本,主要推荐用途:在bootcmd中修改此值实现在下一次启动时执行不同的行为(比如重启进入其他模式)。

个人认为的用途:提前初始化一些硬件,这样bootcmd不变,只改变preboot。

默认情况下,尝试启动失败(而非执行应用失败)会进入shell,这样其实可以测试一些命令及脚本(使用run命令调用)。

传统启动过程

传统启动过程在此wiki中指直接使用u-boot传统方式(写脚本到环境变量加载数据然后启动)启动的过程 ,通常这不是默认的,且基本上都是针对各个具体硬件定制的。

具体指将数据加载在内存中后采用以下命令启动的过程:

  • bootm:启动应用。可启动各种u-boot支持的镜像,一般用于启动Linux uImage.
  • bootz:启动Linux zImage。

传统启动时环境变量bootcmd是自定义的,也不用考虑内存驻留问题,当启动到内核时将控制权交给内核,因此可将几乎所有内存给内核使用,某些特殊启动模式下需要保留一部分内存。

通用发行版(distro)启动过程

发行版启动过程(参考见源代码doc/develop/distro.rst)主要提供一个通用的启动Linux发行版的方式,通常这是默认的值之一,这无需对u-boot进行任何定制。

实现时环境变量bootcmd=run distro_bootcmd

发行版启动主要有以下方式:

  • U-Boot's "syslinux" (disk)
  • "pxe boot" (network)

简单来说就是分磁盘启动与网络pxe启动,网络pxe启动在嵌入式上的应用较少因此不予赘述,磁盘启动主要有以下条件:

  • 磁盘采用通用分区表(如MBR、GPT等,具体可通过Kconfig配置)。
  • 分区采用通用文件系统(如ext2/3/4 、FAT等,具体可通过Kconfig配置)。
  • 分区上存在菜单文件 extlinux.conf(具体可为/extlinux/extlinux.conf或者/boot/extlinux/extlinux.conf等)或者u-boot脚本文件(具体可为/boot/boot.scr等,具体可通过Kconfig配置)。
  • 厂商提供了必要的环境变量以提供内存布局, 具体如下:
环境变量 含义
fdt_addr 设备树dtb地址(在ROM中),仅当可以直接通过地址访问的系统需要,其余系统不能使用此环境变量。
fdt_addr_r 设备树dtb内存地址。
fdtoverlay_addr_r 设备树dtb overlay内存地址。
fdtfile 设备树dtb设备树文件名,有些情况下会自动设置此值。
ramdisk_addr_r ramdisk内存地址,推荐放在高地址。
kernel_addr_r 内核内存地址。
kernel_comp_addr_r 内核压缩文件内存地址,若使用booti命令则需要此值。
kernel_comp_size 内核压缩文件大小,若使用booti命令则需要此值。
scriptaddr U-Boot脚本加载内存地址。若启用了u-boot脚本,则在此处执行脚本。
pxefile_addr_r extlinux.conf菜单加载内存地址。

实际菜单文件 extlinux.conf写法同pxe启动时菜单写法(参考见源代码doc/README.pxe),菜单示例如下:

One example extlinux.conf generated by the Fedora installer is::

    # extlinux.conf generated by anaconda

    ui menu.c32

    menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options.
    menu title Fedora Boot Options.
    menu hidden

    timeout 50
    #totaltimeout 9000

    default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)

    label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide)
        kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl
        append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
        fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl
        initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img

    label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
        kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
        append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
        fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
        initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img

    label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc)
        kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc
        initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img
        append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8
        fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae


One example of hand-crafted extlinux.conf::

   menu title Select kernel
   timeout 100

   label Arch with uart devicetree overlay
       kernel /arch/Image.gz
       initrd /arch/initramfs-linux.img
       fdt /dtbs/arch/board.dtb
       fdtoverlays /dtbs/arch/overlay/uart0-gpio0-1.dtbo
       append console=ttyS0,115200 console=tty1 rw root=UUID=fc0d0284-ca84-4194-bf8a-4b9da8d66908

   label Arch with uart devicetree overlay but with Boot Loader Specification keys
       kernel /arch/Image.gz
       initrd /arch/initramfs-linux.img
       devicetree /dtbs/arch/board.dtb
       devicetree-overlay /dtbs/arch/overlay/uart0-gpio0-1.dtbo
       append console=ttyS0,115200 console=tty1 rw root=UUID=fc0d0284-ca84-4194-bf8a-4b9da8d66908

Another hand-crafted network boot configuration file is::

    TIMEOUT 100

    MENU TITLE TFTP boot options

    LABEL jetson-tk1-emmc
            MENU LABEL ../zImage root on Jetson TK1 eMMC
            LINUX ../zImage
            FDTDIR ../
            APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b

    LABEL venice2-emmc
            MENU LABEL ../zImage root on Venice2 eMMC
            LINUX ../zImage
            FDTDIR ../
            APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f

    LABEL sdcard
            MENU LABEL ../zImage, root on 2GB sdcard
            LINUX ../zImage
            FDTDIR ../
            APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7

    LABEL fedora-installer-fk
            MENU LABEL Fedora installer w/ Fedora kernel
            LINUX fedora-installer/vmlinuz
            INITRD fedora-installer/initrd.img.orig
            FDTDIR fedora-installer/dtb
            APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M

U-Boot标准启动(U-Boot Standard Boot)过程

U-Boot标准启动过程(参考见源代码doc/develop/bootstd.rst)更像是PC上的启动过程,即依次尝试在各个启动设备上使用各种启动方法(包括但不限于 通用发行版(distro)启动过程,如EFI启动管理器或者VBE启动管理器 ),主要提供一个通用的启动方式,通常这是默认的值之一。

此过程需要厂商提供必要的环境变量以提供内存布局,具体如下:

环境变量 含义
fdt_addr 设备树dtb地址(在ROM中),仅当可以直接通过地址访问的系统需要,其余系统不能使用此环境变量。
fdt_addr_r 设备树dtb内存地址。
fdtoverlay_addr_r 设备树dtb overlay内存地址。
fdtfile 设备树dtb设备树文件名,有些情况下会自动设置此值。
ramdisk_addr_r ramdisk内存地址,推荐放在高地址。
kernel_addr_r 内核内存地址。
kernel_comp_addr_r 内核压缩文件内存地址,若使用booti命令则需要此值。
kernel_comp_size 内核压缩文件大小,若使用booti命令则需要此值。
scriptaddr 脚本(菜单)加载内存地址。若启用了u-boot脚本,则在此处执行脚本。
pxefile_addr_r PXE文件加载内存地址。
script_offset_f U-Boot脚本在Flash上的偏移,用于加载SPI Flash上的启动脚本。
script_size_f U-Boot脚本的大小,配合script_offset_f使用。
devtype 启动设备类型。由bootmeth使用。
devnum 启动设备编号。由bootmeth使用。
distro_bootpart 启动分区编号。由bootmeth使用。
prefix 脚本目录。由bootmeth使用。
mmc_bootdev 启动设备编号(仅限全志SOC)。由bootmeth使用。

U-Boot标准启动过程主要使用以下命令:

  • bootdev
  • bootmeth
  • bootflow

在u-boot脚本或者shell中可使用以下命令启动 U-Boot标准启动过程:

#启用CONFIG_BOOTSTD_FULL时使用
bootflow scan -lb
#未启用CONFIG_BOOTSTD_FULL时使用
bootflow scan

将环境变量bootcmd设置为bootflow scan(未启用CONFIG_BOOTSTD_FULL)或者bootflow scan -lb(启用CONFIG_BOOTSTD_FULL)即可启用U-Boot标准启动过程。

官方资料

网站:https://www.denx.de/project/u-boot/

相关资料