u-boot/u-boot
GitHub: u-boot/u-boot
嵌入式领域最流行的通用引导加载程序,支持多架构硬件初始化、操作系统引导和丰富的存储/网络启动方式。
Stars: 4973 | Forks: 4330
# SPDX-License-Identifier: GPL-2.0+
#
# (C) 版权所有 2000 - 2013
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
# 概述:
本目录包含 U-Boot 的源代码,U-Boot 是一款引导加载程序,适用于基于 PowerPC、ARM、MIPS 和其他几种处理器的嵌入式主板,可以安装在引导 ROM 中,用于初始化和测试硬件,或下载和运行应用程序代码。
U-Boot 的开发与 Linux 紧密相关:部分源代码源自 Linux 源码树,我们有一些共同的头文件,并且为支持 Linux 镜像引导做了特殊准备。
我们特别注意使该软件易于配置和扩展。例如,所有监视器命令都使用相同的调用接口实现,因此添加新命令非常容易。此外,与其将很少使用的代码(例如硬件测试实用程序)永久添加到监视器中,不如动态加载并运行它。
# 状态:
通常, configs/ 目录中存在默认配置文件的所有主板都在一定程度上经过了测试,可以被认为是“正常工作”的。事实上,其中许多正用于生产系统。
如果出现问题,您可以使用
```
scripts/get_maintainer.pl
```
来确定负责各种主板和子系统的人员或公司。或者查看 git 日志。
# 获取帮助:
如果您对 U-Boot 有疑问、遇到问题或希望为其做出贡献,应向 U-Boot 邮件列表 发送消息。还有邮件列表的历史存档 - 请在提问前先搜索存档。
请参阅 https://lists.denx.de/pipermail/u-boot 和
https://marc.info/?l=u-boot
# 获取源代码:
U-Boot 源代码在 Git 仓库中维护,地址为
https://source.denx.de/u-boot/u-boot.git ;您可以在
https://source.denx.de/u-boot/u-boot 在线浏览。
此页面上的“Tags”链接允许您下载任何您感兴趣的版本的压缩包。官方发布版也可以通过 HTTPS 或 FTP 从 DENX 文件服务器获得。
https://ftp.denx.de/pub/u-boot/
ftp://ftp.denx.de/pub/u-boot/
# 我们的起源:
- 从 8xxrom 源码开始
- 创建 PPCBoot 项目 (https://sourceforge.net/projects/ppcboot)
- 清理代码
- 使添加自定义主板更容易
- 使添加其他 [PowerPC] CPU 成为可能
- 扩展功能,特别是:
* 提供扩展的 Linux 引导加载程序接口
* S-Record 下载
* 网络启动
* ATA 磁盘 / SCSI ... 启动
- 创建 ARMBoot 项目 (https://sourceforge.net/projects/armboot)
- 添加其他 CPU 系列(从 ARM 开始)
- 创建 U-Boot 项目 (https://sourceforge.net/projects/u-boot)
- 当前项目页面:见 https://www.denx.de/wiki/U-Boot
# 命名和拼写:
本项目的“官方”名称是“Das U-Boot”。拼写“U-Boot”应在所有书面文本(文档、源文件中的注释等)中使用。示例:
```
This is the README file for the U-Boot project.
```
文件名等应基于字符串“u-boot”。示例:
```
include/asm-ppc/u-boot.h
#include
```
变量名、预处理器常量等应基于字符串“u_boot”或“U_BOOT”。示例:
```
U_BOOT_VERSION u_boot_logo
IH_OS_U_BOOT u_boot_hush_start
```
# 软件配置:
## 选择处理器架构和主板类型:
对于所有支持的主板,都有现成的默认配置可用;只需输入“make _defconfig”。
示例:对于 TQM823L 模块,输入:
```
cd u-boot
make TQM823L_defconfig
```
注意:如果您正在寻找某块主板的默认配置文件,确信它以前存在但现在丢失了,请查看文件 doc/README.scrapyard 以获取不再受支持的主板列表。
## Sandbox 环境:
U-Boot 可以使用 'sandbox' 主板原生构建以在 Linux 主机上运行。这允许在原生平台上进行非主板或架构特定的功能开发。Sandbox 也用于运行 U-Boot 的一些测试。
有关更多详细信息,请参阅 doc/arch/sandbox/sandbox.rst。
需要配置以下选项:
- CPU 类型:确切定义一个,例如 CONFIG_MPC85XX。
- 主板类型:确切定义一个,例如 CONFIG_MPC8540ADS。
- 85xx CPU 选项:
CONFIG_SYS_PPC64
指定核心是 64 位 PowerPC 实现(实现 Power ISA 的“64”类别)。除其他可能的原因外,这对于 ePAPR 合规性是必要的。
CONFIG_SYS_FSL_ERRATUM_A004510
启用针对勘误 A004510 的变通方案。如果设置,
则必须设置 CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 和
CFG_SYS_FSL_CORENET_SNOOPVEC_COREONLY。
CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV
CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 (可选)
定义一个或两个应应用 A004510 变通方案的 SoC 修订版(SVR 的低 8 位)。
SVR 的其余部分要么与勘误是否存在的决定无关(例如 p2040 与
p2041),要么由构建目标暗示,该目标控制
是否设置 CONFIG_SYS_FSL_ERRATUM_A004510。
有关此勘误的更多信息,请参阅 Freescale 应用笔记 4493。
CFG_SYS_FSL_CORENET_SNOOPVEC_COREONLY
这是根据 A004510 变通方案写入 CCSR 偏移量 0x18600
的值。
CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
单源时钟是某些 FSL SoC 中存在的时钟模式。
在此模式下,单个差分时钟用于向
sysclock、ddrclock 和 usbclock 供电。
- 通用 CPU 选项:
CONFIG_SYS_FSL_DDR
正在使用 Freescale DDR 驱动程序。这种类型的 DDR 控制器
存在于 mpc83xx、mpc85xx 以及某些 ARM 核心 SoC 中。
CFG_SYS_FSL_DDR_ADDR
Freescale DDR 内存映射寄存器基址。
CONFIG_SYS_FSL_IFC_CLK_DIV
定义平台时钟的分频器(输入到 IFC 控制器的时钟)。
CONFIG_SYS_FSL_LBC_CLK_DIV
定义平台时钟的分频器(输入到 eLBC 控制器的时钟)。
CFG_SYS_FSL_DDR_SDRAM_BASE_PHY
从 DDR 控制器视角看的物理地址。对于所有 Power SoC,
它与 CFG_SYS_DDR_SDRAM_BASE 相同。但
对于 ARM SoC,这可能不同。
- ARM 选项:
CFG_SYS_EXCEPTION_VECTORS_HIGH
选择 ARM 核心的高异常向量,例如,不要
清除 CP15 的 c1 寄存器的 V 位。
COUNTER_FREQUENCY
通用定时器时钟源频率。
COUNTER_FREQUENCY_REAL
如果实际时钟与 COUNTER_FREQUENCY 不同,且
只能在运行时确定,则为通用定时器时钟源频率。
- Linux 内核接口:
CONFIG_OF_LIBFDT
新内核版本期望固件设置使用扁平化设备树传递(基于开放固件
概念)。
CONFIG_OF_LIBFDT
* 新的基于 libfdt 的支持
* 添加“fdt”命令
* bootm 命令自动更新 fdt
OF_TBCLK - 时基频率。
具有 QUICC 引擎的主板需要 OF_QE 来设置 UCC MAC
地址
CONFIG_OF_IDE_FIXUP
U-Boot 可以检测 IDE 设备是否存在。
如果不存在,并且激活了此新配置选项,U-Boot
将在引导 Linux 之前从 DTS 中删除 ATA 节点,
这样 Linux IDE 驱动程序就不会探测设备并
崩溃。这对于有缺陷的硬件 (uc101) 是必需的,其中
没有下拉电阻连接到信号 IDE5V_DD7。
- vxWorks 引导参数:
bootvx 使用以下环境变量构建有效的引导行:
bootdev, bootfile, ipaddr, netmask,
serverip, gatewayip, hostname, othbootargs。
它加载 bootfile 指向的 vxWorks 镜像。
注意:如果定义了“bootargs”环境变量,它将覆盖
上面讨论的默认值。
- ARM 的缓存配置:
CFG_SYS_PL310_BASE - PL310 控制器寄存器空间的物理基址
- 串口:
CFG_PL011_CLOCK
如果您有 Amba PrimeCell PL011 UART,请将此变量设置为
UART 的时钟速度。
CFG_PL01x_PORTS
如果您的主板上有 Amba PrimeCell PL010 或 PL011 UART,
请将其定义为每个(支持的)端口的基址列表。
参见例如 include/configs/versatile.h
CONFIG_SERIAL_HW_FLOW_CONTROL
定义此变量以在串行驱动程序中启用硬件流控制。
此选项的当前用户是 drivers/serial/nsl16550.c 驱动程序
- 命令移除
如果不需要命令来引导,您可以禁用
CONFIG_CMDLINE 以将其移除。在这种情况下,命令行
将不可用,当 U-Boot 想要执行
引导命令(启动时)时,它将调用 board_run_command()
代替。这对于非常简单的引导过程可以显著减小镜像大小。
- 正则表达式支持:
CONFIG_REGEX
如果定义了此变量,U-Boot 将链接到
SLRE(超轻正则表达式)库,
这为某些命令添加了正则表达式支持,例如
“env grep”和“setexpr”。
- 看门狗:
CFG_SYS_WATCHDOG_FREQ
某些平台自动从定时器中断处理程序调用 WATCHDOG_RESET()
,每隔 CFG_SYS_WATCHDOG_FREQ 次中断。如果未通过
主板配置文件设置,则默认值为 CONFIG_SYS_HZ/2
(即 500)。将 CFG_SYS_WATCHDOG_FREQ
设置为 0 将禁用从定时器中断调用 WATCHDOG_RESET()。
- GPIO 支持:
CFG_SYS_I2C_PCA953X_WIDTH 选项指定
chip-ngpio 对列表,告诉 PCA953X 驱动程序特定
芯片支持的引脚数。
请注意,如果 GPIO 设备使用 I2C,则还必须配置 I2C 接口。请参阅下面的 I2C 支持。
- 时间戳支持:
当选择 CONFIG_TIMESTAMP 时,镜像的时间戳
(日期和时间)由镜像命令(如 bootm 或 iminfo)打印。
当您选择 CONFIG_CMD_DATE 时,此选项会自动启用。
- 支持的分区标签:
零个或多个以下选项:
CONFIG_MAC_PARTITION Apple 的 MacOS 分区表。
CONFIG_ISO_PARTITION ISO 分区表,用于 CDROM 等。
CONFIG_EFI_PARTITION GPT 分区表,当 EFI 是引导加载程序时常见。注意 2TB 分区限制;请参阅 disk/part_efi.c
CONFIG_SCSI) 您还必须配置对至少一种非 MTD 分区类型的支持。
- 网络支持 (PCI):
CONFIG_E1000_SPI
用于直接访问 Intel 8257x 上 SPI 总线的实用程序代码。
除非您至少设置 CONFIG_CMD_E1000 或 CONFIG_E1000_SPI_GENERIC 之一,否则这不会执行任何有用的操作。
CONFIG_NATSEMI
支持 National dp83815 芯片。
CONFIG_NS8382X
支持 National dp8382[01] 千兆芯片。
- 网络支持(其他):
CONFIG_CALXEDA_XGMAC
支持 Calxeda XGMAC 设备
CONFIG_LAN91C96
支持 SMSC 的 LAN91C96 芯片。
CONFIG_LAN91C96_USE_32_BIT
定义此选项以启用 32 位寻址
CFG_SYS_DAVINCI_EMAC_PHY_COUNT
如果您有超过 3 个 PHY,请定义此选项。
CONFIG_FTGMAC100
支持 Faraday 的 FTGMAC100 千兆 SoC 以太网
CONFIG_FTGMAC100_EGIGA
定义此选项以使用千兆 PHY 进行 GE 链接更新。
如果 FTGMAC100 连接到千兆 PHY,请定义此选项。
如果您的系统只有 10/100 PHY,可能不会出现
错误行为。因为 PHY 在轮询千兆状态和千兆
控制寄存器时通常返回超时或
无用数据。此行为不会影响
10/100 链接速度更新的正确性。
CONFIG_SH_ETHER
支持 Renesas 片上以太网控制器
- TPM 支持:
CONFIG_TPM
支持 TPM 设备。
CONFIG_TPM_TIS_INFINEON
支持 Infineon i2c 总线 TPM 设备。目前每个系统只支持一个设备。
CONFIG_TPM_TIS_I2C_BURST_LIMITATION
定义突发计数字节的上限
CONFIG_TPM_ATMEL_TWI
支持 Atmel TWI TPM 设备。需要 I2C 支持。
CONFIG_TPM_TIS_LPC
支持通用并口 TPM 设备。目前每个系统只支持一个设备。
CONFIG_TPM
定义此选项以启用 TPM支持库,该库提供
功能接口给某些 TPM 命令。
需要对 TPM 设备的支持。
CONFIG_TPM_AUTH_SESSIONS
定义此选项以在 TPM 库中启用授权功能。
需要 CONFIG_TPM 和 CONFIG_SHA1。
- USB 支持:
目前仅支持 UHCI 主机控制器
(PIP405, MIP405);定义
CONFIG_USB_UHCI 以启用它。
定义 CONFIG_USB_KEYBOARD 以启用 USB 键盘
并定义 CONFIG_USB_STORAGE 以启用 USB
存储设备。
注意:
支持 USB 键盘和 USB 软驱
(TEAC FD-05PUB)。
CONFIG_USB_DWC2_REG_ADDR DWC2 HW 模块寄存器的物理 CPU 地址。
- USB 设备:
如果您希望使用 USB 控制台,请定义以下内容。
固件从串行控制台重建后,发出
命令“setenv stdin usbtty; setenv stdout usbtty”并
连接您的 USB 电缆。Unix 命令“dmesg”应该打印
它已发现新设备。环境变量 usbtty
可以设置为 gserial 或 cdc_acm 以使您的设备
作为 Linux gserial 设备或通用设备类抽象控制模型串行设备出现在 USB 主机面前。
如果您选择 usbtty = gserial,您应该能够通过以下方式枚举 Linux 主机
# modprobe usbserial vendor=0xVendorID product=0xProductID
否则如果使用 cdc_acm,只需设置环境变量 usbtty 为 cdc_acm 即可。以下内容可能会在 YourBoardName.h 中定义
如果您有 USB-IF 分配的 VendorID,您可能希望在 BoardName.h 或直接在 usbd_vendor_info.h 中定义您自己的供应商特定值。如果您没有定义 CONFIG_USBD_MANUFACTURER, CONFIG_USBD_PRODUCT_NAME, CONFIG_USBD_VENDORID 和 CONFIG_USBD_PRODUCTID,那么 U-Boot 应该对其目标主机伪装成 Linux 设备。
CONFIG_USBD_MANUFACTURER
将此字符串定义为您的公司名称
- CONFIG_USBD_MANUFACTURER "my company"
CONFIG_USBD_PRODUCT_NAME
将此字符串定义为您的产品名称
- CONFIG_USBD_PRODUCT_NAME "acme usb device"
CONFIG_USBD_VENDORID
将此定义为 USB 实施者论坛分配给您的供应商 ID。这*必须*是真正的供应商 ID,以避免污染 USB 命名空间。
- CONFIG_USBD_VENDORID 0xFFFF
CONFIG_USBD_PRODUCTID
将此定义为您的设备的唯一产品 ID
- CONFIG_USBD_PRODUCTID 0xFFFF
- MMC 支持:
CONFIG_SH_MMCIF
支持 Renesas 片上 MMCIF 控制器
CONFIG_SH_MMCIF_ADDR
定义 MMCIF 寄存器的基址
CONFIG_SH_MMCIF_CLK
定义 MMCIF 的时钟频率
- USB 设备固件更新 (DFU) 类支持:
CONFIG_DFU_OVER_USB
这将启用 DFU USB 类的 USB 部分
CONFIG_DFU_NAND
这将启用通过 DFU 公开 NAND 设备的支持。
CONFIG_DFU_RAM
这将启用通过 DFU 公开 RAM 的支持。
注意:DFU 规范指的是非易失性内存的使用,但
允许超出规范范围的使用 - 这里是 RAM 使用,
一种主要帮助开发人员的用法。
CONFIG_SYS_DFU_DATA_BUF_SIZE
Dfu 传输在将数据写入原始存储设备之前使用缓冲区。使此缓冲区的大小(以字节为单位)可配置。此缓冲区的大小也可以通过“dfu_bufsiz”环境变量进行配置。
CONFIG_SYS_DFU_MAX_FILE_SIZE
更新文件而不是原始存储设备时,我们使用静态缓冲区将文件复制到其中,然后在获得整个文件后写入该缓冲区。将此定义为缓冲区的最大文件大小(以字节为单位)。如果未定义,默认值为 4 MiB。
DFU_DEFAULT_POLL_TIMEOUT
轮询超时 [ms],是设备可以发送给主机的超时时间。主机必须在发送后续 DFU_GET_STATUS 请求给设备之前等待此超时。
DFU_MANIFEST_POLL_TIMEOUT
轮询超时 [ms],这是设备在进入 dfuMANIFEST 状态时发送给主机的超时时间。主机在再次向设备发送 USB 请求之前等待此超时。
- 键盘支持:
有关可用的键盘驱动程序,请参阅 Kconfig 帮助。
- MII/PHY 支持:
CONFIG_PHY_CLOCK_FREQ (ppc4xx)
MII 总线的时钟频率
CONFIG_PHY_CMD_DELAY (ppc4xx)
某些 PHY(如 Intel LXT971A)在发出命令后需要额外的延迟才能读取 MII 状态寄存器
- BOOTP 恢复模式:
CONFIG_BOOTP_RANDOM_DELAY
如果网络中有许多目标尝试使用 BOOTP 引导,您可能希望避免所有系统在完全相同的时刻发送 BOOTP 请求(例如在从断电中恢复时会发生这种情况,此时所有系统都将尝试引导,从而淹没 BOOTP 服务器。定义 CONFIG_BOOTP_RANDOM_DELAY 会导致在发送 BOOTP 请求之前插入随机延迟。此时将插入以下延迟:
第 1 次 BOOTP 请求: 延迟 0 ... 1 秒
第 2 次 BOOTP 请求: 延迟 0 ... 2 秒
第 3 次 BOOTP 请求: 延迟 0 ... 4 秒
第 4 次及后续 BOOTP 请求: 延迟 0 ... 8 秒
CFG_BOOTP_ID_CACHE_SIZE
BOOTP 数据包使用 32 位 ID 进行唯一标识。服务器会将 ID 从客户端请求复制到响应中,U-Boot 将使用它来确定它是否是传入响应的目的地。某些服务器会在分发地址之前检查地址是否未被使用(通常使用 ARP ping),因此可能需要几百毫秒才能响应。网络拥塞也可能影响响应返回客户端所需的时间。如果该时间太长,U-Boot 将重新传输请求。为了允许在这些重新传输之后仍然接受较早的响应,U-Boot 的 BOOTP 客户端保留了一个小的 ID 缓存。CFG_BOOTP_ID_CACHE_SIZE 控制此缓存的大小。默认设置是为最多四个未完成的请求保留 ID。增加此值将允许 U-Boot 在具有异常高延迟的网络中接受来自 BOOTP 客户端的提供。
- DHCP 高级选项:
- 链路本地 IP 地址协商:
与本地网络上的其他链路本地客户端协商不需要显式配置的地址。
如果无法保证设备必须在其中运行的所有环境中都存在 DHCP 服务器,则这特别有用。
有关更多信息,请参阅 doc/README.link-local。
- 来自环境变量的 MAC 地址
FDT_SEQ_MACADDR_FROM_ENV
使用从环境变量中按顺序获取的 MAC 地址修复设备树。此配置基于这样的假设:设备树中不可用的以太网节点要么不存在,要么其状态已标记为“disabled”。
- CDP 选项:
CONFIG_CDP_DEVICE_ID
CDP 触发帧中使用的设备 ID。
CONFIG_CDP_DEVICE_ID_PREFIX
一个两个字符的字符串,前缀于设备的 MAC 地址。
CONFIG_CDP_PORT_ID
一个 printf 格式字符串,包含端口的 ascii 名称。通常设置为“eth%d”,它为第一个以太网设置 eth0,为第二个设置 eth1,依此类推。
CONFIG_CDP_CAPABILITIES
一个 32 位整数,指示设备功能;
0x00000010 表示不转发的主机。
CONFIG_CDP_VERSION
包含软件版本的 ascii 字符串。
CONFIG_CDP_PLATFORM
包含平台名称的 ascii 字符串。
CONFIG_CDP_TRIGGER
触发时发送的 32 位整数。
CONFIG_CDP_POWER_CONSUMPTION
一个 16 位整数,包含设备的功耗,单位为 0.1 毫瓦。
CONFIG_CDP_APPLIANCE_VLAN_TYPE
一个包含 VLAN ID 的字节。
- 状态 LED: CONFIG_LED_STATUS
几种配置允许使用 LED 显示当前状态。例如,LED 将在运行 U-Boot 代码时快速闪烁,一旦收到对 BOOTP 请求的回复就会停止闪烁,并在 Linux 内核运行时开始缓慢闪烁(由 Linux 内核中的状态 LED 驱动程序支持)。定义 CONFIG_LED_STATUS 在 U-Boot 中启用此功能。
附加选项:
CONFIG_LED_STATUS_GPIO
状态 LED 可以连接到 GPIO 引脚。
在这种情况下,gpio_led 驱动程序可以用作状态 LED 后端实现。定义 CONFIG_LED_STATUS_GPIO 以将 gpio_led 驱动程序包含在 U-Boot 二进制文件中。
CFG_GPIO_LED_INVERTED_TABLE
某些 GPIO 连接的 LED 可能具有反极性,在这种情况下,GPIO 高电平对应于 LED 熄灭状态,而 GPIO 低电平对应于 LED 点亮状态。
在这种情况下,可以定义 CFG_GPIO_LED_INVERTED_TABLE 并列出具有反极性的 GPIO LED。
- I2C 支持:
CFG_SYS_NUM_I2C_BUSES
保存您要使用的 i2c 总线数量。
CFG_SYS_I2C_BUSES
保存您要使用的总线列表
CFG_SYS_I2C_BUSES {{0, {I2C_NULL_HOP}}, \
{0, {{I2C_MUX_PCA9547, 0x70, 1}}}, \
{0, {{I2C_MUX_PCA9547, 0x70, 2}}}, \
{0, {{I2C_MUX_PCA9547, 0x70, 3}}}, \
{0, {{I2C_MUX_PCA9547, 0x70, 4}}}, \
{0, {{I2C_MUX_PCA9547, 0x70, 5}}}, \
{1, {I2C_NULL_HOP}}, \
{1, {{I2C_MUX_PCA9544, 0x72, 1}}}, \
{1, {{I2C_MUX_PCA9544, 0x72, 2}}}, \
}
其中定义了
适配器 0 上的总线 0,无多路复用器
适配器 0 上的总线 1,地址 0x70 端口 1 上有一个 PCA9547
适配器 0 上的总线 2,地址 0x70 端口 2 上有一个 PCA9547
适配器 0 上的总线 3,地址 0x70 端口 3 上有一个 PCA9547
适配器 0 上的总线 4,地址 0x70 端口 4 上有一个 PCA9547
适配器 0 上的总线 5,地址 0x70 端口 5 上有一个 PCA9547
适配器 1 上的总线 6,无多路复用器
适配器 1 上的总线 7,地址 0x72 端口 1 上有一个 PCA9544
适配器 1 上的总线 8,地址 0x72 端口 2 上有一个 PCA9544
如果您的主板上没有 i2c 多路复用器,请忽略此定义。
- 传统 I2C 支持:
如果您使用软件 i2c 接口 (CONFIG_SYS_I2C_SOFT)
则需要定义以下宏(示例来自
include/configs/lwmon.h):
I2C_INIT
(可选)。使能 I2C 控制器或配置端口所需的任何命令。
例如: #define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
I2C_ACTIVE
使 I2C 数据线处于活动状态(被驱动)所需的代码。如果数据线是开漏集电极,此定义可以为空。
例如: #define I2C_ACTIVE (immr->im_cpm.cp_pbdir |= PB_SDA)
I2C_TRISTATE
使 I2C 数据线处于高阻态(非活动)所需的代码。如果数据线是开漏集电极,此定义可以为空。
例如: #define I2C_TRISTATE (immr->im_cpm.cp_pbdir &= ~PB_SDA)
I2C_READ
如果 I2C 数据线为高则返回真,为低则返回假的代码。
例如: #define I2C_READ ((immr->im_cpm.cp_pbdat & PB_SDA) != 0)
I2C_SDA(bit)
如果 为真,则将 I2C 数据线置高。如果为假,则将其清零(置低)。
例如: #define I2C_SDA(bit) \
if(bit) immr->im_cpm.cp_pbdat |= PB_SDA; \
else immr->im_cpm.cp_pbdat &= ~PB_SDA
I2C_SCL(bit)
如果 为真,则将 I2C 时钟线置高。如果为假,则将其清零(置低)。
例如: #define I2C_SCL(bit) \
if(bit) immr->im_cpm_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
I2C_DELAY
此延迟在每个时钟周期调用四次,因此这控制了数据传输速率。数据速率因此为 1 / (I2C_DELAY * 4)。通常定义为类似以下内容:
#define I2C_DELAY udelay(2)
CONFIG_SOFT_I2C_GPIO_SCL / CONFIG_SOFT_I2C_GPIO_SDA
如果您的架构支持通用 GPIO 框架 (asm/gpio.h),
那么您可以另外定义要用作 SCL / SDA 的两个 GPIO。之前的任何 I2C_xxx 宏将根据情况分配给它们基于 GPIO 的默认值。
您应该将这些定义为直接提供给通用 GPIO 函数的 GPIO 值。
CFG_SYS_I2C_NOPROBES
此选项指定发出“i2c probe”命令时将跳过的 I2C 设备列表。
例如
#define CFG_SYS_I2C_NOPROBES {0x50,0x68}
将跳过具有一个 I2C 总线的主板上的地址 0x50 和 0x68
CONFIG_SOFT_I2C_READ_REPEATED_START
定义此选项将强制 soft_i2c 驱动程序中的 i2c_read() 函数在写入地址指针和读取数据之间执行 I2C 重复起始。如果省略此定义,将使用执行停止-起始序列的默认行为。大多数 I2C 设备可以使用任一方法,但有些需要特定的一种。
- SPI 支持: CONFIG_SPI
启用 SPI 驱动程序(目前仅使用 SPI EEPROM 测试过,在 SACSng 主板上也有使用 Crystal A/D 和 D/A 的实例)
CFG_SYS_SPI_MXC_WAIT
等待 SPI 传输完成的超时时间。
默认值: (CONFIG_SYS_HZ/100) /* 10 ms */
- FPGA 支持: CONFIG_FPGA
启用 FPGA 子系统。
CONFIG_FPGA_
启用对特定芯片供应商的支持。
(ALTERA, XILINX)
CONFIG_FPGA_
启用对 FPGA 系列的支持。
(SPARTAN2, SPARTAN3, VIRTEX2, CYCLONE2, ACEX1K, ACEX)
CONFIG_SYS_FPGA_CHECK_BUSY
启用配置函数对 FPGA 配置接口忙状态的检查。此选项需要编写主板或设备特定的函数。
CFG_FPGA_DELAY
如果已定义,则是一个在 FPGA 配置驱动程序中提供延迟的函数。
CFG_SYS_FPGA_CHECK_ERROR
在 FPGA 位流加载期间检查配置错误。例如,如果 INIT_B 线变低(表示 CRC 错误),则在 Virtex II 配置期间中止。
CFG_SYS_FPGA_WAIT_INIT
在 Virtex II FPGA 配置序列中,取消断言 PROB_B 后等待 INIT_B 线取消断言的最长时间。默认时间为 500 ms。
CFG_SYS_FPGA_WAIT_BUSY
在 Virtex II FPGA 配置期间等待 BUSY 取消断言的最长时间。默认为 5 ms。
CFG_SYS_FPGA_WAIT_CONFIG
FPGA 配置后等待的时间。默认为 200 ms。
- 供应商参数保护:
U-Boot 将环境变量“serial#”(主板序列号)和“ethaddr”(以太网地址)的值视为由主板供应商/制造商设置一次的参数,并保护这些变量免受用户的随意修改。设置后,这些变量是只读的,写入或删除尝试将被拒绝。您可以更改此行为:
如果在您的配置文件中 #defined CONFIG_ENV_OVERWRITE,则供应商参数的写保护将完全禁用。任何人都可以更改或删除这些参数。
通过在“.flags”变量中配置访问类型或定义 CFG_ENV_FLAGS_LIST_STATIC,可以以更灵活的方式对任何变量完成相同的操作。
- 受保护的 RAM:
CFG_PRAM
定义此变量以启用“受保护的 RAM”的保留,即不被 U-Boot 覆盖的 RAM。定义 CFG_PRAM 以保存您要为 pRAM 保留的 kB 数。您可以通过将环境变量“pram”定义为您要保留的 kB 数来覆盖此默认值。请注意,主板信息结构仍将显示 RAM 的完整数量。如果保留了 pRAM,则会自动定义一个新的环境变量“mem”,以保存剩余 RAM 的数量,其格式可以作为引导参数传递给 Linux,例如像这样:
setenv bootargs ... mem=\${mem}
saveenv
这样您就可以告诉 Linux 也不要使用此内存,从而产生一个不会受重新启动影响的内存区域。
*警告*如果您的主板配置使用 RAM 大小的自动检测,则必须确保此内存测试是非破坏性的。目前,已知以下主板配置是“pRAM-clean”的:
IVMS8, IVML24, SPD8xx,
HERMES, IP860, RPXlite, LWMON,
FLAGADM
- 错误恢复:
注意:
在当前的实现中,局部变量空间和全局环境变量空间是分开的。局部变量是您通过简单地键入 `name=value` 定义的变量。稍后要访问局部变量,您必须写入 `$name' 或 `${name}';要直接执行变量的内容,请在命令提示符处键入 `$name'。
全局环境变量是您使用 setenv/printenv 处理的变量。要运行存储在此类变量中的命令,您需要使用 run 命令,并且绝不能使用 '$' 符号来访问它们。
要在变量中存储命令和特殊字符,请使用包围整个变量文本的双引号,而不是分号和特殊符号前的反斜杠。
- 默认环境:
CFG_EXTRA_ENV_SETTINGS
定义此变量以包含任意数量的以空字符结尾的字符串(变量=值对),这些字符串将成为编译到引导镜像中的默认环境的一部分。
例如,在您的主板配置文件中放置如下内容:
#define CFG_EXTRA_ENV_SETTINGS \
"myvar1=value1\0" \
"myvar2=value2\0"
警告:此方法基于对 U-Boot 代码存储环境的内部格式的了解。这不是官方的、导出的接口!虽然这种格式不太可能很快改变,但也不保证。您最好知道您在这里做什么。
注意:不建议过度(滥用)默认环境。请务必检查其他预设环境的方法,如“source”命令或 boot 命令。
- 通过 TFTP 服务器自动软件更新
CONFIG_UPDATE_TFTP
CONFIG_UPDATE_TFTP_CNT_MAX
CONFIG_UPDATE_TFTP_MSEC_MAX
这些选项启用并控制自动更新功能;有关更详细的描述,请参阅 doc/README.update。
- MTD 支持(mtdparts 命令,UBI 支持)
CONFIG_MTD_UBI_WL_THRESHOLD
此参数定义 UBI 设备擦除块的最高擦除计数器值与最低擦除计数器值之间的最大差异。当超过此阈值时,UBI 开始通过将数据从擦除计数器低的擦除块移动到擦除计数器高的擦除块来执行磨损均衡。
对于 SLC NAND flash、NOR flash 和其他擦除块生命周期为 100000 或更多的 flash,默认值应该可以。
但是,对于擦除块生命周期通常小于 10000 的 MLC NAND flash,阈值应该减小(例如,减小到 128 或 256,尽管它不必是 2 的幂)。
默认值: 4096
CONFIG_MTD_UBI_BEB_LIMIT
此选项指定 UBI 在 MTD 设备上预期的最大坏物理擦除块(每 1024 个擦除块)。如果底层 flash 不允许坏擦除块(例如 NOR flash),则忽略此值。
NAND 数据手册通常指定 flash 耐久生命周期内的最小和最大 NVM(有效块数)。然后,每 1024 个擦除块的最大预期坏擦除块可以计算为“1024 * (1 - MinNVB / MaxNVB)”,对于大多数 NAND,这给出 20(MaxNVB 基本上是芯片上擦除块的总数)。
换句话说,如果此值为 20,UBI 将尝试为坏块处理保留约 1.9% 的物理擦除块。这将是整个 NAND 芯片上 1.9% 的擦除块,而不仅仅是 UBI 附加的 MTD 分区。这意味着如果您有一个允许最多 40 个坏擦除块的 NAND flash 芯片,并且它被分割成两个大小相同的 MTD 分区,UBI 在附加分区时将保留 40 个擦除块。
默认值: 20
CONFIG_MTD_UBI_FASTMAP
Fastmap 是一种允许在几乎恒定的时间内附加 UBI 设备的机制。它不必扫描整个 MTD 设备,而只需在设备上定位一个检查点(称为 fastmap)。On-flash fastmap 包含附加设备所需的所有信息。使用 fastmap 仅在通过扫描附加需要很长时间的大型设备上有意义。UBI 不会自动在旧镜像上安装 fastmap,但如果您希望如此,可以将 UBI 参数 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT 设置为 1。请注意,启用 fastmap 的镜像仍可与不支持 fastmap 的 UBI 实现一起使用。在典型的 flash 设备上,整个 fastmap 适合放入一个 PEB。UBI 将保留 PEB 以容纳两个 fastmap。
CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT
将此参数设置为在没有 fastmap 的镜像上自动启用 fastmap。
默认值: 0
CONFIG_MTD_UBI_FM_DEBUG
启用 UBI fastmap 调试
默认值: 0
- SPL 框架
CONFIG_SPL
全局启用 SPL 构建。
CONFIG_SPL_PANIC_ON_RAW_IMAGE
定义后,如果加载的镜像没有签名,SPL 将 panic()。
当 SPL 中加载镜像的代码不能保证绝对捕获所有读取错误时,定义此选项很有用。
一个例子是 LPC32XX MLC NAND 驱动程序,它将认为完全不可读的 NAND 块是坏的,因此应该静默跳过。
CONFIG_SPL_DISPLAY_PRINT
对于 ARM,启用一个可选函数以打印有关运行系统的更多信息。
CONFIG_SPL_MPC83XX_WAIT_FOR_NAND
为 PPC mpc83xx 目标上的 NAND SPL 设置此项,以便 start.S 等待 SPL 的其余部分加载后再继续(硬件在仅加载第一页而不是完整的 4K 后开始执行)。
CONFIG_SPL_UBI
支持轻量级 UBI (fastmap) 扫描器和加载器
CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_SIZE,
CONFIG_SYS_NAND_OOBSIZE, CONFIG_SYS_NAND_BLOCK_SIZE,
CONFIG_SYS_NAND_BAD_BLOCK_POS, CFG_SYS_NAND_ECCPOS,
CFG_SYS_NAND_ECCSIZE, CFG_SYS_NAND_ECCBYTES
定义 SPL 用来读取 U-Boot 的 NAND 的大小和行为
CFG_SYS_NAND_U_BOOT_DST
要将 U-Boot 加载到的内存位置
CFG_SYS_NAND_U_BOOT_SIZE
要加载的镜像大小
CFG_SYS_NAND_U_BOOT_START
要跳转到的已加载镜像中的入口点
CONFIG_SPL_RAM_DEVICE
支持在 SPL 二进制文件中运行已存在于 ram 中的镜像
CONFIG_SPL_FIT_PRINT
打印有关 FIT 镜像的信息会给 SPL 增加相当多的代码。因此这通常在 SPL 中禁用。使用此选项重新启用它。这将影响引导 FIT 镜像时 bootm 命令的输出。
- 中断支持 (PPC):
所有 PPC 架构都有通用的 interrupt_init() 和 timer_interrupt()。interrupt_init() 调用 interrupt_init_cpu() 进行 CPU 特定的初始化。interrupt_init_cpu() 应将 decrementer_count 设置为适当的值。如果 CPU 在中断后自动重置减法器(ppc4xx),则应将 decrementer_count 设置为零。timer_interrupt() 调用 timer_interrupt_cpu() 进行 CPU 特定的处理。如果主板有看门狗 / status_led / other_activity_monitor,它将从通用 timer_interrupt() 自动工作。
## 主板初始化设置:
在初始化期间,u-boot 调用许多主板特定的函数,以允许准备主板特定的先决条件,例如在驱动程序初始化之前的引脚设置。要启用这些回调,必须定义以下配置宏。目前这是架构特定的,所以请检查 arch/your_architecture/lib/board.c,通常在 board_init_f() 和 board_init_r() 中。
- CONFIG_BOARD_EARLY_INIT_F:调用 board_early_init_f()
- CONFIG_BOARD_EARLY_INIT_R:调用 board_early_init_r()
- CONFIG_BOARD_LATE_INIT:调用 board_late_init()
## 配置设置:
- CONFIG_SYS_LONGHELP:当您希望包含长帮助消息时定义;当内存不足时取消定义。
- CFG_SYS_HELP_CMD_WIDTH:当您希望覆盖 'help' 命令输出中列出的命令的默认宽度时定义。
- CONFIG_SYS_PROMPT: 这是 U-Boot 在控制台上打印以提示用户输入的内容。
- CFG_SYS_BAUDRATE_TABLE:
此主板的合法波特率设置列表。
- CFG_SYS_MEM_RESERVE_SECURE
目前仅为 ARMv8。
如果定义,CFG_SYS_MEM_RESERVE_SECURE 内存的大小将从总 RAM 中减去,并且不会报告给操作系统。
此内存可用作安全内存。变量
gd->arch.secure_ram 用于跟踪位置。在 RAM 基址不为零或 RAM 分为多组的系统中,需要重新计算此变量以获取地址。
- CFG_SYS_SDRAM_BASE:
SDRAM 的物理起始地址。此处 _必须_ 为 0。
- CFG_SYS_FLASH_BASE:
Flash 内存的物理起始地址。
- CONFIG_SYS_MALLOC_LEN:
为 malloc() 使用保留的 DRAM 大小。
- CFG_SYS_BOOTMAPSZ:
Linux 内核启动代码映射的最大内存大小;所有必须由 Linux 内核处理的数据(bd_info、引导参数、FDT blob(如果使用))必须放置在此限制之下,除非定义了“bootm_low”环境变量且非零。在这种情况下,Linux 内核的所有数据必须在“bootm_low”和“bootm_low” + CFG_SYS_BOOTMAPSZ 之间。环境变量“bootm_mapsize”将覆盖 CFG_SYS_BOOTMAPSZ 的值。如果 CFG_SYS_BOOTMAPSZ 未定义,则将使用“bootm_size”中的值。
- CONFIG_SYS_BOOT_GET_CMDLINE:
启用在“bootm_low”和“bootm_low” + BOOTMAPSZ 之间的空间中分配和保存内核命令行。
- CONFIG_SYS_BOOT_GET_KBD:
启用在“bootm_low”和“bootm_low” + BOOTMAPSZ 之间的空间中分配和保存 bd_info 的内核副本。
- CONFIG_SYS_FLASH_PROTECTION
如果定义,则使用硬件 flash 扇区保护,而不是 U-Boot 软件保护。
- CONFIG_SYS_FLASH_CFI:
如果 flash 驱动程序在通用 flash 结构中使用额外元素来存储 flash 几何结构,则定义。
- CONFIG_FLASH_CFI_DRIVER
此选项也启用在 drivers 目录中构建 cfi_flash 驱动程序
- CONFIG_FLASH_CFI_MTD
此选项启用在 drivers 目录中构建 cfi_mtd 驱动程序。该驱动程序将 CFI flash 导出到 MTD 层。
- CONFIG_SYS_FLASH_USE_BUFFER_WRITE
使用缓冲写入 flash。
- CONFIG_ENV_FLAGS_LIST_DEFAULT
- CFG_ENV_FLAGS_LIST_STATIC
在调用 env set 时启用对赋予环境变量的值的验证。变量可以限制为仅十进制、十六进制或布尔值。如果还定义了 CONFIG_CMD_NET,则变量还可以限制为 IP 地址或 MAC 地址。
列表的格式是:
type_attribute = [s|d|x|b|i|m]
access_attribute = [a|r|o|c]
attributes = type_attribute[access_attribute]
entry = variable_name[:attributes]
list = entry[,list]
类型属性是:
s - 字符串(默认)
d - 十进制
x - 十六进制
b - 布尔值 ([1yYtT|0nNfF])
i - IP 地址
m - MAC 地址
访问属性是:
a - 任意(默认)
r - 只读
o - 写一次
c - 更改默认值
- CONFIG_ENV_FLAGS_LIST_DEFAULT
将此定义为列表(字符串),以在默认或嵌入式环境中定义“.flags”环境变量。
- CFG_ENV_FLAGS_LIST_STATIC
将此定义为列表(字符串),以定义如果在“.flags”环境变量中找不到条目时应进行的验证。要覆盖静态列表中的设置,只需将同一变量名的条目添加到“.flags”变量中。
如果定义了 CONFIG_REGEX,则上面的 variable_name 将作为正则表达式求值。这允许多个变量定义相同的标志,而无需为每个变量显式列出它们。
以下定义涉及环境数据(变量区域)的放置和管理;通常,我们支持以下配置:
小心!对环境的第一次访问发生在 U-Boot 初始化的早期(当我们尝试获取控制台波特率的设置时)。您*必须*在那时映射您的 NVRAM 区域,否则 U-Boot 将挂起。
请注意,即使使用 NVRAM,我们仍然在 RAM 中使用环境的副本:我们可以直接在 NVRAM 上工作,但我们希望那里的设置始终不被修改,除非有人使用“saveenv”保存当前设置。
小心!对于某些特殊情况,本地设备不能使用“saveenv”命令。例如,本地设备将通过 SRIO 或 PCIE 链接获取存储在远程 NOR flash 中的环境,但它无法通过 SRIO 或 PCIE 接口擦除、写入此 NOR flash。
- CONFIG_NAND_ENV_DST
定义 nand_spl 代码应将环境复制到的 RAM 中的地址。如果使用冗余环境,它将被复制到 CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE。
请注意,环境是只读的,直到监视器已重定位到 RAM 并且已创建环境的 RAM 副本;此外,在使用 EEPROM 时,在此之前您必须使用 env_get_f() 来读取环境变量。
环境受 CRC32 校验和保护。在监视器重定位到 RAM 之前,由于 CRC 错误,您将使用编译进的默认环境 - *静默地*!!![这是必要的,因为我们需要的第一个环境变量是控制台的“baudrate”设置 - 如果我们的 CRC 错误,我们还没有任何可以投诉的设备。]
注意:一旦监视器被重定位,如果使用默认环境,它将发出警告;一旦您使用“saveenv”命令存储有效环境,就会计算新的 CRC。
- CONFIG_DISPLAY_BOARDINFO
显示 U-Boot 正在运行的主板的信息当 U-Boot 启动时。主板函数 checkboard() 被调用以执行此操作。
- CONFIG_DISPLAY_BOARDINFO_LATE
与前一个选项类似,但稍后显示此信息,一旦 stdio 运行并且输出转到 LCD(如果存在)。
## 低级(硬件相关)配置选项:
- CONFIG_SYS_CACHELINE_SIZE:
CPU 的缓存行大小。
- CONFIG_SYS_CCSRBAR_DEFAULT:
Freescale PowerPC SOC 上 CCSR 的默认(上电复位)物理地址。
- CFG_SYS_CCSRBAR:
CCSR 的虚拟地址。在 32 位构建中,这通常是
与 CONFIG_SYS_CCSRBAR_DEFAULT 相同的值。
- CFG_SYS_CCSRBAR_PHYS:
CCSR 的物理地址。如果需要,可以将 CCSR 重定位到新的物理地址。在这种情况下,此宏应设置为该地址。否则,应将其设置为与 CONFIG_SYS_CCSRBAR_DEFAULT 相同的值。例如,CCSR 通常在 36 位构建中重定位。建议通过 _HIGH 和 _LOW 宏定义此宏:
#define CFG_SYS_CCSRBAR_PHYS ((CFG_SYS_CCSRBAR_PHYS_HIGH
* 1ull) << 32 | CFG_SYS_CCSRBAR_PHYS_LOW)
- CFG_SYS_CCSRBAR_PHYS_HIGH:
CFG_SYS_CCSRBAR_PHYS 的第 33-36 位。此值通常是 0(32 位构建)或 0xF(36 位构建)。此宏用于汇编代码,因此它不得包含类型转换或整数大小后缀(例如“ULL”)。
- CFG_SYS_CCSRBAR_PHYS_LOW:
CFG_SYS_CCSRBAR_PHYS 的低 32 位。此宏用于汇编代码,因此它不得包含类型转换或整数大小后缀(例如“ULL”)。
- CONFIG_SYS_IMMR: 内部存储器的物理地址。
除非您确切知道自己在做什么,否则不要更改! (11-4) [仅限 MPC8xx 系统]
- CFG_SYS_INIT_RAM_ADDR:
可用于初始数据和栈的内存区域的起始地址;请注意,这必须是无需特殊初始化即可工作的可写内存,即您不能使用只有在编程内存控制器并运行某些初始化序列后才可用的普通 RAM。
U-Boot 使用以下内存类型:
- MPC8xx: IMMR (CPU 的内部内存)
- CONFIG_SYS_SCCR: 系统时钟和复位控制寄存器 (15-27)
- CONFIG_SYS_OR_TIMING_SDRAM:
SDRAM 时序
- CONFIG_SYS_SRIOn_MEM_VIRT:
SRIO 端口 'n' 内存区域的虚拟地址
- CONFIG_SYS_SRIOn_MEM_PHYxS:
SRIO 端口 'n' 内存区域的物理地址
- CONFIG_SYS_SRIOn_MEM_SIZE:
SRIO 端口 'n' 内存区域的大小
- CONFIG_SYS_NAND_BUSWIDTH_16BIT
定义此选项以告诉 NAND 控制器 NAND 芯片使用 16 位总线。
并非所有 NAND 驱动程序都使用此符号。
使用它的驱动程序示例:
- drivers/mtd/nand/raw/ndfc.c
- drivers/mtd/nand/raw/mxc_nand.c
- CONFIG_SYS_NDFC_EBC0_CFG
设置 NDFC 的 EBC0_CFG 寄存器。如果未定义将使用默认值。
- CONFIG_SYS_SPD_BUS_NUM
如果 SPD EEPROM 位于第一个 I2C 总线以外的总线上,请在此处指定。请注意,该值必须解析为您的驱动程序可以处理的内容。
- CONFIG_FSL_DDR_INTERACTIVE
启用交互式 DDR 调试。请参阅 doc/README.fsl-ddr。
- CONFIG_FSL_DDR_SYNC_REFRESH
启用多控制器的刷新同步。
- CONFIG_FSL_DDR_BIST
启用 Freescale DDR 控制器的内置内存测试。
- CONFIG_RMII
为所有 FEC 启用 RMII 模式。
请注意,这是一个全局选项,我们不能
让一个 FEC 处于标准 MII 模式而另一个处于 RMII 模式。
- CONFIG_CRC32_VERIFY
向 crc32 命令添加验证选项。
语法是:
=> crc32 -v
其中 address/count 指示内存区域,而 crc32 是该区域应具有的正确 crc32。
- CONFIG_LOOPW
添加“loopw”内存命令。这仅在全局激活内存命令 (CONFIG_CMD_MEMORY) 时生效。
- CONFIG_CMD_MX_CYCLIC
添加“mdc”和“mwc”内存命令。这些是循环“md/mw”命令。
示例:
=> mdc.b 10 4 500
此命令将每 500ms 打印 4 个字节 (10,11,12,13)。
=> mwc.l 100 12345678 10
此命令将每 10ms 向地址 100 写入 12345678。
这仅在全局激活内存命令 (CONFIG_CMD_MEMORY) 时生效。
- CONFIG_XPL_BUILD
当当前正在进行的编译是针对将在某个 'xPL' 构建中结束的构件时设置,即 SPL, TPL 或 VPL。需要特定阶段行为的代码可以检查此选项,或者(在可能的情况下)改用 xpl_phase()。
- CONFIG_TPL_BUILD
当当前正在进行的编译是针对将在 TPL 构建中结束的构件时设置(相对于 SPL, VPL 或 U-Boot proper)。需要特定阶段行为的代码可以检查此选项,或者(在可能的情况下)改用 xpl_phase()。
- CONFIG_VPL_BUILD
当当前正在进行的编译是针对将在 VPL 构建中结束的构件时设置(相对于 SPL, TPL 或 U-Boot proper)。需要特定阶段行为的代码可以检查此选项,或者(在可能的情况下)改用 xpl_phase()。
- CONFIG_ARCH_MAP_SYSMEM
通常,U-Boot(特别是 md 命令)使用有效地址。因此,无需将 U-Boot 地址视为需要转换为物理地址的虚拟地址。但是,sandbox 需要此功能,因为它维护自己的小 RAM 缓冲区,其中包含所有可寻址内存。此选项导致某些内存访问通过 map_sysmem() / unmap_sysmem() 进行映射。
- CONFIG_X86_RESET_VECTOR
如果定义,则包含 x86 复位向量代码。当 U-Boot 从 Coreboot 运行时不需要此代码。
## Freescale QE/FMAN 固件支持:
Freescale QUICCEngine (QE) 和 Frame Manager (FMAN) 都支持加载“固件”,该固件以 QE 固件二进制格式编码。此固件通常需要在 U-Boot 引导期间加载,因此宏用于标识存储设备(NOR flash、SPI 等)以及该设备内的地址。
- CONFIG_SYS_FMAN_FW_ADDR
FMAN 微代码在存储设备中的地址。此地址的含义取决于还指定了哪个 CONFIG_SYS_QE_FMAN_FW_IN_xxx 宏。
- CONFIG_SYS_QE_FW_ADDR
QE 微代码在存储设备中的地址。此地址的含义取决于还指定了哪个 CONFIG_SYS_QE_FMAN_FW_IN_xxx 宏。
- CONFIG_SYS_QE_FMAN_FW_LENGTH
固件的最大可能大小。固件二进制格式有一个指定固件实际大小的字段,但除非首先分配一些本地存储来保存整个固件,否则可能无法读取固件的任何部分。
- CONFIG_SYS_QE_FMAN_FW_IN_NOR
指定 QE/FMAN 固件位于 NOR flash 中,通过 LBC 映射为普通可寻址内存。CONFIG_SYS_FMAN_FW_ADDR 是 NOR flash 中的虚拟地址。
- CONFIG_SYS_QE_FMAN_FW_IN_NAND
指定 QE/FMAN 固件位于 NAND flash 中。
CONFIG_SYS_FMAN_FW_ADDR 是 NAND flash 内的偏移量。
- CONFIG_SYS_QE_FMAN_FW_IN_MMC
指定 QE/FMAN 固件位于主 SD/MMC 设备上。CONFIG_SYS_FMAN_FW_ADDR 是该设备上的字节偏移量。
- CONFIG_SYS_QE_FMAN_FW_IN_REMOTE
指定 QE/FMAN 固件位于远程(主)内存空间中。CONFIG_SYS_FMAN_FW_ADDR 是一个虚拟地址,可以从从机 TLB->从机 LAW->从机 SRIO 或 PCIE 出站窗口->主机入站窗口->主机 LAW->主机内存空间微代码地址进行映射。
## Freescale Layerscape Management Complex 固件支持:
Freescale Layerscape Management Complex (MC) 支持加载“固件”。
此固件通常需要在 U-Boot 引导期间加载,因此宏用于标识存储设备(NOR flash、SPI 等)以及该设备内的地址。
- CONFIG_FSL_MC_ENET
为 Layerscape SoC 启用 MC 驱动程序。
## Freescale Layerscape 调试服务器支持:
Freescale Layerscape 调试服务器支持支持加载“调试服务器固件”并触发 SP boot-rom。
此固件通常需要在 U-Boot 引导期间加载。
- CONFIG_SYS_MC_RSV_MEM_ALIGN
定义 MC 所需的保留内存的对齐方式
# 构建软件:
已在多个原生构建环境和许多不同的交叉环境中测试了 U-Boot 的构建。当然,我们不能支持所有(可能已过时)版本的所有可能存在的交叉开发工具版本。如果遇到工具链问题,我们建议使用 ELDK(请参阅 https://www.denx.de/wiki/DULG/ELDK),该工具被广泛用于构建和测试 U-Boot。
如果您使用的不是原生环境,则假定您的路径中有 GNU 交叉编译工具。在这种情况下,您必须在 shell 中设置环境变量 CROSS_COMPILE。
请注意,不需要对 Makefile 或任何其他源文件进行更改。例如,在 4xx CPU 上使用 ELDK,请输入:
```
$ CROSS_COMPILE=ppc_4xx-
$ export CROSS_COMPILE
```
U-Boot 旨在易于构建。安装源代码后,您必须为一种特定的主板类型配置 U-Boot。这是通过键入以下内容完成的:
```
make NAME_defconfig
```
其中“NAME_defconfig”是现有配置之一的名称;有关支持的名称,请参阅 configs/*_defconfig。
注意:对于某些主板,可能存在特殊的配置名称;检查主板供应商是否提供了附加信息;例如,TQM823L 系统有不带(标准)或带 LCD 支持的版本。在选择配置时,您可以选择此类附加“功能”,即
```
make TQM823L_defconfig
- will configure for a plain TQM823L, i. e. no LCD support
make TQM823L_LCD_defconfig
- will configure for a TQM823L with U-Boot console on LCD
etc.
```
最后,键入“make all”,您应该会得到一些可以下载到/安装到系统上的可用 U-Boot 镜像:
- “u-boot.bin”是原始二进制镜像
- “u-boot”是 ELF 二进制格式的镜像
- “u-boot.srec”是 Motorola S-Record 格式
可以通过设置相应的环境变量 KCPPFLAGS、KAFLAGS 和 KCFLAGS 将用户特定的 CPPFLAGS、AFLAGS 和 CFLAGS 传递给编译器。
例如,将所有编译器警告视为错误:
```
make KCFLAGS=-Werror
```
请注意,Makefile 假定您使用的是 GNU make,因此例如在 NetBSD 上,您可能需要使用“gmake”而不是原生的“make”。
如果您拥有的系统主板未列出,那么您需要将 U-Boot 移植到您的硬件平台。为此,请按照下列步骤操作:
1. 创建一个新目录来保存您的主板特定代码。添加您需要的任何文件。在您的主板目录中,您至少需要“Makefile”和“.c”。
2. 为您的主板创建一个新的配置文件“include/configs/.h”。
3. 如果您要将 U-Boot 移植到新的 CPU,那么还要创建一个新目录来保存您的 CPU 特定代码。添加您需要的任何文件。
4. 使用您的新名称运行“make _defconfig”。
5. 键入“make”,您应该会得到一个可以安装在目标系统上的可用“u-boot.srec”文件。
6. 调试并解决可能出现的任何问题。
[当然,这最后一步比听起来要难得多。]
# 测试 U-Boot 修改、移植到新硬件等:
如果您修改了 U-Boot 源代码(例如添加了新主板或对新设备、新 CPU 等的支持),则应向其他开发人员提供反馈。反馈通常采用“补丁”的形式,即针对特定(最新官方或 git 仓库中最新)版本的 U-Boot 源代码的上下文差异。
但在提交此类补丁之前,请验证您的修改没有破坏现有代码。至少确保*所有*支持的主板在编译时没有任何编译器警告。为此,只需运行 buildman 脚本,该脚本将为所有受支持的系统配置和构建 U-Boot。请注意,这将需要一段时间。请参阅 buildman README,或运行 'buildman -H' 获取文档。
另请参阅下面的“U-Boot 移植指南”。
# 监视器命令 - 概述:
go - 在地址 'addr' 处启动应用程序
run - 运行环境变量中的命令
bootm - 从内存引导应用程序镜像
bootp - 使用 BootP/TFTP 协议通过网络引导镜像
bootz - 从内存引导 zImage
tftpboot- 使用 TFTP 协议通过网络引导镜像并使用环境变量“ipaddr”和“serverip”(以及最终的“gatewayip”)
tftpput - 使用 TFTP 协议通过网络上传文件
rarpboot- 使用 RARP/TFTP 协议通过网络引导镜像
diskboot- 从 IDE 设备引导bootd - 引导默认值,即运行 'bootcmd'
loads - 通过串行线加载 S-Record 文件
loadb - 通过串行线加载二进制文件(kermit 模式)
loadm - 将二进制 blob 从源地址加载到目标地址
md - 内存显示
mm - 内存修改(自动递增)
nm - 内存修改(恒定地址)
mw - 内存写入(填充)
ms - 内存搜索
cp - 内存复制
cmp - 内存比较
crc32 - 校验和计算
i2c - I2C 子系统
sspi - SPI 实用程序命令
base - 打印或设置地址偏移量
printenv- 打印环境变量
pwm - 控制 pwm 通道
seama - 加载 SEAMA NAND 镜像
setenv - 设置环境变量
saveenv - 将环境变量保存到持久存储
protect - 启用或禁用 FLASH 写保护
erase - 擦除 FLASH 内存
flinfo - 打印 FLASH 内存信息
nand - NAND 内存操作(请参阅 doc/README.nand)
bdinfo - 打印主板信息结构
iminfo - 打印应用程序镜像的头信息
coninfo - 打印控制台设备和信息
ide - IDE 子系统
loop - 地址范围上的无限循环
loopw - 地址范围上的无限写入循环
mtest - 简单的 RAM 测试
icache - 启用或禁用指令缓存
dcache - 启用或禁用数据缓存
reset - 执行 CPU 复位
echo - 将参数回显到控制台
version - 打印监视器版本
help - 打印在线帮助
? - 'help' 的别名
# 监视器命令 - 详细说明:
待办。
目前:只需键入“help ”。
# 冗余以太网接口说明:
某些主板带有冗余以太网接口;U-Boot 支持此类配置,并能在需要时自动选择“工作”接口。MAC 分配工作如下:
网络接口编号为 eth0, eth1, eth2, ... 相应的 MAC 地址可以作为“ethaddr”(=>eth0)、“eth1addr”(=>eth1)、“eth2addr”... 存储在环境中。
如果网络接口存储了一些有效的 MAC 地址(例如在 SROM 中),并且环境中没有相应的设置,则将其用作默认地址;如果设置了相应的环境变量,这将覆盖卡中的设置;这意味着:
o 如果 SROM 具有有效的 MAC 地址,并且环境中没有地址,则使用 SROM 的地址。
o 如果 SROM 中没有有效地址,并且环境中存在定义,则使用环境变量中的值。
o 如果 SROM 和环境都包含 MAC 地址,并且两个地址相同,则使用此 MAC 地址。
o 如果 SROM 和环境都包含 MAC 地址,并且地址不同,则使用环境中的值并打印警告。
o 如果 SROM 和环境都不包含 MAC 地址,则会引发错误。如果定义了 CONFIG_NET_RANDOM_ETHADDR,则在这种情况下使用随机的、本地分配的 MAC。
如果以太网驱动程序实现 'write_hwaddr' 函数,有效的 MAC 地址将作为初始化过程的一部分编程到硬件中。这可以通过设置相应的 'ethmacskip' 环境变量来跳过。
命名约定如下:
“ethmacskip”(=>eth0)、“eth1macskip”(=>eth1)等。
# 镜像格式:
U-Boot 能够引导(并执行其他辅助操作)两种格式的镜像:
## 新 uImage 格式 (FIT)
基于扁平化镜像树 -- FIT 的灵活强大格式(类似于扁平化设备树)。它允许使用具有多个组件(多个内核、ramdisk 等)的镜像,其内容受 SHA1、MD5 或 CRC32 保护。更多详细信息请参见 doc/uImage.FIT 目录。
## 旧 uImage 格式
旧镜像格式基于二进制文件,基本上可以是任何内容,前面有一个特殊的头;有关详细信息,请参阅 include/image.h 中的定义;基本上,该头定义了以下镜像属性:
* 目标操作系统(为 OpenBSD, NetBSD, FreeBSD, 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, INTEGRITY 做了准备;目前支持:Linux, NetBSD, VxWorks, QNX, RTEMS, INTEGRITY)。
* 目标 CPU 架构(为 Alpha, ARM, Intel x86, IA64, MIPS, Nios II, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit 做了准备;目前支持:ARM, Intel x86, MIPS, Nios II, PowerPC)。
* 压缩类型(未压缩, gzip, bzip2)
* 加载地址
* 入口点
* 镜像名称
* 镜像时间戳
该头标有特殊的幻数,并且镜像的头和数据部分都通过 CRC32 校验和进行防篡改保护。
# Linux 支持:
尽管 U-Boot 应该轻松支持任何操作系统或独立应用程序,但在 U-Boot 的设计过程中,主要重点一直是 Linux。
U-Boot 包含许多目前属于 Linux 内核中某些特殊“引导加载程序”代码的功能。此外,任何要使用的“initrd”镜像不再是大型 Linux 镜像的一部分;相反,内核和“initrd”是分开的镜像。此实现有几个目的:
- 相同的功能可用于其他操作系统或独立应用程序(例如:使用压缩镜像减少 Flash 内存占用)
- 移植新的 Linux 内核版本变得更加容易,因为许多低级、依赖于硬件的工作都由 U-Boot 完成
- 现在可以将相同的 Linux 内核镜像与不同的“initrd”镜像一起使用;当然,这也意味着可以使用同一个“initrd”运行不同的内核镜像。这使得测试更容易(您只需更改“initrd”中的一个文件时,不必构建新的“zImage.initrd”Linux 镜像)。此外,现在软件的现场升级也更容易。
# Linux HOWTO:
## 将 Linux 移植到基于 U-Boot 的系统:
U-Boot 无法免除您进行所有必要的修改以配置 Linux 设备驱动程序供目标硬件使用的责任(不,我们不打算向 Linux 提供完整的虚拟机接口 :-).
但现在您可以忽略所有引导加载程序代码(在 arch/powerpc/mbxboot 中)。
只需确保您的机器特定头文件(例如 include/asm-ppc/tqm8xx.h)包含与我们在此定义的主板信息结构相同的定义 include/asm-/u-boot.h,并确保您的 IMAP_ADDR 定义使用与您的 U-Boot 配置中 CONFIG_SYS_IMMR 相同的值。
请注意,U-Boot 现在具有驱动程序模型,这是一个统一的驱动程序模型。如果您要添加新驱动程序,请将其插入驱动程序模型。如果没有可用的 uclass,建议您创建一个。请参阅 doc/driver-model。
## 配置 Linux 内核:
对 U-Boot 没有特定要求。确保您的目标系统有一些根设备(初始 ramdisk, NFS)。
## 构建 Linux 镜像:
使用 U-Boot,不使用像“zImage”或“bzImage”这样的“普通”构建目标。如果您使用最新的内核源代码,将存在一个新的构建目标“uImage”,它会自动构建 U-Boot 可用的镜像。大多数较旧的内核也支持“pImage”目标,该目标是为我们的前身项目 PPCBoot 引入的,并使用 100% 兼容的格式。
示例:
```
make TQM850L_defconfig
make oldconfig
make dep
make uImage
```
“uImage”构建目标使用一个特殊的工具(在 'tools/mkimage' 中)将压缩的 Linux 内核镜像封装为带有头信息、CRC32 校验和等的镜像,供 U-Boot 使用。这就是我们要做的:
* 构建标准的“vmlinux”内核镜像(ELF 二进制格式):
* 将内核转换为原始二进制镜像:
${CROSS_COMPILE}-objcopy -O binary \
-R .note -R .comment \
-S vmlinux linux.bin
* 压缩二进制镜像:
gzip -9 linux.bin
* 为 U-Boot 打包压缩的二进制镜像:
mkimage -A ppc -O linux -T kernel -C gzip \
-a 0 -e 0 -n "Linux Kernel Image" \
-d linux.gz uImage
“mkimage”工具也可用于创建与 U-Boot 一起使用的 ramdisk 镜像,既可以与 Linux 内核镜像分离,也可以合并到一个文件中。“mkimage”使用 64 字节的头封装镜像,其中包含有关目标架构、操作系统、镜像类型、压缩方法、入口点、时间戳、CRC32 校验和等的信息。
可以通过两种方式调用“mkimage”:验证现有镜像并打印头信息,或构建新镜像。
在第一种形式中(带有“-l”选项),mkimage 列出包含在现有 U-Boot 镜像头中的信息;这包括校验和验证:
```
tools/mkimage -l image
-l ==> list image header information
```
第二种形式(带有“-d”选项)用于从用作镜像有效负载的“数据文件”构建 U-Boot 镜像:
```
tools/mkimage -A arch -O os -T type -C comp -a addr -e ep \
-n name -d data_file image
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
```
目前,所有用于 PowerPC 系统的 Linux 内核都使用相同的加载地址 (0x00000000),但入口点地址取决于内核版本:
- 2.2.x 内核的入口点在 0x0000000C,
- 2.3.x 及更高版本内核的入口点在 0x00000000。
因此,构建 U-Boot 镜像的典型调用如下:
```
-> tools/mkimage -n '2.4.4 kernel for TQM850L' \
> -A ppc -O linux -T kernel -C gzip -a 0 -e 0 \
> -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux.gz \
> examples/uImage.TQM850L
Image Name: 2.4.4 kernel for TQM850L
Created: Wed Jul 19 02:34:59 2000
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 335725 Bytes = 327.86 kB = 0.32 MB
Load Address: 0x00000000
Entry Point: 0x00000000
```
要验证镜像的内容(或检查是否损坏):
```
-> tools/mkimage -l examples/uImage.TQM850L
Image Name: 2.4.4 kernel for TQM850L
Created: Wed Jul 19 02:34:59 2000
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 335725 Bytes = 327.86 kB = 0.32 MB
Load Address: 0x00000000
Entry Point: 0x00000000
```
注意:对于引导时间至关重要的嵌入式系统,您可以用速度换取内存,并安装一个未压缩的镜像:这需要更多的 Flash 空间,但引导速度要快得多,因为它不需要解压缩:
```
-> gunzip /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux.gz
-> tools/mkimage -n '2.4.4 kernel for TQM850L' \
> -A ppc -O linux -T kernel -C none -a 0 -e 0 \
> -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux \
> examples/uImage.TQM850L-uncompressed
Image Name: 2.4.4 kernel for TQM850L
Created: Wed Jul 19 02:34:59 2000
Image Type: PowerPC Linux Kernel Image (uncompressed)
Data Size: 792160 Bytes = 773.59 kB = 0.76 MB
Load Address: 0x00000000
Entry Point: 0x00000000
```
同样,当您的内核打算使用初始 ramdisk 时,您可以从 'ramdisk.image.gz' 文件构建 U-Boot 镜像:
```
-> tools/mkimage -n 'Simple Ramdisk Image' \
> -A ppc -O linux -T ramdisk -C gzip \
> -d /LinuxPPC/images/SIMPLE-ramdisk.image.gz examples/simple-initrd
Image Name: Simple Ramdisk Image
Created: Wed Jan 12 14:01:50 2000
Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
Data Size: 566530 Bytes = 553.25 kB = 0.54 MB
Load Address: 0x00000000
Entry Point: 0x00000000
```
“dumpimage”工具可用于反汇编或列出由 mkimage 构建的镜像的内容。有关详细信息,请参阅 dumpimage 的帮助输出。
## 安装 Linux 镜像:
要通过串行(控制台)接口下载 U-Boot 镜像,必须将镜像转换为 S-Record 格式:
```
objcopy -I binary -O srec examples/image examples/image.srec
```
'objcopy' 不理解 U-Boot 镜像头中的信息,因此生成的 S-Record 文件将相对于地址 0x00000000。要将其加载到给定地址,您需要在 'loads' 命令中将目标地址指定为 'offset' 参数。
示例:将镜像安装到地址 0x40100000(在 TQM8xxL 上位于第一个 Flash 存储体中):
```
=> erase 40100000 401FFFFF
.......... done
Erased 8 sectors
=> loads 40100000
## 准备进行 S-Record 下载 ...
~>examples/image.srec
1 2 3 4 5 6 7 8 9 10 11 12 13 ...
...
15989 15990 15991 15992
[file transfer complete]
[connected]
## 起始地址 = 0x00000000
```
您可以使用 'iminfo' 命令检查下载是否成功;这包括校验和验证,因此您可以确信没有发生数据损坏:
```
=> imi 40100000
## 正在检查位于 40100000 的镜像 ...
Image Name: 2.2.13 for initrd on TQM850L
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 335725 Bytes = 327 kB = 0 MB
Load Address: 00000000
Entry Point: 0000000c
Verifying Checksum ... OK
```
## 引导 Linux:
“bootm”命令用于引导存储在内存(RAM 或 Flash)中的应用程序。对于 Linux 内核镜像,“bootargs”环境变量的内容作为参数传递给内核。您可以使用“printenv”和“setenv”命令检查和修改此变量:
```
=> printenv bootargs
bootargs=root=/dev/ram
=> setenv bootargs root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
=> printenv bootargs
bootargs=root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
=> bootm 40020000
## 正在于 40020000 启动 Linux 内核 ...
Image Name: 2.2.13 for NFS on TQM850L
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 381681 Bytes = 372 kB = 0 MB
Load Address: 00000000
Entry Point: 0000000c
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:35:17 MEST 2000
Boot arguments: root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
time_init: decrementer frequency = 187500000/60
Calibrating delay loop... 49.77 BogoMIPS
Memory: 15208k available (700k kernel code, 444k data, 32k init) [c0000000,c1000000]
...
```
如果您想引导带有初始 RAM 磁盘的 Linux 内核,则将内核和 initrd 镜像(PPBCOOT 格式!)的内存地址传递给“bootm”命令:
```
=> imi 40100000 40200000
## 正在检查位于 40100000 的镜像 ...
Image Name: 2.2.13 for initrd on TQM850L
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 335725 Bytes = 327 kB = 0 MB
Load Address: 00000000
Entry Point: 0000000c
Verifying Checksum ... OK
## 正在检查位于 40200000 的镜像 ...
Image Name: Simple Ramdisk Image
Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
Data Size: 566530 Bytes = 553 kB = 0 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
=> bootm 40100000 40200000
## 正在于 40100000 启动 Linux 内核 ...
Image Name: 2.2.13 for initrd on TQM850L
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 335725 Bytes = 327 kB = 0 MB
Load Address: 00000000
Entry Point: 0000000c
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
## 正在于 40200000 加载 RAMDisk 镜像 ...
Image Name: Simple Ramdisk Image
Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
Data Size: 566530 Bytes = 553 kB = 0 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Loading Ramdisk ... OK
Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:32:08 MEST 2000
Boot arguments: root=/dev/ram
time_init: decrementer frequency = 187500000/60
Calibrating delay loop... 49.77 BogoMIPS
...
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem).
bash#
```
## 引导 Linux 并传递扁平化设备树:
首先,U-Boot 必须使用适当的定义进行编译。有关更深入的解释,请参阅上面标题为“Linux 内核接口”的部分。以下是如何启动内核并传递更新的扁平化设备树的示例:
=> print oftaddr
oftaddr=0x300000
=> print oft
oft=oftrees/mpc8540ads.dtb
=> tftp $oftaddr $oft
Speed: 1000, full duplex
Using TSEC0 device
TFTP from server 192.168.1.1; our IP address is 192.168.1.101
Filename 'oftrees/mpc8540ads.dtb'.
Load address: 0x300000
Loading: #
done
Bytes transferred = 4106 (100a hex)
=> tftp $loadaddr $bootfile
Speed: 1000, full duplex
Using TSEC0 device
TFTP from server 192.168.1.1; our IP address is 192.168.1.2
Filename 'uImage'.
加载地址:0x200000
正在加载:############
完成
传输字节数 = 1029407 (fb51f hex)
=> print loadaddr
loadaddr=200000
=> print oftaddr
oftaddr=0x300000
=> bootm $loadaddr - $oftaddr
## 正在引导位于 00200000 的镜像 ...
镜像名称: Linux-2.6.17-dirty
镜像类型: PowerPC Linux 内核镜像 (gzip 压缩)
数据大小: 1029343 字节 = 1005.2 kB
加载地址: 00000000
入口点: 00000000
校验和验证 ... 正确
内核镜像解压中 ... 正确
使用位于 0x300000 的扁平设备树引导
使用 MPC85xx ADS 机器描述
内存 CAM 映射:CAM0=256Mb, CAM1=256Mb, CAM2=0Mb 剩余:0Mb
[省略]
## 关于 U-Boot 镜像类型的更多信息:
U-Boot 支持以下镜像类型:
"独立程序" 可直接在 U-Boot 提供的环境中运行;预期(如果它们行为正常)从独立程序返回后,您可以继续在 U-Boot 中工作。
"OS 内核镜像" 通常是某些嵌入式 OS 的镜像,它们将完全接管控制权。通常,这些程序将安装它们自己的异常处理程序集、设备驱动程序,设置 MMU 等 —— 这意味着,除非复位 CPU,否则您无法期望重新进入 U-Boot。
"RAMDisk 镜像" 或多或少只是数据块,其参数(地址、大小)被传递给正在启动的 OS 内核。
"多文件镜像" 包含多个镜像,通常是一个 OS(Linux)内核镜像和一个或多个数据镜像(如 RAMDisk)。这种结构在某些情况下非常有用,例如当您想通过 BOOTP 等协议通过网络引导时,引导服务器仅提供单个镜像文件,但您希望获取例如一个 OS 内核和一个 RAMDisk 镜像。
```
"Multi-File Images" start with a list of image sizes, each
image size (in bytes) specified by an "uint32_t" in network
byte order. This list is terminated by an "(uint32_t)0".
Immediately after the terminating 0 follow the images, one by
one, all aligned on "uint32_t" boundaries (size rounded up to
a multiple of 4 bytes).
```
"固件镜像" 是包含固件(如 U-Boot 或 FPGA 镜像)的二进制镜像,通常会被烧写到 flash 内存中。
"脚本文件" 是将由 U-Boot 命令解释器执行的命令序列;当您将 U-Boot 配置为使用真实 shell (hush) 作为命令解释器时,此功能尤为有用。
## 引导 Linux zImage:
在某些平台上,可以引导 Linux zImage。这是通过 "bootz" 命令完成的。"bootz" 命令的语法与 "bootm" 命令的语法相同。
注意,定义 CONFIG_SUPPORT_RAW_INITRD 允许用户向内核提供原始 initrd 镜像。其语法略有不同,initrd 的地址必须加上其大小,格式如下:":"。
# 独立程序 HOWTO:
U-Boot 的功能之一是您可以动态加载和运行“独立”应用程序,这些程序可以使用 U-Boot 的一些资源,如控制台 I/O 函数或中断服务。
源代码中包含两个简单的示例:
## "Hello World" 演示:
'examples/hello_world.c' 包含一个小型的 "Hello World" 演示应用程序;它在您构建 U-Boot 时自动编译。
它被配置为在地址 0x00040004 处运行,因此您可以像这样操作它:
```
=> loads
## 准备进行 S-Record 下载 ...
~>examples/hello_world.srec
1 2 3 4 5 6 7 8 9 10 11 ...
[file transfer complete]
[connected]
## 起始地址 = 0x00040004
=> go 40004 Hello World! This is a test.
## 正在于 0x00040004 启动应用程序 ...
Hello World
argc = 7
argv[0] = "40004"
argv[1] = "Hello"
argv[2] = "World!"
argv[3] = "This"
argv[4] = "is"
argv[5] = "a"
argv[6] = "test."
argv[7] = ""
Hit any key to exit ...
## 应用程序已终止,rc = 0x0
```
另一个示例演示了如何向 U-Boot 代码注册 CPM 中断处理程序,可以在 'examples/timer.c' 中找到。在这里,一个 CPM 定时器被设置为每秒产生一次中断。中断服务程序非常简单,仅打印一个 '.' 字符,但这只是一个演示程序。该应用程序可以通过以下按键控制:
```
? - print current values og the CPM Timer registers
b - enable interrupts and start timer
e - stop timer and disable interrupts
q - quit application
=> loads
## 准备进行 S-Record 下载 ...
~>examples/timer.srec
1 2 3 4 5 6 7 8 9 10 11 ...
[file transfer complete]
[connected]
## 起始地址 = 0x00040004
=> go 40004
## 正在于 0x00040004 启动应用程序 ...
TIMERS=0xfff00980
Using timer 1
tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0
```
按 'b':
[q, b, e, ?] 设置间隔 1000000 us
启用定时器
按 '?':
[q, b, e, ?] ........
tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0
按 '?':
[q, b, e, ?] .
tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0
按 '?':
[q, b, e, ?] .
tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0
按 '?':
[q, b, e, ?] .
tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0
按 'e':
[q, b, e, ?] ...正在停止定时器
按 'q':
[q, b, e, ?] ## 应用程序终止,rc = 0x0
# 实现细节:
以下内容并非旨在完整描述每一个实现细节。但是,它应该有助于理解 U-Boot 的内部工作原理,并使其更容易移植到自定义硬件。
## 初始栈,全局数据:
U-Boot 的实现之所以复杂,是因为 U-Boot 开始运行于 ROM(flash 内存)之中,通常无法访问系统 RAM(因为内存控制器尚未初始化)。
这意味着我们没有可写的数据或 BSS 段,且 BSS 未被初始化为零。为了能够使 C 环境正常工作,我们必须至少分配一个最小的栈。此实现选项由所使用的 CPU 定义并受其限制:某些 CPU 型号提供片内内存(如 MPC8xx 和 MPC826x 处理器上的 IMMR 区域),在其他 CPU 上,数据缓存(的一部分)可以被锁定并(误)用作内存等。
```
Chris Hallinan posted a good summary of these issues to the
U-Boot mailing list:
Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
From: "Chris Hallinan"
Date: Mon, 10 Feb 2003 16:43:46 -0500 (22:43 MET)
...
Correct me if I'm wrong, folks, but the way I understand it
is this: Using DCACHE as initial RAM for Stack, etc, does not
require any physical RAM backing up the cache. The cleverness
is that the cache is being used as a temporary supply of
necessary storage before the SDRAM controller is setup. It's
beyond the scope of this list to explain the details, but you
can see how this works by studying the cache architecture and
operation in the architecture and processor-specific manuals.
OCM is On Chip Memory, which I believe the 405GP has 4K. It
is another option for the system designer to use as an
initial stack/RAM area prior to SDRAM being available. Either
option should work for you. Using CS 4 should be fine if your
board designers haven't used it for something that would
cause you grief during the initial boot! It is frequently not
used.
CFG_SYS_INIT_RAM_ADDR should be somewhere that won't interfere
with your processor/board/system design. The default value
you will find in any recent u-boot distribution in
walnut.h should work for you. I'd set it to a value larger
than your SDRAM module. If you have a 64MB SDRAM module, set
it above 400_0000. Just make sure your board has no resources
that are supposed to respond to that address! That code in
start.S has been around a while and should work as is when
you get the config right.
-Chris Hallinan
DS4.COM, Inc.
```
必须记住这一点,因为它对初始化过程的 C 代码有一些影响:
* 已初始化的全局数据(数据段)是只读的。不要尝试写入它。
* 根本不要使用任何未初始化的全局数据(或隐式初始化为零的数据 —— BSS 段)—— 这是未定义的,初始化会在稍后执行(当重定位到 RAM 时)。
* 栈空间非常有限。避免使用大的数据缓冲区或类似的东西。
只有栈作为可写内存意味着我们不能使用普通的全局数据在代码间共享信息。但事实证明,通过向所有函数提供全局数据结构 (gd_t) 可以极大地简化 U-Boot 的实现。我们可以将指向此数据的指针作为参数传递给 *所有* 函数,但这会使代码膨胀。相反,我们利用 GCC 编译器的一个特性(全局寄存器变量)来共享数据:我们将指向全局数据的指针 放入我们为此目的保留的寄存器中。
为此目的选择寄存器时,我们受到当前架构的相关 (E)ABI 规范以及 GCC 实现的限制。
对于 PowerPC,以下寄存器具有特定用途:
R1: 栈指针
R2: 保留供系统使用
R3-R4: 参数传递和返回值
R5-R10: 参数传递
R13: 小数据区域指针
R30: GOT 指针
R31: 帧指针
```
(U-Boot also uses R12 as internal GOT pointer. r12
is a volatile register so r12 needs to be reset when
going back and forth between asm and C)
==> U-Boot will use R2 to hold a pointer to the global data
Note: on PPC, we could use a static initializer (since the
address of the global data structure is known at compile time),
but it turned out that reserving a register results in somewhat
smaller code - although the code savings are not that big (on
average for all boards 752 bytes for the whole U-Boot image,
624 text + 127 data).
```
在 ARM 上,使用以下寄存器:
```
R0: function argument word/integer result
R1-R3: function argument word
R9: platform specific
R10: stack limit (used only if stack checking is enabled)
R11: argument (frame) pointer
R12: temporary workspace
R13: stack pointer
R14: link register
R15: program counter
==> U-Boot will use R9 to hold a pointer to the global data
Note: on ARM, only R_ARM_RELATIVE relocations are supported.
```
在 Nios II 上,ABI 记录于此:
https://www.altera.com/literature/hb/nios2/n2cpu_nii51016.pdf
```
==> U-Boot will use gp to hold a pointer to the global data
Note: on Nios II, we give "-G0" option to gcc and don't use gp
to access small data sections, so gp is free.
```
在 RISC-V 上,使用以下寄存器:
```
x0: hard-wired zero (zero)
x1: return address (ra)
x2: stack pointer (sp)
x3: global pointer (gp)
x4: thread pointer (tp)
x5: link register (t0)
x8: frame pointer (fp)
x10-x11: arguments/return values (a0-1)
x12-x17: arguments (a2-7)
x28-31: temporaries (t3-6)
pc: program counter (pc)
==> U-Boot will use gp to hold a pointer to the global data
```
## 系统初始化:
在复位配置中,U-Boot 从复位入口点(在大多数 PowerPC 系统上位于地址 0x00000100)开始。由于 CS0# 的复位配置,这是板载 Flash 内存的镜像。
为了能够重映射内存,U-Boot 随后跳转到其链接地址。
为了能够用 C 语言实现初始化代码,会在内部双端口 RAM(如果 CPU 提供此类功能)中,或在数据缓存的锁定部分设置一个(小型!)初始栈。之后,U-Boot 初始化 CPU 核心、缓存和 SIU。
接下来,使用初步映射映射所有(潜在)可用的内存组。例如,我们将它们放在 512 MB 边界上(0x20000000 的倍数:SDRAM 位于 0x00000000 和 0x20000000,Flash 位于 0x40000000 和 0x60000000,SRAM 位于 0x80000000)。然后对 UPM A 进行编程以进行 SDRAM 访问。使用临时配置,运行一个简单的内存测试来确定 SDRAM 组的大小。
当有多个 SDRAM 组且大小不同时,最大的首先映射。如果大小相等,则第一组 (CS2#) 首先映射。第一次映射总是针对地址 0x00000000,任何额外的组紧随其后以创建从 0 开始的连续内存。
然后,monitor 将自身安装在 SDRAM 区域的高端,并为 malloc() 和全局 Board Info 数据分配内存;同时,异常向量代码被复制到低 RAM 页面,并设置最终栈。
只有在此重定位之后,您才会拥有一个“正常”的 C 环境;在此之前,您在多方面受到限制,主要是因为您正在从 ROM 运行,而且代码必须重定位到 RAM 中的新地址。
# 贡献
U-Boot 项目依赖于用户社区的贡献。
如果您想参与,请查看 https://docs.u-boot.org/en/latest/develop/index.html 的 'General' 部分,
其中我们描述了编码标准和补丁提交流程。
标签:ARM架构, Bootloader, BSP, DENX, Git仓库, GPL协议, Linux引导, MIPS, PowerPC, U-Boot, 固件开发, 客户端加密, 嵌入式, 嵌入式开发, 嵌入式系统, 底层软件, 开源硬件, 引导加载程序, 快速连接, 板级支持包, 汇编语言, 硬件初始化, 硬件测试, 系统启动, 系统移植, 自动回退