U-Boot
U-Boot(Universal Boot Loader) 是一款广泛应用于嵌入式系统的开源引导加载程序,主要功能包括:
- 硬件初始化:在系统启动时负责初始化 CPU、内存以及外设,确保硬件资源就绪。
- 加载操作系统:从闪存、eMMC、网络等介质加载操作系统内核,为系统启动提供支持。
- 灵活配置:支持环境变量配置、命令行交互以及脚本自动化,便于定制和调试。
U-Boot 是嵌入式开发中常用的引导工具,凭借其灵活性和强大功能,成为许多设备启动过程中的关键组件。
功能描述
U-Boot 包含 USB、以太网、PCIe、I2C、GPIO、QSPI Flash、eMMC、SD 卡驱动等模块。U-Boot 支持多种启动 Linux 的方式,包括:
- NVMe SSD 启动
- 以太网启动
- eMMC 启动
- U 盘启动
以太网启动使用 TFTP 协议加载内核,可以通过 NFS 挂载根文件系统。
U-Boot 在整个启动流程中作为 BL33 阶段,不存在 SPL 阶段。
当前特性包括:
- 仅支持 CPU 单核模式
- 暂不支持中断
- 开启一级缓存和 MMU
- 物理地址与虚拟地址相同
- 支持设备树方式启动
- 支持 acpi 方式启动
配置流程
在 uboot2025.04 中,修改一下内容:
mthreads_m1000_aimodule_defconfig改为m1000_aimodule_defconfigCONFIG_TARGET_MTHREADS_M1000_AIMODULE改为CONFIG_TARGET_M1000_AIMODULEmthreads-m1000-aimodule.dts改为m1000-aimodule.dtsmthreads-m1000-aimodule.dtb改为m1000-aimodule.dtbTARGET_MTHREADS_M1000_AIMODULE改为TARGET_M1000_AIMODULEmthreads-m1000.dtsi改为m1000.dtsimthreads-m1000-padc.dtsi改为m1000-padc.dtsiCONFIG_EXTRA_ENV_SETTINGS改为CFG_EXTRA_ENV_SETTINGS
步骤 1:增加新的板级配置
下面假定新的板子名称为 boardx。
增加新的板级配置需要建立多个文件和文件夹,建议拷贝原有的板级配置文件,这样可以避免从零开始创建新的文件。
-
在
board/mthreads/文件夹下创建新的板级配置文件夹board/mthreads/文件夹下面是所有 m1000 芯片的板级文件。 -
进入目录
board/mthreads/,输入:cp -ra m1000_aimodule boardx从现有的主板配置拷贝一份,基于此进行修改。
-
进入
boardx目录,修改源文件名称:mv m1000_aimodule.c boardx.c -
修改
Kconfig文件,如下图所示。
其中:- SYS_BOARD 是板子名称
- SYS_VENDOR 是芯片厂家名称
- SYS_CONFIG_NAME 是 config 文件名称
-
修改
Makefile如下图所示: -
建立配置头文件:
-
进入
include/configs文件夹,输入:cp m1000_aimodule.h boardx.h -
修改开始的两行和最后一行(如下图所示)
-
修改最后一行,如下图所示:
-
-
建立配置文件:
-
进入
configs文件夹,输入:cp m1000_aimodule_defconfig boardx_defconfig -
修改
boardx_defconfig文件,将以下内容:CONFIG_DEFAULT_DEVICE_TREE="m1000-aimodule"CONFIG_TARGET_M1000_AIMODULE=y改为:
CONFIG_DEFAULT_DEVICE_TREE="boardx"CONFIG_TARGET_MTHREADS_BOARDX=y如下图所示:
-
-
建立设备树文件:
-
进入
arch/arm/dts目录,输入:cp m1000-aimodule.dts boardx.dts -
修改
Makefile文件,在:dtb-$(CONFIG_TARGET_M1000_AIMODULE) += m1000-aimodule.dtb -
后面增加一行:
dtb-$(CONFIG_TARGET_MTHREADS_BOARDX) += boardx.dtb如下图所示:

-
-
关联板级文件:
-
修改
arch/arm/mach-m1000/Kconfig文件,在:config TARGET_M1000_AIMODULE下面增加
boardx相关选项,如下图所示:
-
并在:
source "board/mthreads/m1000_aimodule/Kconfig"下面增加一行:
source "board/mthreads/boardx/Kconfig"如下图所示:

-
配置完成,编译 U-Boot 即可。
步骤 2:配置设备树
MTT E300 的设备树文件位于 arch/arm/dts 目录下,分为 .dtsi 文件和 .dts 文件。.dts 文件中包含了
.dtsi 文件。其中主要的配置在 m1000.dtsi 文件中,管脚相关的配置在 m1000-padc.dtsi 文件中。
用户自己的 .dts 文件(如上一节中的 boardx.dts 文件)中应包含这两个文件,如下图所示:
一般情况下,用户无需修改
m1000.dtsi。如果确实需要修改其中的某个配置项,不建议直接修改该文件,而是在 dts 文件中重新定义该配置项。
在 m1000.dtsi 中 usb0 的配置如下图所示:

其中 max_speed = <4>; 表示 usb0 使用 super speed 速度模式。如用户需要使能 super speed
plus 模式,可以修改 boardx.dts,如下图所示:
&usb0 表示引用设备树包含文件(.dtsi)中的 usb0 节点。在设备树源文件(.dts)中重新定义的 max_speed = <5> 会覆盖 .dtsi 文件中的
max_speed = <4>
max_speed = <5>:super speed plus 模式
max_speed = <4>:super speed 模式
下面介绍主要外设的设备树配置方法:
-
USB
usb0至usb3节点代表 SoC 的 4 个 USB 控制器,默认处于 host 模式。max_speed = <1>使用全速模式。max_speed = <3>使用高速模式。max_speed = <4>使用 super speed 模式。max_speed = <5>使用 super speed plus 模式。
-
以太网(Ethernet)
当前 U-Boot 仅支持
以太网 0,即gem0节点。 设备树中 gem0 节点的phy-mode = "rgmii-id",表示使用 rgmii 的 phy。 若使用 rmii 的 phy,则需改为:phy-mode = "rmii"; -
eMMC
emmc节点代表 eMMC 存储控制器。mmc-hs200-1_8v;表示支持 hs200 速度模式,若不使用 hs200 模式,可以屏蔽掉此项。mmc-ddr-1_8v;表示支持 ddr 速度模式。如果不使用 ddr 模式,可以屏蔽掉此项。sdhci-caps = <0x0 0x40000>;表示支持 8 线模式,若使用 4 线或 1 线模式,可以屏蔽掉这一项。bus-width表示线宽:bus-width = <8>;使用 8 线模式。bus-width = <4>;使用 4 线模式。bus-width = <1>;使用 1 线模式。
-
SD 卡
sd节点代表 SD 卡。sd; // 表示本节点为 SD 卡
bus-width表示线宽:bus-width = <4>;使用 4 线模式。bus-width = <1>;使用 1 线模式。
-
PCIe 控制器
pcie0~pcie3节点代表 PCIe 控制器 0–3。num-lanes表示 PCIe 使用的 lane 数量:num-lanes = <1>;表示使用 x1 模式,依此类推。
-
QSPI
qspi0节点代表 QSPI,接串行 flash。spi-max-frequency = <3000000>;表示 QSPI 的总线频率为 3M。spi-tx-bus-width = <4>;表示发送支持 4 线模式。spi-rx-bus-width = <4>;表示接收支持 4 线模式。
qspi0节点中有一个flash@0节点,代表外接的串行 flash。 -
I2C:
i2c0~i2c18表示 I2C 的 19 个节点。用户可以根据需求在.dts文件中引用相应的节点,设置status = "okay";即可启用该节点。UART:
U-Boot 中目前支持
uart0和uart7这两个串口节点,其中uart7是默认调试串口,兼容 16550 标准。uart_clock = <100000000>; // 表示 UART 的内部总线频率为 100MHz,这里无需修改
步骤 3:配置 config 头文件
include/configs 文件夹下是与 U-Boot 配置相关的头文件,其中 m1000.h
是 msoc 的公共 config 头文件,需要被每块板子对应的 config 头文件包含。
以下以 boardx.h 为例介绍如何客制化 config 头文件:
-
CONFIG_EXTRA_ENV_SETTINGS
这个宏定义是 U-Boot 扩展的环境变量。 在 U-Boot 中,环境变量主要用于存储系统启动时的各种参数和配置信息,其作用包括定义启动命令、传递内核参数等。
CONFIG_EXTRA_ENV_SETTINGS被定义为一系列拼接起来的字符串,每个字符串之间用\0分隔。例如:"bootdelay=2\0"
等号前是环境变量名称,右边是环境变量的值。
文件开始部分有大量宏定义,这些宏多数用于方便
CONFIG_EXTRA_ENV_SETTINGS的定义。
下面介绍 CONFIG_EXTRA_ENV_SETTINGS 中各参数的含义:
网络 和启动参数
- bootdelay: U-Boot 启动 Linux 之前会等待若干秒。在此期间,用户可通过串口按下空格键进入 U-Boot 命令行。
bootdelay表示该等待时间(秒数)。 - tftppath: 通过以太网 TFTP 协议加载内核时,指定内核镜像在 TFTP 服务器上的路径。
- nfspath: 通过以太网将 rootfs 挂载至 NFS 服务器的某个文件夹时,指定该文件夹路径。
- ipaddr: 板子的 IP 地址。
- gatewayip: 网关地址。若板子与服务器在同一网段,该值可设置为空:"gatewayip=\0"
- netmask: 子网掩码。
- serverip: TFTP 服务器 IP 地址。
- nfsserver: NFS 服务器 IP 地址。
内存地址参数
- dtbaddr: Linux 设备树在 DDR 中的内存地址。
- kerneladdr: Linux 内核在 DDR 中的内存地址。
文件名参数
- kernel: Linux 内核镜像(不包含 ramfs)文件名。
- kernelinitramfs: Linux 内核镜像(包含 ramfs)文件名。
- dtb: Linux 设备树文件名.
启动配置参数
- udiskpart: 表示 U 盘的分区号,例如
udiskpart=1表示第 1 分区。主要用于 U 盘启动,从该分区查找内核镜像。 - compara: 传递给 Linux 内核的通用参数。
- mmcparam: 从 eMMC 启动内核时传递的参数。
- nvmeparam: 从 NVMe SSD 启动内核时传递的参数.
- netparam: 从以太网启动内核时传递的参数.
启动命令
可用的启动命令包括:
# ACPI 方式启动
netbootacpi // 从以太网启动内核(使用 ramfs 作为根文件系统)
mmcbootacpi // 从 eMMC 启动内核
usbbootacpi // 从 U 盘启动内核
nvmebootacpi // 从 NVMe SSD 启动内核
# 设备树方式启动
netbootdts // 从以太网启动内核(使用 ramfs 作为根文件系统)
mmcbootdts // 从 eMMC 启动内核
usbbootdts // 从 U 盘启动内核
nvmebootdts // 从 NVMe SSD 启动内核
自适应启动环境变量
-
bootmedia: 设置环境变量默认值为 auto。
- 若配置为 auto,则优先从 mmc 启动,mmc 启动失败则从 nvme 启动,nvme 启动失败则启动失败,返回错误
- 若环境变量的值为非 auto,设置为 mmc 就从 mmc 启动,设置为 nvme 就从 nvme 启动,启动失败则直接报错
-
bootdts:
- 设置为 acpi 表示通过 acpi 方式启动 linux
- 设置为 dts 表示通过设备树方式启动 linux
-
bootdev: 表示从第几个设备启动内核(0 表示第一个,1 表示第二个...)
-
bootextraarg: 用户需要加入 bootargs 的参数,会放到 bootargs 的最后部分
-
udiskupdate: 是否支持 u 盘更新文件系统功能(0 表示不支持,1 表示支持)
- CONFIG_BOOTCOMMAND
CONFIG_BOOTCOMMAND 是 U-Boot 启动 Linux 所需要的命令,被定义为一个字符串。U-Boot 启动 Linux 过程中会运行这个字符串代表的命令来启动 Linux 内核。
CONFIG_BOOTCOMMAND 默认为 autoboot,这是一个自适应启动的命令,默认以设备树方式启动内核。
自定义启动行为
- 如果希望以 acpi 方式启动内核,可以将环境变量
bootmode改为acpi - 如果希望以设备树方式启动内核,可以将环境变量
bootmode改为dts - 如果希望从第二个 nvme 卡启动内核,可以将环境变量
bootdev改为1,以此类推 - 如果希望从 u 盘启动并更新文件系统,可以将环境变量
udiskupdate设置为1
U 盘启动逻辑
当 udiskupdate=1 时,系统会先检测是否插入 u 盘:
- 若插入了一个 u 盘(注意只能插入 1 个 u 盘),u 盘根目录中有
.boot文件,且文件中的字符为usb_boot或usb_update,则从 u 盘启动 - 如果没有,则从 nvme 卡或 emmc 启动
如果想从 u 盘启动,需要在 u 盘根目录中创建 boot 文件夹,文件夹中放入以下三个文件:
Imagem1000-aimodule.dtbmt-minimal-image-initramfs-aimodule.cpio
根文件系统挂载
内核启动后根文件系统默认挂载在第一个分区(标签一般为 root)上。如果第二个分区(标签为 recovery)的根目录存在名字为 .recovery 的文件,就会挂载在第二个(recovery)分区上,这是为了支持 recovery 功能。
步骤 4:U-Boot 系统配置选项
U-Boot 的系统配置选项可通过 menuconfig 命令进行配置。使用 Yocto 环境时,配置流程相对复杂。下面以 boardx_defconfig 作为系统配置文件举例说明:
在编译环境中,输入:
bitbake u-boot-mt -c devshell # 进入 devshell
输入:
cd oe-workdir/u-boot-mt-2025.04/boardx_defconfig/ # 进入 uboot 编译文件夹
输入:
make menuconfig # 进入配置界面,配置好后保存退出
运行:
make savedefconfig # 保存配置为 defconfig 文件
将该文件拷贝到方便访问的文件夹:
cp defconfig ~/tmp/
输入:
Exit # 退出 devshell
然后用 defconfig 覆盖 configs/boardx_defconfig 文件:
cp ~/tmp/defconfig configs/boardx_defconfig
至此,完成了一次配置流程。
下面介绍部分配置项:
-
Architecture select (ARM architecture):配置 CPU 架构,m1000 使用 ARM 架构。
-
ARM architecture 菜单中包含架构相关的选项:
- ARM Generic Timer support: 需要选中以支持 ARM 的定时器
- Support for booting from TF-A: 需要选中以支持从 TF-A 启动 U-Boot
- m1000 board select: 用于选择板子,例如:m1000 boardx board
- m1000 uart console select: 用于选择调试串口,建议选择 uart ns16550 for console(使用兼容 16550 的 uart7)
-
Command line interface 菜单中包含大量 U-Boot 命令,可选择需要的命令:
- Boot commands: 启动不同格式内核镜像的命令。booti 可启动未压缩的内核镜像,是默认启动命令
- Environment commands: 操作环境变量的命令
- Memory commands: 内存操作命令。md 查看内存内容,mm 修改内存内容
- Device access commands: 访问设备命令,包括 gpio、i2c、gpt、mmc、nvme、pci、pinmux、sf(操作 flash)、usb 等
- Network commands: 网络相关命令。tftpboot 加载镜像,ping 测试网络连接
- Misc commands: 各类其他命令。icache/dcache 可开关缓存
- Filesystem commands: 文件系统支持。ext4/fat/filesystem 通用命令支持
-
Device Tree Control 中包含设备树相关选项:
- Default Device Tree for DT control: 默认设备树文件(如 boardx)
-
Environment 中包含环境变量相关选项:
- Enable overwriting environment: 允许修改以太网和串口环境变量
- Environment is in SPI flash: 环境变量存储在 qspi flash 中
- Environment address: 环境变量在内存中的地址
- Environment offset: 环境变量在 flash 中的偏移地址
- Environment Size: 环境变量占用空间大小
-
Networking support 包含网络相关选项:
- Random ethaddr if unset: 未设置 MAC 地址时自动生成随机 MAC
- Support IP datagram reassembly: 用于加速 TFTP 网络传输
-
Device Drivers 菜单中含有多种驱动,可以在其中选择需要的驱动:
- GPIO support: GPIO 驱动支持
- I2C support: I2C 驱动支持。mthread m1000 I2C driver 表示支持 m1000 SoC I2C 驱动
- MMC Host controller Support: eMMC 和 SD 卡驱动支持
- MTD Support: Flash 驱动框架支持
- Ethernet PHY support: 以太网 PHY 驱动支持
- Network device support: 网络设备驱动支持,包括以太网
- NVM Express device support: NVMe SSD 驱动支持
- PCI support: PCIe 驱动支持
- Serial: 串口驱动支持
- SPI Support: SPI 驱动支持,包括 QSPI
- USB support: USB 驱动支持
-
File systems 文件系统相关支持:
- Enable ext4 filesystem support: ext4 文件系统支持
- Enable FAT filesystem support: FAT 文件系统支持
开发参考
开发定制的命令
U-Boot 提供了大量命令,有时需定制自定义命令。
命令代码在 cmd/ 文件夹中。可以在此文件夹中新建文件,如 commandx.c,并在 Makefile 中添加一行:
obj-y += commandx.o
在 commandx.c 中,要包含如下头文件:
在文件末尾,需要加入如下代码(假定命令为 commandx):

U_BOOT_CMD 是定义命令的一个特殊宏。
commandx是指命令本身的字符串表示;- 第一个
1是指命令参数的最大数量(包括命令本身),因此1表示该命令不接受额外参数; - 第二个
1表示该命令是否可以被重复执行; do_commandx是执行该命令时所调用的函数名;- 最后的两个字符串分别用于解释该命令及其用法说明,通常会显示在
help命令输出中。
因此,需要定义 do_commandx 函数:
static int do_commandx(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
...
return CMD_RET_SUCCESS;
}
argc 是参数的数量,包括命令本身;
argv 是一个字符串数组,包含每个参数的字符串表示;
... 部分就是该命令需要实现的功能代码。
在函数内部,其实也可以调用其他 U-Boot 命令,使用如下函数:
run_command(const char *cmd, int flag);
例如:
run_command("pci emu", 0);
其中 flag 一般设置为 0 即可。
调试方法说明
U-Boot 主要通过串口进行调试,默认使用 uart7(兼容 16550 标准)作为调试串口,波特率默认为
115200。
U-Boot 启动 log 分析
U-Boot 启动 log 如下图所示:

- U-Boot 2025.04-g40d1c4934c9b-dirty (Aug 01 2025 - 04:46:14 +0000):表示 U-Boot 的版本号为
2025.04,括号中是编译的时间戳。 - SoC: m1000 with ARM Cortex-A78 x 12 @ 1.2GHz:表示使用的 SoC 为
m1000,核心为 ARM Cortex-A78,支持 12 核。目前 U-Boot 仅支持单核模式。 - DRAM: 16 GiB:表示 DDR 的内存容量为 16GB。
- MMC: mmc@738000: 0:
mmc@738000: 0表示 eMMC。 - Loading Environment from SPIFlash...:表示从 QSPI Flash 中加载 U-Boot 的环境变量到 DDR 中。
- In: serial@47000;Out: serial@47000;Err: serial@47000:表示输入输出及错误输出均为串口
serial@47000。 - Net: ethernet voltage is 1.8V;eth0: ethernet@734000:表示网络配置,默认使用 RGMII 接口,因此 PHY 电压为 1.8V。
- Press
<SPACE>key to stop autoboot in 2s:U-Boot 启动 Linux 内核前会等待若干秒(此处为 2 秒,可配置)。如果此时按下空格键,可打断启动流程并进入 U-Boot shell。
U-Boot shell 调试
在 U-Boot shell 中,有很多命令可以用于调试,主要分为以下几类:
环境变量命令
pri # 打印所有环境变量。
setenv # 设置环境变量的值。
eraseenv # 清空 QSPI Flash 中所有的环境变量。
saveenv # 将内存中的环境变量保存到 QSPI Flash 中。
内存命令
md <addr> # 打印指定内存地址内容,例如 md 0x900000000

mm <addr> # 修改内存内容。例如:
# mm 0x900000000
# 在 ? 后输入新值按回车,连续修改,按 q 退出。
MMC(eMMC/SD 卡)命令
mmc list # 列出所有 MMC 设备。
mmc info # 打印当前 MMC 设备的信息。
mmc read # 从 MMC 读取数据到内存中。
mmc write # 将内存中的数据写入到 MMC 中。
mmc dev <id> # 切换当前操作的设备(eMMC 或 SD 卡)。
USB 命令
usb start # 开始枚举 USB 设备。
usb stop # 停止 USB 访问(重新 start 前需要先 stop)。
usb info # 查看 USB 设备信息。
PCI 命令
pci emu # 枚举 PCIe 设备。
NVMe SSD 命令
nvme scan # 扫描并初始化 NVMe SSD。
nvme info # 查看 NVMe SSD 信息。
nvme read # 从 NVMe 读取数据到内存。
nvme write # 将内存中的数据写入到 NVMe。
QSPI Flash 命令
sf probe # 初始化 QSPI Flash(使用前必须运行)。
sf read # 从 QSPI 读取数据到内存。
sf write # 将内存数据写入到 QSPI。
sf erase # 擦除 QSPI Flash 数据。
网络命令
net list:列举当前可用的以太网设备。
ping:测试网络是否连通。
tftpboot:通过以太网和 tftp 协议从 tftp 服务器获取文件到内存中。
文件系统通用命令(支持 FAT 和 ext4)
ls <dev>:<part>[/path] # 查看指定路径下文件。
load <dev>:<part> <addr> <file> # 加载文件到内存。
FAT 文件系统专用命令
fatrm # 删除文件。
fatwrite # 写入内存数据到文件。
fatmkdir # 创建目录。
ext4 文件系统命令
ext4write # 将内存中的数据写入文件。
启动内核命令
booti # 启动未压缩内核镜像。
bootz # 启动 gzip 压缩格式的内核镜像。
bootefi # 启动 EFI 格式的内核镜像。
U-Boot 启动ISO镜像
1.4.1 U-Boot已支持启动安装ISO镜像的nvme硬盘,不需要输入命令,默认以ACPI方式启动。
DTS方式启动
setenv bootmode dts # 设置启动模式为 DTS。
load nvme 0:2 ${dtbaddr} boot/m1000-aimodule.dtb # 加载 DTS 文件到内存,路径根据实际路径修改。
load nvme 0:1 ${kerneladdr} /EFI/BOOT/BOOTAA64.EFI # 加载内核镜像到内存,路径根据实际路径修改。
bootefi ${kerneladdr} ${dtbaddr} # 启动内核镜像。
ACPI方式启动
setenv bootmode acpi # 设置启动模式为 ACPI。
load nvme 0:1 ${kerneladdr} /EFI/BOOT/BOOTAA64.EFI # 加载内核镜像到内存,路径根据实际路径修改。
bootefi ${kerneladdr} # 启动内核镜像。
ISO安装盘安装系统
# 安装ISO镜像到U盘。
sudo dd if=m1000-release-oem-2026051908.iso of=/dev/sda bs=4M status=progress conv=fsync
# 进入U-Boot shell。
setenv bootmode acpi # 设置启动模式为 ACPI。
usb start # 开始枚举 USB 设备。
load usb 0:1 ${kerneladdr} /EFI/BOOT/BOOTAA64.EFI # 加载内核镜像到内存,路径根据实际路径修改。
bootefi ${kerneladdr}
常见问题
Q:为什么没有 SPL 阶段?
A:MTT E300 SoC 使用 ARM64 架构,ARM32 传统架构中的 SPL 阶段被 TF-A 软件中的 BL2、BL31 阶段取代,U-Boot 在整个启动链条中处于 BL33 阶段,所以不再需要 SPL 阶段。
Q:运行启动命令后,看到了 Starting kernel ...
的打印,然后就没有打印信息了,是不是表示卡死在内核里面了 ?
A:不是的,Starting kernel ... 是指开始进行启动内核的流程,并没有完成流程,所以仍然可能卡死在 U-Boot 中。
Q:如何判断是卡死在 U-Boot 最后阶段还是卡死在内核的早期阶段?
A:可以在内核较早启动的汇编代码中加入简单的打印信息,例如在 arch/arm64/kernel/head.S 文件中。如果能看到这些打印,说明已经进入内核;如果没有看到,则说明仍然卡在 U-Boot 阶段。
Q:U-Boot 最开始运行的代码在哪?
A:U-Boot 最早期运行的代码在 arch/arm/cpu/armv8/start.S 文件中,_start 是程序开始运行的入口。
Q:调试驱动代码时,发现有时 CPU 已经将数据写入到 DDR 中,为什么设备看不到 DDR 中的数据?
A:有可能是数据还在缓存中。U-Boot 中开启了一级缓存,写入数据后需要运行 Cache Clean 相关函数才可保证数据真正写入 DDR。可使用
flush_dcache_range 函数。
同样地,从 DDR 中读取数据前也需运行 Cache Invalidate 相关函数,保证数据从 DDR 重新加载到 Cache,可使用
invalidate_dcache_range 函数。

