Bootloader -- U-Boot 介绍
- 1 介绍
- 1.1 概述
- 1.2 知名 Bootloader
- LILO (Linux Loader)
- GRUB (GNU GRand Unified Bootloader)
- Loadlin
- ROLO (Rockbox Loader)
- Etherboot
- LinuxBIOS (现在叫 coreboot)
- BLOB
- U-Boot
- RedBoot
- 1.3 BootLoader 和 Monitor 区别
- 1.4 U-Boot 的源码结构
- 1.5 U-Boot 的主要版本
- 1.6 U-Boot 的作用和功能
- 2 U-Boot 命令与启动
- 启动
- 命令
- 全部命令
- 常用命令
- mmc 命令
- 文件系统类型操作命令
- FAT 格式文件系统操作
- ext4 格式文件系统操作
- uboot 启动内核过程
- 嵌入式之家画的流程图
- uboot 环境参数介绍
- 3 U-Boot 编译
- 3.1 系统
- 3.2 安装依赖和编译工具
- 3.3 获取 U-Boot
- 3.4 uboot 工程结构 & 变量 & 子功能
- 3.4.1 uboot 工程结构
- 3.4.2 uboot 变量
- 3.4.3 uboot 子功能
- 3.5 uboot 编译
- 来自 lzd626 的图解
- 赵建辉理解的 u-boot.imx 目标依赖关系图
- 野火 ebf_v2020_10_imx 分支
- 3.6 编译产物分析
- 4 U-Boot 烧录
- 4.1 Mfgtool 烧写 Uboot 到内部存储(EMMC/NAND 通用)
- 介绍
- 烧录步骤分析
- 4.2 Uboot 烧写到 SD 卡镜像(常用于做 uboot 测试)
- 5 U-Boot 移植
- 6 U-Boot 控制 GPIO & 定制自己的 Uboot 单板
- 6.1 U-Boot 控制 GPIO
- 6.2 U-Boot 定制自己的 Uboot 单板
- 7 电脑 与 嵌入式设备 系统启动区别
- 知识点
- 1 BIOS、UEFI、MBR、GPT、GRUB 区别联系
- 基本输入输出系统【BIOS、UEFI】
- 硬盘分区初始化格式【MBR、GPT】
- bootloader【GRUB】
- 如下图所示为GRUB加载引导流程
- 参考
1 介绍
1.1 概述
Bootloader,引导加载程序,是一种负责启动计算机的计算机程序。
U-Boot是Das U-Boot的简写,是一种开源引导加载程序,用于嵌入式设备执行各种低级硬件初始化任务并引导设备的操作系统内核。它适用于多种计算机架构,包括M68000、ARM、Blackfin、MicroBlaze、IBM S360、My66、MOS 6502、ARM64、MIPS、Nios、SuperH、PPC、RISC-V和x86。
U-Boot 一开始是由一个德国大神Magnus Damm(马格努斯 达姆)发起的一个项目。
U-Boot 既是第一阶段的引导加载程序,也是第二阶段的引导加载程序。它由系统的 ROM(例如 ARM CPU 的片上 ROM)从受支持的启动设备(例如 SD 卡、SATA 驱动器、NOR 闪存(例如使用SPI或I²C)或 NAND 闪存)加载。如果有大小限制,U-Boot 可能会分为两个阶段:平台将加载一个小型 SPL(辅助程序加载器),它是 U-Boot 的精简版,SPL 将执行一些初始硬件配置(例如使用 CPU 缓存作为 RAM 进行DRAM初始化)并加载更大、功能齐全的 U-Boot 版本。无论是否使用 SPL,U-Boot 都会执行第一阶段(例如配置内存控制器和 SDRAM)和第二阶段引导(执行多个步骤从必须配置的各种设备加载现代操作系统、显示菜单供用户交互和控制引导过程等)。
U-Boot 的主要作用是用来启动操作系统内核,它分为两个阶段,即 boot + loader,boot 阶段启动系统,初始化硬件设备,建立内存空间映射图,将系统的软硬件带到一个合适的状态,loader 阶段将操作系统内核文件加载至内存,之后跳转到内核所在地址运行。
U-Boot 有众多命令,如信息查询,环境变量操作,内存操作,网络操作,mmc操作,文件系统操作,nand操作,boot操作,reset, go(到指定地址执行程序),run(运行环境变量中的命令),metest(内存测试)。
1.2 知名 Bootloader
Bootloader,引导加载程序,是一种负责启动计算机的计算机程序。
LILO (Linux Loader)
一度很火,2009年起被 GRUB 替代,2015年停止进一步开发;
GRUB (GNU GRand Unified Bootloader)
GRUB 是最为常见的Linux Bootloader之一。它支持多种操作系统,包括Linux、Windows、Mac OS 等。GRUB具有强大的功能和灵活的配置选项,因此被广泛使用。GRUB可以通过配置文件进行定制,例如添加启动项、设置启动顺序等。
GRUB 最初是为 GNU Hurd 操作系统设计的,目的是提供一个统一的引导程序,以替代当时众多不兼容的PC启动方式。
发展历程:
- 1995年:GRUB由Erich Boleyn开发,最初是为了启动GNU Hurd操作系统。
- 2002年:Yoshinori K. Okuji开始开发GRUB 2,旨在重写GRUB的核心,使其更加模块化、安全和强大。
- 2005年:GRUB Legacy 的最后一个版本0.97发布,之后的开发重点转移到 GRUB 2上。
- 2007年:一些GNU/Linux发行版开始使用GRUB 2,到2009年底,多个主要发行版默认安装GRUB 2。
Loadlin
运行在 16 位的实模式DOS (包括Windows 95、Windows 98和Windows Me启动盘的 MS-DOS 模式)下的Linux 启动加载程序。它允许 Linux 系统加载和替换正在运行的 DOS,而无需更改现有的 DOS 系统文件。
ROLO (Rockbox Loader)
Rockbox 是一种免费的数字音乐播放器替代固件。它可以在多种播放器上运行。适用于 Archos Jukebox 5000、6000、Studio、Recorder、Recorder V2 和 FM Recorder MP3 播放器。
Etherboot
Etherboot 是一个免费软件包,用于制作引导 ROM,以便使用 Internet 协议(即 bootp/DHCP 和 tftp)通过网络在 x86 PC 上引导 GNU/Linux 和其他操作系统。Etherboot 通常用于无盘引导 PC,这对于集群、路由器、远程服务器和在磁盘不友好的环境中工作的机器特别有用。
LinuxBIOS (现在叫 coreboot)
coreboot,以前称为LinuxBIOS,是一个软件项目,旨在用轻量级固件取代大多数计算机中的专有固件(BIOS或UEFI),轻量级固件旨在仅执行加载和运行现代32 位或64 位 操作系统所需的最少任务。
由于 coreboot 会初始化裸硬件,因此必须将其移植到其支持的每个芯片组和主板上。因此,coreboot 仅适用于有限数量的硬件平台和主板型号。
BLOB
Blob是一个为基于StrongARM平台设计的简单引导加载程序,由Jan-Derk Bakker和Erik Mouw编写,并采用GPL许可证。
Blob的最后版本是blob-2.0.5。
U-Boot
U-Boot是Das U-Boot的简写,是一种开源引导加载程序,用于嵌入式设备执行各种低级硬件初始化任务并引导设备的操作系统内核。它适用于多种计算机架构,包括M68000、ARM、Blackfin、MicroBlaze、IBM S360、My66、MOS 6502、ARM64、MIPS、Nios、SuperH、PPC、RISC-V和x86。
U-Boot 一开始是由一个德国大神Magnus Damm(马格努斯 达姆)发起的一个项目。
RedBoot
RedBoot(Red Hat 嵌入式调试和引导固件的缩写)是一个开源应用程序,它使用eCos实时操作系统硬件抽象层为嵌入式系统提供引导固件。
1.3 BootLoader 和 Monitor 区别
BootLoader,严格来说只是引导设备并且执行主程序的固件;
Monitor,提供了更多的命令行接口,可以进行调试、读写内存、烧写Flash、配置环境变量等。
Monitor在嵌入式系统开发过程中可以提供很好的调试功能,开发完成以后,就完全设置成了一个BootLoader。所以,习惯上大家把它们统称为BootLoader。
1.4 U-Boot 的源码结构
子目录 | 描述 |
---|---|
board | 开发板相关 |
common | 通用的函数 |
cpu | cpu相关,对应不同的架构的cpu,子目录进一步细分了 |
disk | 磁盘驱动和相关的操作代码 |
doc | 开发文档,还有使用文档 |
lib_generic | 通用库函数 |
lib_xxx | xxx架构下的通用文件,支持平台设备树的库,基于open firmware结构,一般不会用到 |
libfdt | 支持平台设备树的库,基于open firmware结构,一般不会用到 |
driver | 各类设备的驱动,根据平台配置会编译不同的驱动 |
fs | 文件系统 |
include | 头文件和开发板的配置文件 |
net | 网络子系统 |
nand_spl | 支持从nand flash启动,但支持的cpu的种类也不是很多 |
onenand_ipl | 支持从onenand flash启动的代码,三星公司开发的结合了nand和nor技术的flash |
post | 上电自检程序 |
tools | 制作S-Record(motorola 制定的一种烧写格式,很简单), u-boot镜像等的工具 |
example | 一些可以在u-boot上运行的小示例程序 |
api | 些扩展应用的独立的api |
api_example | api的示例程序 |
1.5 U-Boot 的主要版本
类别 | 描述 |
---|---|
uboot 官方的uboot 代码 | 由uboot 官方维护开发的uboot 版本,版本更新快,基本包含所有常用的芯片。 |
半导体厂商的uboot代码 | 半导体厂商维护的一个uboot,专门针对自家的芯片,在对自家芯片支持上要比uboot官方的好。 |
开发板厂商的 uboot 代码 | 开发板厂商在半导体厂商提供的uboot基础上加入了对自家开发板的支持。 |
1.6 U-Boot 的作用和功能
2 U-Boot 命令与启动
启动
在开发板上电 uboot 启动 kernel 之前按下键盘的空格或回车键, 进入 uboot 的命令模式。如下所示:
可以看出 uboot 打印出了板子的一些基本信息,包括 CPU、内存等信息。
uboot 2020.10-g4f79a1a2 (Feb 20 2021 - 11:25:18 +0800)
CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 49C
Reset cause: WDOG
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In: serial
Out: serial
Err: serial
Net: eth1: ethernet@20b4000 [PRIME]Could not get PHY for FEC0: addr 2
Hit any key to stop autoboot: 0
=>
U-Boot 2016.03-00001-gb0f94c6 (Apr 22 2020 - 09:29:24 +0800)
CPU: Freescale i.MX6Q rev1.5 996 MHz (running at 792 MHz)
CPU: Automotive temperature grade (-40C to 125C) at 24C
Reset cause: POR
Board: MX6-SabreSD
I2C: ready
DRAM: 1 GiB
PMIC: PFUZE100 ID=0x10
MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Display: CLAA-WVGA (800x480)
reading logo.bmp
1152054 bytes read in 47 ms (23.4 MiB/s)
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc2(part 0) is current device
Net: FEC [PRIME]
Normal Boot
Hit any key to stop autoboot: 0
----------------------Main Menu-----------------------
0 -- exit to uboot shell
1 -- set mxcfb0 parameters
2 -- set mxcfb1 parameters
3 -- set ldb mode
4 -- select boot mode
------------------------------------------------------
0 -- exit to uboot shell
选择此选项将退出当前的菜单或配置界面,返回到U-Boot的命令行界面(shell)。
1 -- set mxcfb0 parameters
mxcfb 通常是用于i.MX系列处理器上帧缓冲管理的驱动程序。选择此选项可能允许您配置与mxcfb0(可能是第一个显示接口)相关的参数,如分辨率、颜色深度等。
2 -- set mxcfb1 parameters
类似于mxcfb0,但此选项是为mxcfb1(可能是第二个显示接口)配置参数。
3 -- set ldb mode
LDB (LVDS Display Bridge) 是一种用于连接LVDS(低电压差分信号)显示器的接口。此选项可能允许您配置与LDB相关的模式或参数。
4 -- select boot mode
选择此选项可能允许您从多种不同的启动模式中选择一个,如从SD卡、NAND闪存、网络或其他存储设备启动。
命令
全部命令
关于 uboot 命令的使用可参考 uboot 官方链接:
https://docs.u-boot.org/en/latest/ -【shell-commands】
可输入 help 或 ? 可查看 uboot 支持的命令列表:
Normal Boot
Hit any key to stop autoboot: 0
----------------------Main Menu-----------------------
0 -- exit to uboot shell
1 -- set mxcfb0 parameters
2 -- set mxcfb1 parameters
3 -- set ldb mode
4 -- select boot mode
------------------------------------------------------
:0
=> help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
bmode - sd2|sd3|emmc|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset]
bmp - manipulate BMP image data
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
bootz - boot Linux zImage image from memory
clocks - display clocks
clrlogo - fill the boot logo area with black
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
cpu - Multiprocessor CPU boot manipulation and release
crc32 - checksum calculation
dcache - enable or disable data cache
dfu - Device Firmware Upgrade
dhcp - boot image via network using DHCP/TFTP protocol
dm - Driver model low level access
echo - echo args to console
editenv - edit environment variable
env - environment handling commands
erase - erase FLASH memory
exit - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls - list files in a directory (default /)
ext4size- determine a file's size
ext4write- create a file in the root directory
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fatsize - determine a file's size
fdt - flattened device tree utility commands
flinfo - print FLASH memory information
fstype - Look up a filesystem type
fuse - Fuse sub-system
go - start application at address 'addr'
gpio - query and control gpio pins
help - print command description/usage
i2c - I2C sub-system
icache - enable or disable instruction cache
iminfo - print header information for application image
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
load - load binary file from a filesystem
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls - list files in a directory (default /)
md - memory display
mdio - MDIO utility commands
mii - MII utility commands
mm - memory modify (auto-incrementing address)
mmc - MMC sub system
mmcinfo - display MMC info
mtest - simple RAM read/write test
mw - memory write (fill)
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
pmic - PMIC
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
run - run commands in an environment variable
save - save file to a filesystem
saveenv - save environment variables to persistent storage
scr_menu- menu - display a menu, to select the items to do something
setenv - set environment variables
setexpr - set environment variable as the result of eval expression
sf - SPI flash sub-system
showvar - print local hushshell variables
size - determine a file's size
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true - do nothing, successfully
ums - Use the UMS [USB Mass Storage]
usb - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version
=>
可看到 uboot 支持很多的命令,功能十分强大,与 linux 类似,在执行某条 uboot 命令时,可使用 tab 自动补全命令,在没有命令名冲突的情况下可以使用命令的前几个字母作为命令的输入,例如想要执行 reset 命令,输入 res 或 re 即可。
当需要具体使用哪个命令时,可使用 “help 命令”或 “? 命令”的方式查看具体命令的使用说
明。以 “help printenv”为例,
=> help printenv
printenv - print environment variables
Usage:
printenv [-a]
- print [all] values of all environment variables
printenv name ...
- print value of environment variable 'name'
=>
可以看到 printenv 命令的说明以及使用方法。
常用命令
命令 | 说明 | 举例 |
---|---|---|
help | 列出当前 uboot 所有支持的命令 | |
help[命令] | 查看指定命令的帮助 | help printenv |
reset | 重启 uboot | |
printenv | 打印所有环境参数的值 | |
printenv[环境参数名] | 查看指定的环境参数值 | printenv bootdelay |
setenv | 设置/修改/删除环境参数的值 | setenv bootdelay 3 |
saveenv | 保存环境参数 | |
ping | 检测网络是否连通 | ping 192.168.0.1 |
md | 查看内存地址上的值 | md.b 0x80000000 10 |
mw | 用于修改内存地址上的值 | mw.b 0x80000000 ff 10 |
echo | 打印信息,与 linux下的 echo 类似 | |
run | 在执行某条环境参数命令 | run bootcmd,执行 bootcmd |
bootz | 在内存中引导内核启动 | |
ls | 查看文件系统中目录下的文件 | |
load | 从文件系统中加载二进制文件到内存 |
mmc 命令
mmc 命令能够对如 sd 卡以及 emmc 类的存储介质进行操作。
命令 | 说明 |
---|---|
mmc list | 查看板子上 mmc 设备 |
mmc dev | 查看/切换当前默认 mmc 设备 |
mmc info | 查看当前 mmc 设备信息 |
mmc part | 查看当前 mmc 设备分区 |
mmc read | 读取当前 mmc 设备数据 |
mmc write | 写入当前 mmc 设备数据 |
mmc erase | 擦除当前 mmc 设备数据 |
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
=> mmc info
Device: FSL_SDHC
Manufacturer ID: d6
OEM: 103
Name: 88A39
Tran Speed: 52000000
Rd Block Len: 512
MMC version 4.0
High Capacity: Yes
Capacity: 7.3 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
=> mmc part
Partition Map for MMC device 2 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 20480 184320 4d6f4290-01 0c
2 204800 5242880 4d6f4290-02 83
3 5447680 4194304 4d6f4290-03 83
4 9641984 5627904 4d6f4290-04 85 Extd
5 9658368 2097152 4d6f4290-05 83
6 11771904 2097152 4d6f4290-06 83
7 13885440 1384448 4d6f4290-07 83
=> mmc dev
switch to partitions #0, OK
mmc2(part 0) is current device
=>
文件系统类型操作命令
uboot 能够对 ext2/3/4 以及 fat 文件系统设备进行访问,可使用 fstype 命令判断存储介质分区使用的是什么类型的文件系统。以 mmc 介质为例,判断 sd 的两个分区的文件系统类型。
=> fstype help
fstype - Look up a filesystem type
Usage:
fstype <interface> <dev>:<part>
- print filesystem type
fstype <interface> <dev>:<part> <varname>
- set environment variable to filesystem type
dev | part |
---|---|
设备号 | 分区号 |
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
=> mmc part
Partition Map for MMC device 2 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 20480 184320 4d6f4290-01 0c
2 204800 5242880 4d6f4290-02 83
3 5447680 4194304 4d6f4290-03 83
4 9641984 5627904 4d6f4290-04 85 Extd
5 9658368 2097152 4d6f4290-05 83
6 11771904 2097152 4d6f4290-06 83
7 13885440 1384448 4d6f4290-07 83
=> fstype help
fstype - Look up a filesystem type
Usage:
fstype <interface> <dev>:<part>
- print filesystem type
fstype <interface> <dev>:<part> <varname>
- set environment variable to filesystem type
| <dev> | <part> |
| 设备号 | 分区号 |
=> fstype mmc 2:1
fat
=> fstype mmc 2:2
ext4
=> fstype mmc 2:3
ext4
=> fstype mmc 2:4
** Invalid partition 4 **
=> fstype mmc 2:5
ext4
=> fstype mmc 2:6
ext4
=> fstype mmc 2:7
ext4
=>
FAT 格式文件系统操作
uboot 提供了能够对于 FAT 格式文件系统操作的各个指令。
命令 | 说明 |
---|---|
fatinfo | 打印关于文件系统的信息 |
fatls | 查看存储设备的 fat 分区里的内容 |
fatload | 从 fat 分区里读出文件到指定的内存地址 |
fatwrite | 把内存上的数据存储到 fat 分区的一个文件里 |
fatmkdir | 创建文件夹 |
fatrm | 删除文件 |
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
=> fatinfo mmc 2:1
Interface: MMC
Device 2: Vendor: Man 0000d6 Snr 2ff7b3a0 Rev: 1.1 Prod: 88A398
Type: Removable Hard Disk
Capacity: 7456.0 MB = 7.2 GB (15269888 x 512)
Filesystem: FAT16 "NO NAME "
=> fatls mmc 2:1
7334040 zimage
7332312 zimage.orig
1152054 logo.bmp
53092 imx6q-c-sabresd.dtb
52758 imx6q-c-sabresd.dtb.orig
5 file(s), 0 dir(s)
=>
ext4 格式文件系统操作
命令 | 说明 |
---|---|
ext4ls | 查看存储设备的 ext4 分区里的内容 |
ext4load | 从 ext4 分区里读出文件到指定的内存地址 |
ext4write | 把内存上的数据存储到 ext4 分区的一个文件里 |
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
=> mmc part
Partition Map for MMC device 2 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 20480 184320 4d6f4290-01 0c
2 204800 5242880 4d6f4290-02 83
3 5447680 4194304 4d6f4290-03 83
4 9641984 5627904 4d6f4290-04 85 Extd
5 9658368 2097152 4d6f4290-05 83
6 11771904 2097152 4d6f4290-06 83
7 13885440 1384448 4d6f4290-07 83
=> fatls mmc 2:1 【/boot/】
7334040 zimage
7332312 zimage.orig
1152054 logo.bmp
53092 imx6q-c-sabresd.dtb
52758 imx6q-c-sabresd.dtb.orig
5 file(s), 0 dir(s)
=> ext4ls mmc 2:2 【/】
<DIR> 4096 .
<DIR> 4096 ..
<DIR> 16384 lost+found
<DIR> 4096 run
<DIR> 4096 var
<DIR> 4096 mnt
<DIR> 4096 bin
<DIR> 4096 tmp
<DIR> 4096 root
0 .dockerenv
<DIR> 4096 sys
<DIR> 4096 sbin
<DIR> 4096 etc
<DIR> 4096 opt
<DIR> 4096 media
<DIR> 4096 srv
<DIR> 4096 home
<DIR> 4096 usr
<DIR> 4096 lib
<DIR> 4096 boot
<DIR> 4096 dev
<DIR> 4096 proc
=> ext4ls mmc 2:3 【/opt/sen/】
=> ext4ls mmc 2:2 /opt
<DIR> 4096 .
<DIR> 4096 ..
<DIR> 4096 log
<DIR> 4096 sen
<DIR> 4096 test
uboot 启动内核过程
bootcmd 与 bootargs 可以说是 uboot 最重要的两个环境参数,uboot 执行完毕之后,如果没有按下回车,则会自动执行 bootcmd 命环境参数里的内容,而 bootargs 则是传递给内核的启动参数。
使用 printenv bootcmd 可查看 bootcmd 的内容。
提示: 若从 uboot 中直接使用 printenv 查看 boot 的内容会显得格式很乱,推荐在 uboot 源码 include/configs/mx6ullfire.h 中查看。
#if defined(CONFIG_SYS_BOOT_NAND)
#define CONFIG_EXTRA_ENV_SETTINGS \
"panel=TFT50AB\0" \
"splashimage=0x82000000\0" \
"fdt_addr=0x83000000\0" \
"fdt_high=0xffffffff\0" \
"console=ttymxc0\0" \
"console=ttymxc0\0" \
"loaduEnv=" \
"load ramblock 0:1 ${loadaddr} /uEnv.txt;\0" \
"importbootenv=echo Importing environment from ${devtype} ...; " \
"env import -t ${loadaddr} ${filesize}\0" \
"bootargs=console=ttymxc0 bootargs=console=ttymxc0,115200 ubi.mtd=1 " \
"root=ubi0:rootfs rw rootfstype=ubifs " \
"mtdparts=gpmi-nand:8m(uboot),-(rootfs) ${cmdline} ${flashtype}\0"\
"bootcmd=mmc check;ubi part rootfs;ubifsmount ubi0;"\
"ubifsload ${ramblock_addr} /lib/firmware/fatboot.img;"\
"echo loading /uEnv.txt ...; "\
"if run loaduEnv; then " \
"run importbootenv;" \
"if test ${second_flash} = emmc; then " \
"setenv dtb ${mmc_dtb};" \
"setenv storage_media init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh;" \
"else " \
"setenv dtb ${nand_dtb};" \
"setenv storage_media init=/opt/scripts/tools/Nand/init-Nand-flasher-v1.sh;" \
"fi; " \
"if test -n ${flash_firmware}; then " \
"echo setting flash firmware...;" \
"setenv flashtype ${storage_media};" \
"fi;" \
"echo loading vmlinuz-${uname_r} ...; "\
"load ramblock 0:1 0x80800000 /kernel/vmlinuz-${uname_r};"\
"echo loading ${dtb} ...; "\
"ubifsload 0x83000000 /usr/lib/linux-image-${uname_r}/${dtb};"\
"dtfile 0x83000000 0x87000000 /uEnv.txt ${loadaddr};" \
"load ramblock 0:1 0x88000000 /kernel/initrd.img-${uname_r};"\
"echo debug: [${bootargs}] ... ;" \
"echo debug: [bootz] ... ;" \
"bootz 0x80800000 0x88000000:${filesize} 0x83000000;" \
"fi;\0"
#else
#define CONFIG_EXTRA_ENV_SETTINGS \
"script=boot.scr\0" \
"image=zImage\0" \
"console=ttymxc0\0" \
"fdt_high=0xffffffff\0" \
"initrd_high=0xffffffff\0" \
"fdt_file=undefined\0" \
"fdt_addr=0x83000000\0" \
"boot_fdt=try\0" \
"ip_dyn=yes\0" \
"videomode=video=ctfb:x:480,y:272,depth:24,pclk:108695,le:8,ri:4,up:2,lo:4,hs:41,vs:10,sync:0,vmode:0\0" \
"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
"mmcautodetect=yes\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} " \
"root=${mmcroot}\0" \
"loadbootscript=" \
"load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
"loaduEnv=" \
"load ${devtype} ${bootpart} ${loadaddr} /uEnv.txt;\0" \
"importbootenv=echo Importing environment from ${devtype} ...; " \
"env import -t ${loadaddr} ${filesize}\0" \
"bootscript=echo Running bootscript from mmc ...; " \
"source\0" \
"loadimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image};\0" \
"loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file};\0" \
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
"if run loadfdt; then " \
"bootz ${loadaddr} - ${fdt_addr}; " \
"else " \
"if test ${boot_fdt} = try; then " \
"bootz; " \
"else " \
"echo WARN: Cannot load the DT; " \
"fi; " \
"fi; " \
"else " \
"bootz; " \
"fi;\0" \
"findfdt="\
"if test $fdt_file = undefined; then " \
"if test $board_name = ULZ-EVK && test $board_rev = 14X14; then " \
"setenv fdt_file imx6ulz-14x14-evk.dtb; fi; " \
"if test $board_name = EVK && test $board_rev = 14X14; then " \
"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
"if test $fdt_file = undefined; then " \
"echo WARNING: Could not determine dtb to use; " \
"fi; " \
"fi;\0" \
"netargs=setenv bootargs console=${console},${baudrate} " \
"root=/dev/nfs " \
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
"netboot=echo Booting from net ...; " \
"run netargs; " \
"if test ${ip_dyn} = yes; then " \
"setenv get_cmd dhcp; " \
"else " \
"setenv get_cmd tftp; " \
"fi; " \
"${get_cmd} ${image}; " \
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
"bootz ${loadaddr} - ${fdt_addr}; " \
"else " \
"if test ${boot_fdt} = try; then " \
"bootz; " \
"else " \
"echo WARN: Cannot load the DT; " \
"fi; " \
"fi; " \
"else " \
"bootz; " \
"fi;\0" \
"args_mmc_old=setenv bootargs console=ttymxc0 " \
"root=/dev/mmcblk${mmcdev}p2 rw " \
"rootfstype=ext4 " \
"rootwait ${cmdline} ${flashtype}\0" \
"boot=mmc check;${devtype} dev ${mmcdev};mmc rescan; " \
"echo loading [${devtype} ${bootpart}] /uEnv.txt ...; "\
"if run loaduEnv; then " \
"run importbootenv;" \
"if test ${second_flash} = emmc; then " \
"setenv dtb ${mmc_dtb};" \
"setenv storage_media init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh;" \
"else " \
"setenv dtb ${nand_dtb};" \
"setenv storage_media init=/opt/scripts/tools/Nand/init-Nand-flasher-v1.sh;" \
"fi; " \
"if test -n ${flash_firmware}; then " \
"echo setting flash firmware...;" \
"setenv flashtype ${storage_media};" \
"fi;" \
"run args_mmc_old;" \
"echo loading vmlinuz-${uname_r} ...; "\
"load ${devtype} ${bootpart} 0x80800000 /kernel/vmlinuz-${uname_r};"\
"echo loading ${dtb} ...; "\
"load ${devtype} ${rootfpart} 0x83000000 /usr/lib/linux-image-${uname_r}/${dtb};"\
"dtfile 0x83000000 0x87000000 /uEnv.txt ${loadaddr};" \
"load ${devtype} ${bootpart} 0x88000000 /kernel/initrd.img-${uname_r};"\
"echo debug: [${bootargs}] ... ;" \
"echo debug: [bootz] ... ;" \
"bootz 0x80800000 0x88000000:${filesize} 0x83000000;" \
"fi;\0" \
BOOTENV
/*
#define CONFIG_BOOTCOMMAND \
"run findfdt;" \
"mmc dev ${mmcdev};" \
"mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \
"run bootscript; " \
"else " \
"if run loadimage; then " \
"run mmcboot; " \
"else run netboot; " \
"fi; " \
"fi; " \
"else run netboot; fi"
*/
#endif
*****************************完整环境参数*****************************
=> printenv
baudrate=115200
board_name=SABRESD
board_rev=MX6Q
boot_fdt=try
bootcmd=run findfdt;mmc dev ${mmcdev};if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
dfu_alt_info=spl raw 0x400
dfu_alt_info_img=u-boot raw 0x10000
dfu_alt_info_spl=spl raw 0x400
dfuspi=dfu 0 sf 0:0:10000000:0
emmcdev=2
epdc_waveform=epdc_splash.bin
ethact=FEC
ethaddr=22:C1:F4:A2:2A:B0
ethprime=FEC
fdt_addr=0x18000000
fdt_file=undefined
fdt_high=0xffffffff
fec_mac=22:C1:F4:A2:2A:B0
fileaddr=20000000
filesize=119436
findfdt=if test $fdt_file = undefined; then if test $board_name = SABREAUTO && test $board_rev = MX6QP; then setenv fdt_file imx6qp-sabreauto.dtb; fi; if test $board_name = SABREAUTO && test $board_rev = MX6Q; then setenv fdt_file imx6q-sabreauto.dtb; fi; if test $board_name = SABREAUTO && test $board_rev = MX6DL; then setenv fdt_file imx6dl-sabreauto.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6QP; then setenv fdt_file imx6qp-sabresd.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6Q; then setenv fdt_file imx6q-c-sabresd.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6DL; then setenv fdt_file imx6dl-c-sabresd.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
image=zImage
initrd_addr=0x12C00000
initrd_high=0xffffffff
ip_dyn=yes
ldbmode=ldb=sin0
loadaddr=0x12000000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
mfgtool_args=setenv bootargs console=ttymxc0,115200 rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" enable_wait_mode=off
mmcargs=setenv bootargs console=${console},${baudrate} ${mxcfb0} ${mxcfb1} ${ldbmode} ${smp} root=${mmcroot} fec.macaddr=${fec_mac}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcdev=2
mmcpart=1
mmcroot=/dev/mmcblk3p2 rootwait rw
mxcfb0=video=mxcfb0:dev=mipi_dsi,TRULY-EK79007-WVGA,if=RGB24,bpp=16
mxcfb1=video=mxcfb1:dev=hdmi,1920x1080M@60,if=RGB24,bpp=16
netargs=setenv bootargs console=${console},${baudrate} ${smp} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
panel=TRULY-EK79007-WVGA
script=boot.scr
splashpos=m,m
update_emmc_firmware=if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; if ${get_cmd} ${update_sd_firmware_filename}; then if mmc dev ${emmcdev} 1; then setexpr fw_sz ${filesize} / 0x200; setexpr fw_sz ${fw_sz} + 1; mmc write ${loadaddr} 0x2 ${fw_sz}; fi; fi
update_sd_firmware=if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; if mmc dev ${mmcdev}; then if ${get_cmd} ${update_sd_firmware_filename}; then setexpr fw_sz ${filesize} / 0x200; setexpr fw_sz ${fw_sz} + 1; mmc write ${loadaddr} 0x2 ${fw_sz}; fi; fi
Environment size: 3932/8188 bytes
=>
*****************************命令及子命令*****************************
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
=> printenv bootcmd
bootcmd=run findfdt;mmc dev ${mmcdev};if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
=> printenv findfdt
findfdt=if test $fdt_file = undefined; then if test $board_name = SABREAUTO && test $board_rev = MX6QP; then setenv fdt_file imx6qp-sabreauto.dtb; fi; if test $board_name = SABREAUTO && test $board_rev = MX6Q; then setenv fdt_file imx6q-sabreauto.dtb; fi; if test $board_name = SABREAUTO && test $board_rev = MX6DL; then setenv fdt_file imx6dl-sabreauto.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6QP; then setenv fdt_file imx6qp-sabresd.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6Q; then setenv fdt_file imx6q-c-sabresd.dtb; fi; if test $board_name = SABRESD && test $board_rev = MX6DL; then setenv
=> printenv mmcdev
mmcdev=2
=> printenv loadbootscript
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
=> printenv bootscript
bootscript=echo Running bootscript from mmc ...; source
=> printenv loadimage
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
=> printenv mmcboot
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
=> printenv netboot
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
=>
嵌入式之家画的流程图
uboot 环境参数介绍
uboot 中环境参数为我们提供一种不修改 uboot 源码的情况下,能够修改 kernel 启动倒计时、ip 地址、以及向内核传递不同的参数等。
在板子上使用 printenv 可查看板子上所有的环境参数,使用 setenv 添加/修改/删除环境参数,具体说明如下所示:
# 设置新的环境参数名为 sen,值为 100
=> setenv sen 100
=> echo $sen
100
# 将值修改为 200
=> setenv sen 200
=> echo $sen
200
# 删除 sen 环境参数
=> setenv sen
=> echo $sen
=>
默认情况下使用 setenv 命令修改环境参数重启后就会消失,若想要掉电保存需要执行 saveenv 将环境参数保存到存储介质。
uboot 上有一些官方规定的环境变量,这些环境变量在 uboot 有着特殊的作用,可通过以下链接查看:https://www.denx.de/wiki/view/DULG/UBootEnvVariables
3 U-Boot 编译
3.1 系统
Ubuntu 18.04 LTS
3.2 安装依赖和编译工具
sudo apt install make git gcc-arm-none-eabi gcc bison flex libssl-dev dpkg-dev lzop libncurses5-dev
3.3 获取 U-Boot
(1)下载源代码
官方 uboot GitHub:
https://github.com/u-boot/u-boot
映射到gitee
https://gitee.com/ingenic-dev/u-boot
NXP 提供的 uboot 下载链接:
https://github.com/Freescale/u-boot-fslc
映射到gitee
https://gitee.com/xrke/u-boot-fslc
野火提供的 uboot 下载链接:
https://gitee.com/Embedfire/ebf_linux_uboot
- 如下尝试下载 Freescale 的都失败,网络不行
# 直接全部下载报错
bot@u18:~/worthsen/u-boot$ git clone https://github.com/Freescale/u-boot-fslc.git
Cloning into 'u-boot-fslc'...
remote: Enumerating objects: 975157, done.
remote: Counting objects: 100% (135382/135382), done.
remote: Compressing objects: 100% (26711/26711), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
# 只拉取 2020.10+fslc 分支
# -b 2020.10+fslc 为只拉取该分支内容,可以改为其他分支名称
# --depth 1为只拉取最近一次提交的内容
bot@u18:~/worthsen/u-boot$ git clone -b 2020.10+fslc https://github.com/Freescale/u-boot-fslc.git
Cloning into 'u-boot-fslc'...
remote: Enumerating objects: 975157, done.
remote: Counting objects: 100% (135382/135382), done.
remote: Compressing objects: 100% (26711/26711), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
# 增加缓存,设置为500M
bot@u18:~/worthsen/u-boot$ git config --global http.postBuffer 524288000
bot@u18:~/worthsen/u-boot$ git config --global --get http.postBuffer
524288000
bot@u18:~/worthsen/u-boot$ git clone -b 2020.10+fslc https://github.com/Freescale/u-boot-fslc.git
Cloning into 'u-boot-fslc'...
remote: Enumerating objects: 975157, done.
remote: Counting objects: 100% (135382/135382), done.
remote: Compressing objects: 100% (26714/26714), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
- 借助码云来下载 u-boot 的:https://gitee.com/ingenic-dev/u-boot.git
bot@u18:~/worthsen/u-boot$ git clone https://gitee.com/ingenic-dev/u-boot.git
Cloning into 'u-boot'...
remote: Enumerating objects: 999393, done.
remote: Counting objects: 100% (999393/999393), done.
remote: Compressing objects: 100% (192876/192876), done.
remote: Total 999393 (delta 794995), reused 999393 (delta 794995), pack-reused 0
Receiving objects: 100% (999393/999393), 286.59 MiB | 1.66 MiB/s, done.
Resolving deltas: 100% (794995/794995), done.
Checking out files: 100% (31968/31968), done.
- 借助码云来下载 Freescale 的:https://gitee.com/xrke/u-boot-fslc
bot@u18:~/worthsen/u-boot$ git clone https://gitee.com/xrke/u-boot-fslc.git
Cloning into 'u-boot-fslc'...
remote: Enumerating objects: 975157, done.
remote: Counting objects: 100% (975157/975157), done.
remote: Compressing objects: 100% (164034/164034), done.
remote: Total 975157 (delta 799792), reused 975157 (delta 799792), pack-reused 0
Receiving objects: 100% (975157/975157), 241.30 MiB | 9.14 MiB/s, done.
Resolving deltas: 100% (799792/799792), done.
Checking out files: 100% (19492/19492), done.
bot@u18:~/worthsen/u-boot$ cd u-boot-fslc/
bot@u18:~/worthsen/u-boot/u-boot-fslc$ git branch -a
* 2023.04+fslc
remotes/origin/2015.07+fslc
remotes/origin/2015.10+fslc
...
bot@u18:~/worthsen/u-boot/u-boot-fslc$ git checkout 2020.10+fslc
Branch '2020.10+fslc' set up to track remote branch '2020.10+fslc' from 'origin'.
Switched to a new branch '2020.10+fslc'
bot@u18:~/worthsen/u-boot/u-boot-fslc$ git branch
* 2020.10+fslc
2023.04+fslc
bot@u18:~/worthsen/u-boot/u-boot-fslc$
- 下载野火的
https://gitee.com/Embedfire/ebf_linux_uboot
git clone https://gitee.com/Embedfire/ebf_linux_uboot
(2)查看切换分支
3.4 uboot 工程结构 & 变量 & 子功能
3.4.1 uboot 工程结构
uboot 的源代码布局和 Linux 类似,使用了按照模块划分的结构,并且充分考虑了体系结构和跨平台问题,其源代码树结构请参考如下:
目录/文件 | 说明 |
---|---|
api | 通用的 API 函数相关目录 |
arch | 与芯片架构相关的目录 |
board | 板级相关信息目录 |
boot | 包含与启动过程相关的代码,如自举加载程序(bootstrap)代码。 |
cmd | uboot 命令相关的目录 |
common | 通用代码目录 |
configs | boot 配置文件目录 |
disk | 磁盘相关内容目录 |
doc | 说明文档 |
drivers | 驱动代码相关目录 |
dtoverlay | 设备树相关目录 |
dts | 设备树相关目录 |
env | uboot 环境相关 |
examples | 示例代码目录 |
fs | 文件系统相关目录 |
include | 头文件相关目录 |
lib | lib库文件目录 |
Licenses | 许可证相关目录 |
net | 网络相关代码目录 |
post | 上电自检相关目录 |
scripts | 相关脚本目录 |
test | 测试代码目录 |
tools | uboot 构建工具相关的目录 |
Kconfig | 图形配置界面相关目录 |
Makefile | Makefile 文件 |
3.4.2 uboot 变量
变量 | 数值 | 描述 |
---|---|---|
__image_copy_start | 0x87800000 | uboot拷贝的首地址 |
__image_copy_end | 0x8785dd54 | uboot拷贝的结束地址 |
__rel_dyn_start | 0x8785dd54 | .rel.dyn段起始地址 |
__rel_dyn_end | 0x878668f4 | .rel.dyn段结束地址 |
__image_binary_end | 0x878668f4 | 镜像结束地址 |
__bss_start | 0x8785dd54 | .bss段起始地址 |
__bss_end | 0x878a8e74 | .bss段结束地址 |
3.4.3 uboot 子功能
- bootz流程
3.5 uboot 编译
来自 lzd626 的图解
-
配置:当输入“make xxx_defconfig”的时候就会匹配到%config 目标,目标“%config”依赖于 scripts_basic、outputmakefile 和 FORCE
-
编译:过程如下
赵建辉理解的 u-boot.imx 目标依赖关系图
https://github.com/zhaojh329/U-boot-1/blob/master/%E7%AC%AC9%E7%AB%A0-U-boot%E7%BC%96%E8%AF%91%E4%B9%8B%E4%BA%8C%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B.md
野火 ebf_v2020_10_imx 分支
野火提供的 imx6ull uboot 分为 nand 版本和 emmc 版本,以编译 emmc 版本为例
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/ebf_v2017_09_rk3328
remotes/origin/ebf_v2017_09_rk3399
remotes/origin/ebf_v2018.11_star
remotes/origin/ebf_v2020_10_imx
remotes/origin/ebf_v2021_07_rk3399
remotes/origin/imx_v2019.04_ls1043ardb
remotes/origin/imx_v2020.04_5.4.47_2.2.0
remotes/origin/master
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ git checkout ebf_v2020_10_imx
Branch 'ebf_v2020_10_imx' set up to track remote branch 'ebf_v2020_10_imx' from 'origin'.
Switched to a new branch 'ebf_v2020_10_imx'
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ git branch
* ebf_v2020_10_imx
master
# (1)sudo make distclean 清除上次生成的编译环境,避免之前的环境干扰影响编译结果
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ sudo make distclean
# (2)sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi- mx6ull_fire_mmc_defconfig
# 加载板级配置文件,具体的板级配置文件在 uboot 根目录下的 configs 目录下
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi- mx6ull_fire_mmc_defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
# (3)sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi-
# 设置编译架构为 arm 编译工具链为 arm-none-eabi- 然后开始编译
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$ sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi-
scripts/kconfig/conf --syncconfig Kconfig
UPD include/config.h
CFG u-boot.cfg
...
CFGCHK u-boot.cfg
bot@u18:~/worthsen/u-boot/ebf_linux_uboot$
3.6 编译产物分析
文件 | 说明 |
---|---|
u-boot | 初步链接后得到的uboot文件 |
u-boot-nodtb.bin | 在u-boot的基础上,经过objcopy去除符号表信息之后的可执行程序 |
u-boot.dtb | dtb文件 |
u-boot-dtb.bin | 将u-boot-nodtb.bin和u-boot.dtb打包在一起的文件 |
u-boot.bin | 在需要dtb的情况下,直接由u-boot-dtb.bin复制而来,也就是编译u-boot的最终目标 |
u-boot.lds | uboot的连接脚本 |
System.map | 连接之后的符号表文件 |
u-boot.cfg | 由uboot配置生成的文件 |
4 U-Boot 烧录
4.1 Mfgtool 烧写 Uboot 到内部存储(EMMC/NAND 通用)
系统烧写工具–MfgTool
介绍
MFGTool 工具是 NXP 官方推荐的一个使用 USB OTG 来升级镜像的软件工具,它是 NXP 针对 i.MX 系列处理器专门使用的烧录工具,可以用来升级 linux,单独烧录某一系统分区,独立地烧录 spi flash、nor flash、sd card、nand flash,emmc 等,只需简单的配置,就可以使用该工具将编译好的文件系统和镜像文件烧录到开发板上,使用起来非常方便。
烧录步骤分析
MFGtool 工具的烧录步骤分为两个阶段:BurnStarp 和 Updater。
第一阶段先烧录媒介镜像到 DDR,然后启动媒介系统;
第二阶段通过该系统把目标镜像固化到存储设备中。
第二阶段严格根据 ucl2.xml 文件来处理。
4.2 Uboot 烧写到 SD 卡镜像(常用于做 uboot 测试)
系统烧写工具–MfgTool
5 U-Boot 移植
略
6 U-Boot 控制 GPIO & 定制自己的 Uboot 单板
6.1 U-Boot 控制 GPIO
-
介绍
Uboot 的 GPIO 是常用的功能,在开发中常常需要在上电时进行控制。 -
详见文件
[野火]《嵌入式Linux镜像构建与部署——基于LubanCat-i.MX6ULL开发板》
6.2 U-Boot 定制自己的 Uboot 单板
- 详见文件
[野火]《嵌入式Linux镜像构建与部署——基于LubanCat-i.MX6ULL开发板》
7 电脑 与 嵌入式设备 系统启动区别
在 一只嵌入式爱好者 的图上加了补充
一张图看懂嵌入式与PC启动流程
知识点
1 BIOS、UEFI、MBR、GPT、GRUB 区别联系
基本输入输出系统【BIOS、UEFI】
BIOS(Basic Input Output System),直译成中文名称就是"基本输入输出系统"。它是一组固化到主板中一个ROM芯片上的程序,它可以从CMOS中读写系统设置的具体信息。此程序保存着计算机最重要的基本输入输出程序、开机后的自检程序和系统自启动程序。
UEFI(Unified Extensible Firmware Interface)则是取代传统 BIOS 的,相比传统BIOS来说,它更易实现,容错和纠错特性也更强。传统 BIOS 主要支持 MBR 引导,UEFI则是取代传统BIOS,使用 GPT 替代 MBR 引导,从而支持2TB以上硬盘。
特性 | UEFI | BIOS |
---|---|---|
开源/闭源 | 开源 | 闭源 |
开发效率 | 高 | 低 |
标准接口 | 是 | 否 |
接口混乱 | 否 | 是 |
代码构成 | 绝大多数是C代码 | 主要是汇编 |
性能 | 异步+时钟中断 | 中断机制 |
扩展和兼容性 | 模块化驱动设计 | 静态链接 |
安全 | 安全 | 未考虑安全 |
其它 | 支持容量超过2TB的驱动器 | 不支持容量超过2TB的驱动器 |
硬盘分区初始化格式【MBR、GPT】
硬盘分区初始化的格式主要有两种,分别为MBR格式和GPT格式。
MBR 最大的缺点则是不支持容量大于2T的硬盘。
GPT是另一种更先进的磁盘系统分区方式,它的出现弥补了MBR这个缺点,最大支持18EB的硬盘,是基于UEFI使用的磁盘分区架构。
bootloader【GRUB】
GRUB(GRand unified bootloader),多操作系统启动程序。它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。
GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。它是一个多重操作系统启动管理器,用来引导不同系统,如Windows、Linux。Linux常见的引导程序包括LILO、GRUB、GRUB2。
如下图所示为GRUB加载引导流程
参考
1、yocto 手册
2、[野火]《嵌入式Linux镜像构建与部署——基于LubanCat-i.MX6ULL开发板》
3、BitBake 手册
4、The U-Boot Documentation
5、嵌入式 Linux 开发的基本概念和学习新路线
6、BootLoader 介绍 与 uboot 简介
7、[架构之路-26]:目标系统 - 系统软件 - bootloader uboot使用方法、常用命令
8、wiki–Bootloader
9、wiki–Das U-Boot
10、rockbox–官网
11、rockbox–Rockbox User Manual
12、【干货】BIOS、UEFI、MBR、GPT、GRUB 到底是什么意思?
13、BIOS、UEFI、Boot Loader都是些什么
14、全网最全面最易懂的U-Boot解读
15、嵌入式Linux系统 的组成(BootLoader,Kernel,Root Filesystem)
16、一张图看懂嵌入式与PC启动流程
17、Linux学习笔记(7)——u-boot常用指令
18、制作rk3588镜像及烧写
19、Yocto/docs
/0007_MFGTool_initramfs_Boot_Root_Filesystem.md
20、Linux学习笔记(7)——u-boot常用指令
21、UBoot之bootcmd和bootarg环境变量
22、Uboot中bootargs以及bootcmd设置
23、2. 如何学习linux开发
24、Linux/u-boot 代码目录结构
25、uboot学习(1)-uboot目录详解
26、uboot_imx_2016浅析
27、uboot启动流程详细分析(基于i.m6ull)
28、good–u-boot 的编译和配置
29、U-Boot启动过程概述 U-Boot启动代码具体分析
30、uboot 的配置和编译过程
31、U-boot学习笔记 嵌入式项目,基于imx6q的编译执行
32、[uboot] (第四章)uboot流程——uboot编译流程