启动开发指南
概述
编写目的
本指南主要介绍 SpacemiT 的刷机启动流程、自定义配置方法,以及 U-Boot 和 OpenSBI 相关的驱动开发与调试技巧,旨在帮助开发者快速掌握设备的启动开发与二次开发流程。
适用范围
本文档适用于SpacemiT的K1系列SOC。
相关人员
- 刷机启动开发工程师
- 内核开发工程师
文档结构
- 刷机启动流程与配置:介绍设备启动机制及自定义方法。
- U-Boot/OpenSBI 开发调试:涵盖编译配置、驱动开发与调试技巧。
- 常见问题处理:提供开发过程中常见问题的解决方案。
刷机启动
本章节介绍刷机和启动相关的配置以及实现原理,并提供自定义刷机、启动的方式。
注意: 刷机与启动是相互关联的,如果需要对刷机做自定义配置,启动可能也需要做相关的调整,反之亦然。
固件布局
K1 系列 SOC 常见的固件布局有以下三种。以下是布局特点:
-
eMMC
- 包含 boot0(存储 bootinfo_emmc.bin 和 FSBL.bin)和 user_data_area(由 GPT 管理分区表)。
- bootinfo_emmc.bin 和 FSBL.bin 存储在 boot0 区域,user_data_area 区域的 fsbl 分区实际上没有内容。
- BROM 启动后会从 boot0 区域加载 bootinfo_emmc.bin 和 FSBL.bin。
-
SD 卡
- 类似 eMMC,但 SD 卡只有 user_data_area 区域。
- bootinfo_sd.bin 占用前 80 字节,GPT 表位于 1 blk。
-
NOR + SSD
- 包含 NOR 上的固件(FSBL+OpenSBI+U-Boot)和 SSD 上的固件(bootfs+rootfs)。
- 支持 NOR+eMMC 等块设备,默认已适配。如果未插入 SSD,仅使用 NOR+eMMC,则拨码开关拨向 NOR 启动。
- 仅支持通过 PCIe0 接口插入的 SSD 作为刷机启动介质,如果 SSD 插入非 PCIe0 接口,则仅作为存储介质。
- 如果使用 TitanFlasher 工具刷机,SSD 上的分区表实际会包含 FSBL/uboot/OpenSBI,但分区内容不会生效。
刷机流程和配置
以下内容包含的刷机、烧写为同一个概念。卡量产本质上也是刷机,只是数据来源于SD卡。而卡量产和卡启动为两个不同的概念,卡启动是将镜像烧写到SD卡里面,从SD卡里面启动系统。
刷机流程
刷机流程是通过 Fastboot 协议将 PC 端的镜像传输到设备,并通过 MMC/MTD/NVMe 等接口写入到对应的存储介质。完整的刷机流程包括进入 U-Boot Fastboot 模式、镜像传输、存储介质设备检测、创建 GPT 表、写入数据到存储介质等步骤。
U-Boot Fastboot 模式
本平台的刷机通讯协议基于 Fastboot 协议,并进行了自定义扩展。所有实际的刷机行为都在 U-Boot Fastboot 模式下进行。进入 U-Boot Fastboot 模式后,通过 PC 端执行 fastboot devices
可以检测到设备(需要配置 PC 的 Fastboot 环境)。
~$ fastboot devices
c3bc939586f0 Android Fastboot
以下介绍进入 U-Boot Fastboot 模式的三种方法:
- 通过按键组合进入:按下板子上的 FEL 键和 RESET 键进入 BROM-Fastboot 模式,然后在上位机(PC)执行以下命令,使板子进入 U-Boot 刷机交互界面。BROM-Fastboot 仅用于加载启动 U-Boot Fastboot。
fastboot stage factory/FSBL.bin
fastboot continue
#sleep wait for uboot ready
#linux环境下
sleep 1
#windows环境下
#timeout /t 1 >null
fastboot stage u-boot.itb
fastboot continue
- 通过 ADB 命令进入:对于已经启动到操作系统的设备,可以通过上位机(PC)运行以下命令
adb reboot bootloader
使板子进入 U-Boot 刷机交互界面。(某些固件可能移除了 ADB 功能,因此该方法不通用。)
- 通过串口进入:在板子启动时,通过串口长按 S 键进入 U-Boot Shell,然后在串口执行以下命令进入 U-Boot 刷机交互界面:
fastboot 0
以下介绍不同存储介质组合的刷机命令。BROM 可以根据 boot pin 切换不同的启动介质(NOR/NAND/eMMC),这取决于硬件设计,具体请参考硬件参考设计。
eMMC 刷机
- eMMC 刷机流程 对于 eMMC 的刷机流程如下,前面部分是从brom-fastboot启动到uboot-fastboot模式,下面其他的介质也一样
fastboot stage factory/FSBL.bin
fastboot continue
#sleep to wait for uboot ready
#linux环境下
sleep 1
#windows环境下
#timeout /t 1 >null
fastboot stage u-boot.itb
fastboot continue
fastboot flash gpt partition_universal.json
#bootinfo_emmc.bin内容无实际作用,请参考FAQ 6.4章节。但刷写步骤还需执行
fastboot flash bootinfo factory/bootinfo_emmc.bin
fastboot flash fsbl factory/FSBL.bin
fastboot flash env env.bin
fastboot flash opensbi fw_dynamic.itb
fastboot flash uboot u-boot.itb
fastboot flash bootfs bootfs.img
fastboot flash rootfs rootfs.ext4
对于 eMMC,bootinfo_emmc.bin
的内容固化在 U-Boot 代码里面,这是为了用同一份 partition_universal.json
分区表兼容卡启动的制作等。且 bootinfo_emmc.bin
和 fsbl.bin
实际上是写入到 eMMC 的 boot0 分区
- eMMC 分区表配置
分区表保存在
buildroot-ext/board/spacemit/k1/partition_universal.json
。其中,bootinfo 不作为一个显式的分区,用于保存启动介质相关信息。
{
"version": "1.0",
"format": "gpt",
"partitions": [
{
"name": "bootinfo",
"offset": "0",
"size": "80B",
"image": "factory/bootinfo_sd.bin"
},
{
"name": "fsbl",
"offset": "256K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"offset": "512K",
"size": "128K"
},
{
"name": "opensbi",
"offset": "1M",
"size": "1M",
"image": "opensbi.itb"
},
{
"name": "uboot",
"offset": "2M",
"size": "2M",
"image": "u-boot.itb"
},
{
"name": "bootfs",
"offset": "4M",
"size": "128M",
"image": "bootfs.img"
},
{
"name": "rootfs",
"size": "-"
}
]
}
NOR+BLK 设备刷机
- NOR+BLK 刷机流程 K1 支持 NOR+SSD/eMMC 等 BLK 设备的组合刷机启动,且为自适应方式。如果同时存在 SSD 和 eMMC,默认烧写到 SSD。
fastboot stage factory/FSBL.bin
fastboot continue
#sleep wait for uboot ready
#linux环境下
sleep 1
#windows环境下
#timeout /t 1 >null
fastboot stage u-boot.itb
fastboot continue
#刷spi nor
fastboot flash mtd partition_2M.json
fastboot flash bootinfo factory/bootinfo_spinor.bin
fastboot flash fsbl factory/FSBL.bin
fastboot flash env env.bin
fastboot flash opensbi fw_dynamic.itb
fastboot flash uboot u-boot.itb
#刷block设备
#刷机工具会根据实际的分区表烧写镜像,所以对于nor+blk,blk设备的fsbl/uboot/等分区并没有实际作用
fastboot flash gpt partition_universal.json
fastboot flash bootfs bootfs.img
fastboot flash rootfs rootfs.ext4
-
NOR+BLK 分区表配置
- NOR 分区表位于
buildroot-ext/board/spacemit/k1/partition_2M.json
。对于 NAND/NOR 设备,分区表以partition_xM.json
命名,并需根据实际 Flash 容量重命名,否则会导致刷机时找不到对应的分区表。- NOR/NAND 的分区表会向最小容量兼容,例如 NOR 的介质容量为 8MB,刷机包中只有
partition_2M.json
,则会匹配到partition_2M.json
的分区表。
- NOR/NAND 的分区表会向最小容量兼容,例如 NOR 的介质容量为 8MB,刷机包中只有
- 对于分区表配置
- MTD 存储介质(NAND/NOR Flash)以
partition_2M.json
等容量形式表 示。 - BLK 设备(包括 eMMC/SD/SSD 等)以
partition_universal.json
命名。
- MTD 存储介质(NAND/NOR Flash)以
- NOR 分区表位于
-
NOR Flash 分区表修改:
- 分区起始地址和 size 默认以 64KB 对齐(对应 erase size 为 64KB)。
- 如果需要将起始地址和 size 更改为 4KB 对齐,则需开启 U-Boot 的编译配置
CONFIG_SPI_FLASH_USE_4K_SECTORS
。
//buildroot-ext/board/spacemit/k1/partition_2M.json
{
"version": "1.0",
"format": "mtd",
"partitions": [
{
"name": "bootinfo",
"offset": "0",
"size": "128K",
"image": "factory/bootinfo_spinor.bin"
},
{
"name": "fsbl",
"offset": "128K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"offset": "384K",
"size": "64K"
},
{
"name": "opensbi",
"offset": "448K",
"size": "192K",
"image": "fw_dynamic.itb"
},
{
"name": "uboot",
"offset": "640K",
"size": "-",
"image": "u-boot.itb"
}
]
}
- SSD 分区表说明
BLK 设备(SSD、eMMC 等)统一使用
partition_universal.json
分区表。 此时,bootinfo
、fsbl
、env
、opensbi
、uboot
等分区及其数据不会影响正常启动。
//buildroot-ext/board/spacemit/k1/partition_universal.json
{
"version": "1.0",
"format": "gpt",
"partitions": [
{
"name": "bootinfo",
"offset": "0K",
"size": "512",
"image": "factory/bootinfo_sd.bin",
"holes": "{\"(80;512)\"}"
},
{
"name": "fsbl",
"offset": "128K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"offset":"384K",
"size": "64K",
"image": "env.bin"
},
{
"name": "opensbi",
"size": "384K",
"image": "fw_dynamic.itb"
},
{
"name": "uboot",
"size": "2M",
"image": "u-boot.itb"
},
{
"name": "bootfs",
"offset": "4M",
"size": "256M",
"image": "bootfs.img",
"compress": "gzip-5"
},
{
"name": "rootfs",
"offset": "260M",
"size": "-",
"image": "rootfs.ext4",
"compress": "gzip-5"
}
]
}
NAND 刷机启动
- NAND 刷机流程 K1 支持使用 NAND 进行刷机启动。但由于 NAND 和 NOR 共用同一个 SPI 接口,两者只能选其一,系统默认使用 NOR 启动。 如需启用 NAND 启动,请参考刷机启动章节中的 NAND 配置说明,完成相关配置。
fastboot stage factory/FSBL.bin
fastboot continue
#sleep wait for uboot ready
#linux环境下
sleep 1
#windows环境下
#timeout /t 1 >null
fastboot stage u-boot.itb
fastboot continue
fastboot flash mtd partition_64M.json
fastboot flash bootinfo factory/bootinfo_spinand.bin
fastboot flash fsbl factory/FSBL.bin
fastboot flash env env.bin
fastboot flash opensbi fw_dynamic.itb
fastboot flash uboot u-boot.itb
fastboot flash user-bootfs bootfs.img
fastboot flash user-rootfs rootfs.img
- UBIFS 文件系统镜像制作说明
NAND 上的文件系统依赖于 UBIFS,需提前生成
bootfs.img
和rootfs.img
,制作方法如下:
#制作bootfs.img
mkfs.ubifs -F -m 2048 -e 124KiB -c 8124 -x zlib -o output/bootfs.img -d input_bootfs/
#制作rootfs.img
mkfs.ubifs -F -m 2048 -e 124KiB -c 8124 -x zlib -o output/rootfs.img -d input_rootfs/
#input_bootfs和input_rootfs应该存放bootfs和rootfs中的文件
#例如对于bootfs,应该放入如下文件Image.itb、env_k1-x.txt 、bianbu.bmp
#不同的nand需要修改对应的参数,以下是一些参数说明,具体可查看mkfs.ubifs的用法
-m 2048:设置最小输入/输出单元大小为 2048 字节(2 KiB),要与NAND Flash 的页大小相匹配。
-e 124KiB:设置逻辑擦除块的大小为 124 KiB(千字节),这应小于实际的物理擦除块的大小,以留出空间用于 UBI 的管理结构。
-c 8124:设置最大逻辑擦除块的数量为 8124,这个数字限制了文件系统的最大大小,基于逻辑擦除块的大小和数量计算。
-x zlib:设置压缩类型为 zlib,这将在文件系统上对数据进行 zlib 压缩。
-o output/ubifs.img:指定输出文件名,将生成的 UBIFS 文件系统镜像保存为 output/ubifs.img。
-d input/:指定源目录为 input/,mkfs.ubifs 将会把这个目录下的文件和文件结构创建成 UBIFS 文件系统镜像。
-
NAND + BLK 组合启动 本平台也支持 NAND + BLK 设备组合启动方式,相关刷机流程可参考 NOR+BLK 设备刷机 章节。
-
NAND 分区表配置 以下示例为适用于 256MB 容量 NAND 的分区表:
partition_256M.json
//buildroot-ext/board/spacemit/k1/partition_64M.json
{
"version": "1.0",
"format": "mtd",
"partitions": [
{
"name": "bootinfo",
"comment": "private partition, should not overrided it",
"offset": "0",
"size": "128K",
"image": "factory/bootinfo_spinand.bin"
},
{
"name": "fsbl",
"offset": "128K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"offset": "384K",
"size": "128K"
},
{
"name": "opensbi",
"offset": "640K",
"size": "384K",
"image": "opensbi.itb"
},
{
"name": "uboot",
"offset": "1M",
"size": "2M",
"image": "u-boot.itb"
},
{
"name": "user",
"offset": "3M",
"size": "-",
"volume_images": {"bootfs": "bootfs.img", "rootfs": "rootfs.img"}
}
]
}
卡启动
卡启动是指将系统镜像写入到 SD 卡 中,当设备插入该 SD 卡后,上电启动时会优先从卡中加载系统。
K1 平台支持卡启动,并且在启动时 会优先尝试从 SD 卡启动,如果启动失败,系统将退回到使用 pin select 选中的其他存储介质启动。
注: 本平台 不支持通过 fastboot 协议 将镜像烧写到 SD 卡。
制作卡启动镜像需使用 TitanFlash 工具 或 dd
命令完成。
使用刷机工具制作卡启动镜像:
- 将 TF 卡插入读卡器,并连接到电脑的 USB 接口。
- 打开电脑端的 TitanFlash 刷机工具(安装方式请参考 TitanFlash 安装)。
- 点击顶部菜单栏中的 研发工具 → 卡启动。
- 点击对应的 选择SD卡 和 选择刷机包。
- 点击 执行,开始烧写镜像。
- 烧写成功后,将 TF 卡插入设备,上电后设备即可实现卡启动。
卡量产
卡量产是指:将刷机相关的镜像文件写入 SD 卡 中,当设备上电启动后,首先从 SD 卡启动,并检测到处于量产模式时,将卡内镜像文件按分区表配置写入到 pin select 选中的存储介质(如 eMMC、NOR、NAND 等)。
K1 平台支持卡量产烧录。通过 TitanFlash 工具 可将 SD 卡制作成量产卡。将量产卡插入设备并上电后,系统会自动将镜像烧录到目标存储 介质。
卡量产制作步骤:
- 将 TF 卡插入读卡器,并接入电脑 USB 接口。
- 打开 TitanFlash 工具,点击 量产工具 → 制作量产卡。
- 选择需要烧录的刷机包,点击 执行 开始制作。
- 制作完成后,将 SD 卡插入设备。
- 上电后设备会自动进入卡烧录流程,并将镜像写入目标存储介质。
- 烧录完成后,务必拔出 SD 卡,以避免再次上电重复烧录。
刷机工具
本章节简要介绍刷机工具的使用方式和相关配套内容。
刷机工具使用
对于镜像的烧写,平台支持以下两种方式:
-
TitanFlash 刷机工具: 面向一般开发者,适用于完整刷机包的烧写,界面友好、功能完整。 工具的安装与使用说明详见官方文档:TitanFlash 使用手册
-
Fastboot 工具: 面向具备一定开发能力的用户,适合进行单个分区的镜像烧写。 注意: 若分区镜像烧写错误,可能导致系统启动异常,请谨慎操作。 相关烧写流程详见本文的 刷机流程 章节,fastboot 环境安装可参 考以下链接:
固件镜像的生成方式,请参考文档:下载和编译
刷机介质选择
-
硬件平台支持通过 Boot Download Sel Switch 拨码开关 切换启动介质。 具体使用方法可参考 MUSE Pi 用户指南中的 Boot Download Sel & JTAG Sel 章节。
-
其他平台或方案,请参考对应的硬件用户使用手册。
-
对于不同的启动介质,刷机方式已做成自动适配。
启动配置
本章节介绍 eMMC、SD、NOR、NAND 启动的配置,以及自定义启动配置相关的注意事项。刷机启动需要配合正确的分区表等配置以及正确的启动配置。
启动流程
本章节介绍平台芯片的启动流程,并且提供定制化启动的修改方。
如下框图,启动流程主要包括以下阶段:
brom -> fsbl -> opensbi -> uboot -> kernel
其中,bootinfo
提供 fsbl 所在偏移、大小、签名等信息。
根据硬件的 Boot Pin Select 配置,系统会从 SD 卡、eMMC、NOR 等介质中加载下一级启动镜像。 不同的启动介质,整体启动流程与上图一致。 Boot Pin Select 的详细介绍请参考 刷机工具使用 章节中的 刷机介质选择 。
在 K1 平台上,设备上电后将:
- 优先尝试从 SD 卡启动;
- 若 SD 卡启动失败,则根据 Boot Pin Select 配置,依次尝试从 eMMC、NAND 或 NOR 加载
OpenSBI
和U-Boot
镜像。
以下小节将根据启动顺序,分别介绍bootinfo、fsbl、opensbi、uboot 和 kernel 等启动配置
BROM (Boot ROM)
brom 是预置于 SoC 的启动代码,出厂即无法改变。芯片上电或复位后自动运行。它根据 Boot Pin 判断启动介质 (如 SD、eMMC、NOR),并从中加载 bootinfo
和 fsbl
。
Boot Pin 设置详见 刷机工具使用 章节中的 刷机介质选择 。
bootinfo
brom 启动后会从对应存储介质的物理 0 地址偏移获取 bootinfo 信息(如,eMMC 会从 boot0 区域的 0 地址加载)。bootinfo 包含 fsbl、fsbl1 的位置、大小与校验 等信息。
其中,bootinfo描述文件在如下目录的 .json
uboot-2022.10$ ls board/spacemit/k1-x/configs/
bootinfo_emmc.json bootinfo_sd.json bootinfo_spinand.json bootinfo_spinor.json
JSON 文件示例说明如下,记录了各种存储介质的默认 fsbl/fsbl1 位置。fsbl1 为备份数据。如果需要修改偏移地址,可以修改 bootinfo_*json
文件,然后重新编译 uboot。
fsbl 的位置尽量保持原厂设置。如果需要自定义,需要考虑不同存储介质的特性,例如 NAND 需要按 sector 对齐等。eMMC 的 fsbl 只支持在 boot 分区加载。
emmc:boot0:0x200, boot1:0x0
sd:0x20000/0x80000
nor:0x20000/0x70000
nand:0x20000/0x80000
编译uboot时会在其根目录下生成对应的 *.bin
文件等 bootinfo 镜像文件,生成方式可参考 uboot-2022.10/board/spacemit/k1-x/config.mk
uboot-2022.10$ ls -l
bootinfo_emmc.bin
bootinfo_sd.bin
bootinfo_spinand.bin
bootinfo_spinor.bin
FSBL (First Stage Boot Loader)
brom 获取 bootinfo 后,会从指定的 offset 加载 fsbl
。
fsbl
文件是由 4K 的头信息与 uboot-spl.bin
组合而成,头信息包含 uboot-spl 的一些必要信息,如 CRC 校验值等。
fsbl 启动后,会先 初始化 DDR,然后从分区表 加载 opensbi 和 uboot 到内存的指定位置,再 运行 opensbi,接着 opensbi 会启动 uboot。(fsbl 如何初始化 DDR 的内容不在本文档的描述范围内)