Boot Development Guide
Overview
Purpose
This guide provides a comprehensive introduction to the boot and flashing process for SpacemiT platforms, including methods for custom configuration, as well as techniques for driver development and debugging within U-Boot and OpenSBI. It is designed to help developers quickly master the system boot process and streamline secondary development.
Scope
This document is applicable to the K1 series SoC (System on Chip) of SpacemiT.
Relevant Personnel
- Firmware flashing and boot development engineers
- Kernel development engineers
Document Structure
- Boot Process and Configuration – Describes the system boot mechanism and customization options.
- U-Boot / OpenSBI Development & Debugging – Covers build configurations, driver development, and debugging techniques.
- Troubleshooting Guide – Offers solutions to common issues encountered during development.
Firmware Flashing and Boot Process
This section introduces configurations and implementation principles related to firmware flashing and booting, along with methods for custom flashing and booting setups.
Note: Flashing and booting are closely connected. Customizing the flashing process may require adjusting the boot settings, and vice versa.
Firmware Layout
The K1 series SoC commonly supports the following three firmware layout schemes. Their key characteristics are described below:

-
eMMC
- Consists of a
boot0area (used to storebootinfo_emmc.binandFSBL.bin) and auser_data_areamanaged by a GPT partition table. bootinfo_emmc.binandFSBL.binare stored in theboot0area. Thefsblpartition in theuser_data_areatypically contains no actual data.- After power-on, BROM loads
bootinfo_emmc.binandFSBL.binfrom theboot0area.
- Consists of a
-
SD Card
- Similar to the eMMC layout, but only includes a
user_data_area. bootinfo_sd.binoccupies the first 80 bytes, and the GPT table begins at block 1.
- Similar to the eMMC layout, but only includes a
-
NOR + SSD
- Firmware on NOR includes
FSBL,OpenSBI, andU-Boot, while, the SSD holdsbootfsandrootfs. - Supports combinations like NOR + eMMC by default. If no SSD is inserted, NOR + eMMC can be used by setting the DIP switch to boot from NOR.
- Only SSDs connected to the PCIe0 interface can be used to boot during flashing. If the SSD is connected to a different PCIe port, it will only work as a storage device, not for booting.
- When flashing with the TitanFlasher tool, the SSD’s partition table may include
FSBL,U-Boot, andOpenSBIentries, but these contents will not be used during boot.
- Firmware on NOR includes
Firmware Flashing Process and Configuration
In this guide,
- Flashing and Burning mean the same thing — writing a system image to storage.
- Mass production is just another way of flashing — except the source image lives on an SD card, and the tool copies it to your device’s internal storage.
- Card booting is different: the device actually boots straight from the SD card image instead of copying it anywhere.
Firmware Flashing Process
Flashing uses the Fastboot protocol to send image files from your PC to the device. These files are written to the corresponding storage like MMC, MTD, or NVMe. The full process includes:
- Entering Fastboot mode in U-Boot
- Sending image files
- Detecting the storage device
- Creating a GPT partition table
- Writing the image data to storage
U-Boot Fastboot Mode
In this platform, the firmware flashing communication protocol is based on the fastboot protocol with some custom extensions. Actual firmware flashing operations occur within the U-Boot's Fastboot mode.
Once the device enters this mode, you can run fastboot devices on your PC to check if the device is detected (make sure Fastboot is set up on your PC):
~$ fastboot devices
c3bc939586f0 Android Fastboot
Below are three methods to enter U-Boot fastboot mode:
-
Using Buttons on the Board
- Hold the FEL button and press the RESET button.
- This puts the board into BROM-Fastboot mode, which is only used to load U-Boot.
- On the PC, run the following commands to load U-Boot Fastboot:
fastboot stage factory/FSBL.binfastboot continue#sleep wait for uboot ready#On Linuxsleep 1#On Windows#timeout /t 1 >nullfastboot stage u-boot.itbfastboot continue -
Using ADB Command If the system is already running, use this command on the PC to reboot into U-Boot Fastboot:
adb reboot bootloaderNote: Some firmware may not include ADB, so this method won't always work.
-
Using the Serial Port During startup, hold the S key via serial connection to enter the U-Boot shell, then run:
fastboot 0
The following subsections introduce the different storage setups which may require different flashing commands. The BROM will boot from the selected storage based on boot pin settings (e.g., NOR/NAND/eMMC). Check your hardware reference design for the exact configuration.
eMMC Flashing
-
eMMC Flashing Process Flashing eMMC follows this basic flow. The first steps are the same as other storage types: you enter U-Boot Fastboot mode via BROM-Fastboot and then begin flashing.
fastboot stage factory/FSBL.binfastboot continue#sleep to wait for uboot ready#linux envsleep 1#windows env#timeout /t 1 >nullfastboot stage u-boot.itbfastboot continuefastboot flash gpt partition_universal.json# This step is still needed, even though bootinfo_emmc.bin content is not used. See FAQ below.fastboot flash bootinfo factory/bootinfo_emmc.binfastboot flash fsbl factory/FSBL.binfastboot flash env env.binfastboot flash opensbi fw_dynamic.itbfastboot flash uboot u-boot.itbfastboot flash bootfs bootfs.imgfastboot flash rootfs rootfs.ext4For EMMC, the content of
bootinfo_emmc.binis embedded within the U-Boot code. This is done to ensure compatibility with using the samepartition_universal.jsontable for SD card booting, among others. Bothbootinfo_emmc.binandFSBL.binare actually written to the EMMC's Boot0 partition. -
EMMC Partition Table Configuration The partition table is stored in
buildroot-ext/board/spacemit/k1/partition_universal.json. The bootinfo is not explicitly defined as a partition but is used to store information related to the boot medium.{"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 Device Flashing
-
NOR+BLK device Flashing process The K1 supports flashing and booting from a combination of NOR Flash and block devices (like SSD or eMMC). It works in an adaptive way — if both SSD and eMMC are connected, SSD will be used as the default flashing target.
fastboot stage factory/FSBL.binfastboot continue#sleep wait for uboot ready#linux envsleep 1#windows env#timeout /t 1 >nullfastboot stage u-boot.itbfastboot continue#flashing to spi norfastboot flash mtd partition_2M.jsonfastboot flash bootinfo factory/bootinfo_spinor.binfastboot flash fsbl factory/FSBL.binfastboot flash env env.binfastboot flash opensbi fw_dynamic.itbfastboot flash uboot u-boot.itb#flashing to block devicefastboot flash gpt partition_universal.jsonfastboot flash bootfs bootfs.imgfastboot flash rootfs rootfs.ext4 -
NOR + BLK Partition Table Configuration
-
NOR Flash Partition Table
-
The NOR partition table is located at:
buildroot-ext/board/spacemit/k1/partition_2M.json -
For NAND/NOR devices, the partition table is named like
partition_xM.json. Make sure the filename matches your actual flash size, or the system won’t find the correct table. -
Partition tables are compatible downward — e.g., if NOR is 8MB and only
partition_2M.jsonis available, it will be used.
-
-
Partition Naming Convention
- MTD devices (e.g., NAND/NOR) use names like
partition_2M.json. - BLK devices (eMMC/SD/SSD) all use
partition_universal.json.
- MTD devices (e.g., NAND/NOR) use names like
-
-
Modifying NOR Flash Partition Tables
-
Partition offsets and sizes are aligned to 64KB by default (corresponding to an erase size of 64 KB)
-
If the offset and size need to align with 4 KB, the U-Boot compilation configuration
CONFIG_SPI_FLASH_USE_4K_SECTORSmust be enabled.
//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 Partition Table All block devices (like SSDs and eMMCs) use the same partition table file
partition_universal.json. In this case, partitions such asbootinfo,fsbl,env,opensbi,uboot, and the data within them, will not affect normal boot processes.//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 Flashing
-
NAND Flashing Process The K1 supports NAND flash booting. However, since NAND and NOR share the same SPI interface, only one of these schemes can be selected, with the default support being for NOR booting.
For NAND flash booting, please refer to the NAND boot configuration section in the programming boot process to configure NAND booting
fastboot stage factory/FSBL.binfastboot continue#sleep wait for uboot ready#linux envsleep 1#windows env#timeout /t 1 >nullfastboot stage u-boot.itbfastboot continuefastboot flash mtd partition_64M.jsonfastboot flash bootinfo factory/bootinfo_spinand.binfastboot flash fsbl factory/FSBL.binfastboot flash env env.binfastboot flash opensbi fw_dynamic.itbfastboot flash uboot u-boot.itbfastboot flash user-bootfs bootfs.imgfastboot flash user-rootfs rootfs.img -
UBIFS Image Creation File system management on the NAND relies on UBIFS. The methods for creating the bootfs and rootfs partitions are as follows:
#Creating bootfs.imgmkfs.ubifs -F -m 2048 -e 124KiB -c 8124 -x zlib -o output/bootfs.img -d input_bootfs/#Creating rootfs.imgmkfs.ubifs -F -m 2048 -e 124KiB -c 8124 -x zlib -o output/rootfs.img -d input_rootfs/#input_bootfs and input_rootfs should contain the files to be included in the bootfs and rootfs partitions, respectively.# For example, for bootfs, include the following files: Image.itb, env_k1-x.txt, bianbu.bmp#Different NANDs require modification of the corresponding parameters; here are some parameter descriptions:-m 2048:Sets the minimum input/output unit size to 2048 bytes (2 KiB), which should match the page size of the NAND Flash.-e 124KiB:Sets the logical erase block size to 124 KiB (kilobytes), which should be smaller than the actual physical erase block size to leave space for UBI management structures.-c 8124:Sets the maximum number of logical erase blocks to 8124, which limits the maximum size of the filesystem based on the size and number of logical erase blocks.-x zlib: Sets the compression type to zlib, which will compress the data in the filesystem using zlib.-o output/ubifs.img: Specifies the output file name, saving the generated UBIFS filesystem image as output/ubifs.img.-d input/: Specifies the source directory as input/, where mkfs.ubifs will create a UBIFS filesystem image from the files and directory structure in this directory. -
NAND + Block Device Boot K1 also supports booting with a combination of NAND and a block device (e.g., SSD or eMMC). The flashing process is similar to the NOR+BLK configuration.
-
NAND Partition Table Example Below is an example of a 64MB partition layout for NAND (
partition_64M.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"}}]}
Card Booting
Card booting refers to writing the image to an SD card. When the device is powered on with the SD card inserted, the system will attempt to boot from the card first.
The K1 platform supports card booting and defaults to first attempting to boot from the SD card. If SD boot fails, the system will fall back to another boot source as selected by the boot pin configuration.
Note: The platform does not support flashing SD cards via the Fastboot protocol.
To prepare an SD card for booting, use the TitanFlash tool or the dd command.
How to Create a Bootable SD Card (with TitanFlash)
- Insert a TF (microSD) card into a card reader and connect it to your PC.
- Open the TitanFlash utility on your computer (installation guide: TitanFlash Installation).
- In the top menu, go to Dev Tools → SDCard Boot Disk.
- Choose the Boot Card and select the flashing package.

- Click Start to begin flashing.
- Once done, insert the SD card into your device. Power it on to boot from the card.
Card Mass Production
Card Mass Production refers to preparing an SD card with flashing images, so that when the device powers on:
- It boots from the SD card first.
- If mass production mode is detected, the system will automatically write the images from the card to the selected onboard storage (eMMC, NOR, NAND, etc.), based on the partition table.
The K1 supports this process. Using the TitanFlash tool, you can create a mass production SD card. Once the card is inserted and the device is powered on, the system will detect it and automatically flash the internal storage without user interaction.
How to Create a Mass Production SD Card
- Insert the TF card into a card reader and connect it to the computer's USB port.
- Open the TitanFlash tool, and navigate to Factory Tools → MP SDcard Programming
- Select the desired flashing package, then click Start to write it.

- After the mass production card has been created, insert the SD card into the device.
- Power on the device. It will automatically boot from the SD card and flash the internal storage according to the partition table.
- After flashing is complete, remove the SD card to prevent re-flashing on the next power-up.
Flashing Tools
This section gives a brief introduction to the available flashing tools and how to use them.
Usage of Flashing Tools
The platform supports two main methods for flashing firmware images:
-
TitanFlash Tool Designed for general developers, TitanFlash offers a full-featured, user-friendly GUI for flashing complete image packages. For installation and usage, refer to the official documentation: TitanFlash User Guide
-
Fastboot Tool Intended for advanced users who are comfortable with command-line tools. It’s best for flashing individual image partitions. Note: Incorrect usage (e.g. flashing the wrong partition) may cause boot failures. Proceed with caution. Flashing steps are covered in the Flashing Process section of this document. Fastboot installation guides:
For information on how to build the firmware image, see: Download and Build
Boot Media Selection
-
The hardware platform supports boot media selection via the Boot Download Sel Switch (DIP switch). For how to use this switch, refer to the Boot Download Sel & JTAG Sel section in the MUSE Pi user guide.
-
For other boards or custom solutions, please refer to their respective hardware manuals.
-
The flashing process supports auto-detection and adapts to the selected boot media.
Boot Configuration
This section explains how to configure booting from different storage devices such as eMMC, SD, NOR, and NAND, and highlights important considerations when customizing boot settings. To successfully boot the system, both the flashing process and the boot configuration (like partition tables and image offsets) must be correctly set.
Boot Process
This section outlines the platform’s boot process which follows a multi-stage sequence:
BROM → FSBL → OpenSBI → U-Boot → Kernel
The bootinfo data provides key details for the FSBL, such as its offset, size, and signature.

At power-on, the system uses the Boot Pin Select configuration to decide which storage device (e.g., SD card, eMMC, NOR) to boot from.
Note: The overall boot sequence remains the same regardless of the boot medium.
For more about the boot pin settings, refer to the Boot Media Selection section under Flashing Tools.
Upon power-on K1, the boot priority is as follows:
- Try to boot from the SD card first.
- If SD boot fails, the system will fall back to other boot media (eMMC, NAND, or NOR), according to the Boot Pin Select settings. It will attempt to load
OpenSBIandU-Bootfrom the selected device.
The following subsections will explain the configuration details for each boot stage component:
bootinfofsblopensbiubootkernel
BROM (Boot ROM)
BROM is the boot code built into the SoC at the factory — it cannot be changed. It runs automatically when the chip powers up or resets.
Based on the Boot Pin settings, BROM detects the selected boot device (e.g., SD, eMMC, NOR) and loads the bootinfo and fsbl from that storage.
For details on how to set Boot Pins, see Boot Media Selection in the Flashing Tools section.
bootinfo
After BROM starts, it reads bootinfo from offset 0 of the selected storage device.
For example, on eMMC, it reads from the start of the boot0 partition.
bootinfo contains metadata about the FSBL and FSBL1 — including their offsets, sizes, and checksums.
The FSBL locations for each storage type are defined in JSON files:
uboot-2022.10$ ls board/spacemit/k1-x/configs/
bootinfo_emmc.json bootinfo_sd.json bootinfo_spinand.json bootinfo_spinor.json
Each file specifies the default locations of fsbl and fsbl1 (a backup copy).
You can adjust the offsets by editing these .json files and recompiling U-Boot.
If you're customizing FSBL positions, ensure they align with the requirements of the storage type. For example:
- NAND needs sector alignment
- eMMC only supports FSBL loading from the boot partition
Default Offset Examples
emmc:boot0:0x200, boot1:0x0
sd:0x20000/0x80000
nor:0x20000/0x70000
nand:0x20000/0x80000
bootinfo Output Files
When compiling U-Boot, the corresponding bootinfo image files (i.e. *.bin files) are generated in the root directory:
uboot-2022.10$ ls -l
bootinfo_emmc.bin
bootinfo_sd.bin
bootinfo_spinand.bin
bootinfo_spinor.bin
The generation logic is in:
uboot-2022.10/board/spacemit/k1-x/config.mk
FSBL (First Stage Boot Loader)
After BROM reads bootinfo, it loads the FSBL from the specified offset.
The FSBL is made up of:
- A 4 KB header, which includes essential information for uboot-spl like CRC checksums, and
- The actual
uboot-spl.binbinary (U-Boot SPL = Secondary Program Loader).
What FSBL Does:
- Initializes DDR memory
- Loads OpenSBI and U-Boot into their designated locations in memory, using information from the partition table.
- Runs OpenSBI, which then
- Starts U-Boot
Note: How FSBL performs DDR initialization will not be covered in this section.
Booting with OpenSBI and U-Boot
Different storage media support various ways to load OpenSBI and U-Boot. The following subsections describe how SPL loads and starts OpenSBI and U-Boot for each type of storage device (eMMC, SD, NOR, NAND).
K1 supports two main ways to load OpenSBI and U-Boot during the boot process:
- Separate partitions for
opensbianduboot(default) - A combined image (
uboot-opensbi.itb)
The default behavior is to load from partition names. For combined image booting, refer to the FAQ section below: “Combined loading of U-Boot and OpenSBI.”
eMMC and SD Card Boot
Both eMMC and SD use the MMC driver, and U-Boot determines which to boot from based on the Boot Pin Select configuration. The startup configurations for both are similar.
OpenSBI and U-Boot can be stored in various formats depending on the boot method, including raw partitions, files within a filesystem, or a single FIT (Flattened Image Tree) image.
By default, on K1, the system attempts to boot from the SD card first. If that fails, it falls back to other available media (eMMC, NOR, or NAND).
The SPL device tree source (DTS) needs to be configured to enable support for eMMC and SD. Example:
//uboot-2022.10/arch/riscv/dts/k1-x_spl.dts
/* eMMC */
sdh@d4281000 {
bus-width = <8>;
non-removable;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
sdh-phy-module = <1>;
status = "okay";
u-boot,dm-spl;
};
/* sd */
sdh@d4280000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;
bus-width = <4>;
cap-sd-highspeed;
sdh-phy-module = <0>;
status = "okay";
u-boot,dm-spl;
};
The following introduces different boot methods for eMMC/SD, with a default approach of loading by partition name.
-
Raw Partition Mode The FSBL loads U-Boot and OpenSBI from named partitions. Here, we use eMMC as an example (SD and NOR are similar and not repeated here).
-
Run
make uboot_menuconfigto enter the SPL configuration interface.
-
Select loading via the partition table. Here, separate loading of U-Boot/OpenSBI is supported by default. SPL will first look for partitions named
opensbianduboot. If they’re missing, it falls back to loading raw images from partition index 1 and 2 respectively.

-
After SPL successfully loads OpenSBI and U-Boot, it starts OpenSBI and passes the memory address of U-Boot along with the DTB (Device Tree Blob) information. OpenSBI then boots U-Boot according to the provided address and DTB.
-
-
Fixed Offset Mode This method loads the image directly from a fixed offset on the eMMC.
-
When enabled, SPL reads a single image—containing both OpenSBI and U-Boot from the configured offset.
Note: This mode does not support separate loading of OpenSBI and U-Boot. They must be packaged into a single FIT image.
-
If separate loading is needed, refer to the source:
uboot-2022.10/common/spl/spl_mmc.cunderMMCSD_MODE_RAW.
-
-
Filesystem Mode This method allows SPL to load boot images from a filesystem (typically FAT).
-
U-Boot SPL can load OpenSBI and U-Boot separately as files from the filesystem (e.g.,
opensbi.itb,uboot.itb). -
Run
make menuconfig, enable the required SPL options, and turn on FAT filesystem support.
-
NOR Boot
K1 supports booting from NOR flash. Typical boot combinations include:
- NOR (u-boot-spl / u-boot / OpenSBI) + SSD (bootfs / rootfs)
- NOR (u-boot-spl / u-boot / OpenSBI) + eMMC (bootfs / rootfs)
By default, the system attempts to boot from SSD first. If unsuccessful, it falls back to alternative configurations.
The DTS (Device Tree Source) configuration for SPL is as follows:
//uboot-2022.10/arch/riscv/dts/k1-x_spl.dts
spi@d420c000 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
u-boot,dm-spl;
spi-max-frequency = <15140000>;
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <26500000>;
m25p,fast-read;
broken-flash-reset;
u-boot,dm-spl;
status = "okay";
};
};
NOR Boot Setup (Loading via SPL)
The following options are enabled by default, however, you can verify or modify them by using
menuconfig.
-
Run
make uboot_menuconfig, and then navigate toSPL configuration options.
-
Enable the Following Options: Ensure the following are enabled:
Support MTD driversSupport SPI DM drivers in SPLSupport SPI driversSupport SPI flash driversSupport for SPI flash MTD drivers in SPLSupport loading from mtd device- Ensure that the
Partition name to use to load U-Boot frommatches the partition names in the partition table.
-
Enable Block Device Support (SSD / eMMC) Navigate to
Device Drivers → Fastboot supportEnable:Support blk device- Select appropriate device type: NVMe (for SSD) or MMC (for eMMC)

-
Enable MTD Environment (env) Support SPL uses the environment (env) to locate MTD partition information.
Steps:
-
Go to the
Environmentconfiguration section. -
Enable SPI env loading.
-
Set the env offset (must match the partition table), e.g.
0x80000

-
-
Configure SPI Flash Driver (Based on Hardware) If the default build does not include your flash chip’s driver:
- Run
make uboot_menuconfig - Navigate to
Device Drivers → MTD Support → SPI Flash Support - Enable the driver matching your SPI NOR Flash vendor.

If the required driver is not listed, manually add it in the source:
//uboot-2022.10/drivers/mtd/spi/spi-nor-ids.cconst struct flash_info spi_nor_ids[] = {{ INFO("flash_name", 0x1f4501, 0, 64 * 1024, 16, SECT_4K) },flash_name: Custom name for your chip0x1f4501: JEDEC ID for the target flash- Remaining fields depend on your chip’s specs (sector size, number of sectors, etc.)
- Run
There are mainly two loading methods, they are:
-
Partition-Based Loading (Recommended) For NOR devices, SPL loads
opensbiandu-bootbased on names defined in the MTD partition table. Configuation can be followed as:
-
Fixed Offset Loading SPL can also load a boot image from a hardcoded offset in NOR flash.
Notes:
- This method does not support loading OpenSBI and U-Boot separately.
- You must package them into a single FIT image.
Enable fixed offset loading and specify the offset:

NAND Boot
K1 platform supports booting from NAND flash. Two main configurations are available:
- NAND (u-boot-spl / U-Boot / OpenSBI) + SSD (bootfs / rootfs)
- Full NAND (u-boot-spl / U-Boot / OpenSBI / kernel)
By default, NAND boot is disabled.
The SPL-DTS configuration is as follows:
//uboot-2022.10/arch/riscv/dts/k1-x_spl.dts
spi@d420c000 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
u-boot,dm-spl;
spi-max-frequency = <15140000>;
spi-nand@0 {
compatible = "spi-nand";
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
spi-max-frequency = <6250000>;
u-boot,dm-spl;
status = "okay";
};
};
Full NAND boot configuration steps are showing below:
-
Enable SPL Build Options
-
Run
make uboot_menuconfigand navigate toSPL configuration optionsand enable the following:
Support MTD driversSupport SPI DM drivers in SPLSupport SPI driversUse standard NAND driverSupport simple NAND drivers in SPLSupport loading from mtd devicePartition name to use to load U-Boot fromshould match the partition names in the partition table.
-
If you are loading OpenSBI and U-Boot separately, also enable:
Second partition to use to load U-Boot from- Ensure the load sequence is: OpenSBI first, then U-Boot.

-
-
Configure Environment (env) Support
MTD(Memory Technology Device)-based systems require the env subsystem to retrieve MTD partition information after SPL (Secondary Program Loader) startup.
-
Run:
make uboot_menuconfig -
Navigate to
Environmentconfiguration. -
Enable support for loading env from SPI.
-
Set env offset to
0x80000(must match partition table).
The NAND flash driver needs to be adapted to the corresponding model of the SPI flash used on the hardware. The currently supported NAND flash drivers are listed below. If there is no corresponding driver, you can add the manufacturer's JEDEC ID (Joint Electron Devices Engineering Council ID) in the other.c driver.
-
-
Add or Modify NAND Flash Drivers
-
Ensure your build includes the correct SPI NAND driver matching your actual flash chip. Currently supported vendors include:
~/uboot-2022.10$ ls drivers/mtd/nand/spi/*.cuboot-2022.10/drivers/mtd/nand/spi/core.cuboot-2022.10/drivers/mtd/nand/spi/micron.cuboot-2022.10/drivers/mtd/nand/spi/winbond.cuboot-2022.10/drivers/mtd/nand/spi/gigadevice.cuboot-2022.10/drivers/mtd/nand/spi/other.cuboot-2022.10/drivers/mtd/nand/spi/macronix.cuboot-2022.10/drivers/mtd/nand/spi/toshiba.c -
If the chip isn’t listed, add support manually in the
other.csource file by defining the JEDEC ID. Example: Adding support for FORESEE or Dosilicon:
//uboot-2022.10/drivers/mtd/nand/spi/other.cstatic int other_spinand_detect(struct spinand_device *spinand){u8 *id = spinand->id.data;int ret = 0;/** dosilicon nand flash*/if (id[1] == 0xe5)ret = spinand_match_and_init(spinand, dosilicon_spinand_table,ARRAY_SIZE(dosilicon_spinand_table),id[2]);/*FORESEE nand flash*/if (id[1] == 0xcd)ret = spinand_match_and_init(spinand, foresee_spinand_table,ARRAY_SIZE(foresee_spinand_table),id[2]);if (ret)return ret;return 1;} -
Kernel Boot
After the system enters U-Boot, it automatically loads and boots the Linux kernel based on configuration in the env file. Developers can customize the boot behavior as needed.
Note: The file
k1-x_env.txttakes precedence overenv.bin— any overlapping variables inenv.binwill be overridden.
Kernel Boot Flow
Once FSBL (First Stage Boot Loader) loads and boots OpenSBI, then hands off to U-Boot, the following occurs:
U-Boot executes a defined boot command to load the kernel, dtb, and other image files from either a FAT or EXT4 file system into memory. It then runs the bootm command to boot the kernel.
All related configurations are located in:
uboot-2022.10/board/spacemit/k1-x/k1-x.env
This file includes multiple pre-configured boot flows (eMMC/SD/NOR+BLK, etc.), and U-Boot will auto-detect the appropriate flow based on the active boot device.
Boot Command Examples
-
MMC Boot (for SD or eMMC) For both SD and eMMC, the boot flow is handled via
mmc_boot.//uboot-2022.10/board/spacemit/k1-x/k1-x.envrun mmc_boot;mmc_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \run commonargs; \run set_mmc_root; \run set_mmc_args; \run detect_dtb; \run loadknl; \run loaddtb; \run loadramdisk; \bootm ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr};The
rootfsis passed from U-Boot to the kernel viabootargs. The kernel or itsinitscript uses this to mount the correct root partition.In below example,
root=/dev/mmcblk2p6indicates the partition for the rootfs.bootargs=earlycon=sbi earlyprintk console=tty1 console=ttyS0,115200 loglevel=8 clk_ignore_unused swiotlb=65536 rdinit=/init root=/dev/mmcblk2p6 rootwait rootfstype=ext4 -
NOR + Block Device Boot (e.g., NOR + SSD)
//uboot-2022.10/board/spacemit/k1-x/k1-x.envrun nor_boot;nor_boot=echo "Try to boot from ${bootfs_devname}${boot_devnum} ..."; \run commonargs; \run set_nor_root; \run set_nor_args; \run detect_dtb; \run loadknl; \run loaddtb; \run loadramdisk; \bootm ${kernel_addr_r} ${ramdisk_combo} ${dtb_addr}; -
NAND Boot
//uboot-2022.10/board/spacemit/k1-x/k1-x.envrun nand_boot;//to be adapted
U-Boot Features and Configuration
This section introduces the key features of U-Boot and common configuration methods used in development.
Functions
The main functions of U-Boot are:
-
Loading the Boot Kernel Loads the Linux kernel image from storage devices (eMMC / SD / NAND / NOR / SSD, etc.) into a designated memory address and initiates kernel execution.
-
Fastboot Flashing Support Enables image flashing to designated partitions via the
fastboottool. -
Boot Logo Display Shows a boot logo and boot menu during the U-Boot boot phase.
-
Driver Debugging U-Boot provides a shell interface for testing hardware drivers including MMC, SPI, NAND, NOR, NVMe, etc. All drivers are located under the
drivers/directory of the U-Boot source tree.
Compilation
This section describes how to compile U-Boot images from the codebase.
-
Build Configuration
Before the first build or when switching target boards or configurations, set the appropriate defconfig (example for K1):
cd ~/uboot-2022.10make ARCH=riscv k1_defconfig -C ~/uboot-2022.10/To modify the build configuration interactively, you can use the following command:
make ARCH=riscv menuconfig
Use "Y" to enable or "N" to disable specific features. Changes will be saved to the
.configfile in the root directory. -
Compiling U-Boot
cd ~/uboot-2022.10GCC_PREFIX=riscv64-unknown-linux-gnu-make ARCH=riscv CROSS_COMPILE=${GCC_PREFIX} -C ~/uboot-2022.10 -j4 -
Compiling Output
~/uboot-2022.10$ ls u-boot* -lu-bootu-boot.bin # U-Boot imageu-boot.dtb # DTB fileu-boot-dtb.bin # U-Boot image with DTBu-boot.itb # Packs u-boot-nodtb.bin and DTB into FIT formatu-boot-nodtb.binbootinfo_emmc.bin # Records SPL location for eMMC bootbootinfo_sd.binbootinfo_spinand.binbootinfo_spinor.binFSBL.bin # u-boot-spl.bin with header information, loaded and started by BROMk1-x_deb1.dtb # DTB file for the deb1 solutionk1-x_spl.dtb # SPL DTB file
DTS Configuration
All U-Boot device tree source files (DTS) are located under:
~/uboot-2022.10/arch/riscv/dts/
Edit the corresponding DTS file for the specific solution (e.g., deb1):
~/uboot-2022.10$ ls arch/riscv/dts/k1*.dts -l
arch/riscv/dts/k1-x_deb1.dts
arch/riscv/dts/k1-x_deb2.dts
arch/riscv/dts/k1-x_evb.dts
arch/riscv/dts/k1-x_fpga_1x4.dts
arch/riscv/dts/k1-x_fpga_2x2.dts
arch/riscv/dts/k1-x_fpga.dts
arch/riscv/dts/k1-x_spl.dts
U-Boot Driver Development and Debugging
This section outlines how to use and debug drivers within U-Boot. By default, all necessary drivers are enabled in the build configuration, no manual activation is required.
Booting the Linux Kernel
This part demonstrates how to boot a Linux kernel from U-Boot, including setting up custom partition configurations and executing the boot sequence.
Step 1: Enter U-Boot Shell
After powering on the development board, press the s key immediately to enter the U-Boot shell.
Step 2: Enter Fastboot Mode
From the U-Boot shell, run the following command to enter Fastboot mode:
=> fastboot 0
The device will wait for incoming image files from the host.
Step 3: Download the Kernel Image
On the host PC, run the following command to send the kernel image to the board:
C:\Users>fastboot stage Z:\k1\output\Image
On the development board, run the following command in the U-Boot shell to receive the image:
=> fastboot -l 0x40000000 0
Expected Output (U-Boot):
Starting download of 50687488 bytes
...
downloading/uploading of 50687488 bytes finished
Expected Output (PC):
Sending 'Z:\k1\output\Image' (49499 KB) OKAY [ 1.934s]
Finished. Total time: 3.358s
Step 4: Download DTB
On the host PC, send the DTB file with the below command:
C:\Users>fastboot stage Z:\k1\output\k1-x_deb1.dtb
On the development board, receive the DTB file with the below command::
=> fastboot -l 0x50000000 0
Expected Output (U-Boot):
Starting download of 33261 bytes
downloading/uploading of 33261 bytes finished
Expected Output (PC):
Sending 'Z:\k1\output\k1-x_deb1.dtb' (32 KB) OKAY [ 0.004s]
Finished. Total time: 0.054s
Step 5: Exit Fastboot Mode
After completing the transfers, press CTRL+C in the U-Boot shell to exit Fastboot mode.
Step 6: Boot the Kernel
Run the following command to start the Linux kernel:
=> booti 0x40000000 - 0x50000000
Expected Boot Output:
Moving Image from 0x40000000 to 0x200000, end=3d4f000
## Flattened Device Tree blob at 50000000
Booting using the fdt blob at 0x50000000
Using Device Tree in place at 0000000050000000, end 0000000050014896
Starting kernel ...
[ 0.000000] Linux version 6.1.15+ ...
[ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x200000
[ 0.000000] Machine model: spacemit k1-x deb1 board
[ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[ 0.000000] printk: bootconsole [sbi0] enabled
Configuring env
-
Configuration via
make menuconfigDuring U-Boot build configuration, run the following command to open the interactive configuration menu:make menuconfig -
Navigate to Environment Settings In the
menuconfiginterface, go to the Environment section to configure environment variable loading.

Supported Storage Devices: Currently, U-Boot supports loading environment variables from:
- MMC devices (e.g., SD cards or eMMC)
- MTD devices (including SPI NOR and SPI NAND)
-
Set Environment Variable Offset Address
The environment offset must align with the layout defined in your partition table. The default offset is
0x80000. Configuration examples:-
For SPI NOR devices:
(0x80000) Environment address # Offset for SPI NOR env -
For MMC devices:
(0x80000) Environment offset # Offset for MMC env
-
MMC Driver Configuration and Debugging
This section explains how to configure and debug MMC drivers in U-Boot, covering both eMMC and SD card support.
Both devices use the MMC driver but have different device numbers:
- eMMC: dev number = 2
- SD card: dev number = 0
-
Configuration via
make menuconfig-
Enter
make menuconfigRun the following command to launch the interactive configuration menu:make menuconfig -
Enable MMC Host Controller Support Navigate to:
Device Drivers→MMC Host controller SupportEnable the necessary controller options as:
-
-
DTS Configuration Define device tree nodes for eMMC and SD card interfaces in U-Boot's DTS files.
Example configuration:
// uboot-2022.10/arch/riscv/dts/k1-x.dtsisdhci0: sdh@d4280000 {compatible = "spacemit,k1-x-sdhci";reg = <0x0 0xd4280000 0x0 0x200>;interrupt-parent = <&intc>;interrupts = <99>;resets = <&reset RESET_SDH_AXI>, <&reset RESET_SDH0>;reset-names = "sdh_axi", "sdh0";clocks = <&ccu CLK_SDH0>, <&ccu CLK_SDH_AXI>;clock-names = "sdh-io", "sdh-core";status = "disabled";};sdhci2: sdh@d4281000 {compatible = "spacemit,k1-x-sdhci";reg = <0x0 0xd4281000 0x0 0x200>;interrupt-parent = <&intc>;interrupts = <101>;resets = <&reset RESET_SDH_AXI>, <&reset RESET_SDH2>;reset-names = "sdh_axi", "sdh2";clocks = <&ccu CLK_SDH2>, <&ccu CLK_SDH_AXI>;clock-names = "sdh-io", "sdh-core";status = "disabled";};// uboot-2022.10/arch/riscv/dts/k1-x_deb1.dts&sdhci0 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_mmc1 &gpio80_pmx_func0>;bus-width = <4>;cd-gpios = <&gpio 80 0>;cd-inverted;cap-sd-highspeed;sdh-phy-module = <0>;status = "okay";};/* eMMC */&sdhci2 {bus-width = <8>;non-removable;mmc-hs400-1_8v;mmc-hs400-enhanced-strobe;sdh-phy-module = <1>;status = "okay";}; -
Debug and Validation U-Boot provides a command-line interface for MMC driver debugging. Make sure the
CONFIG_CMD_MMCoption is enabled in the build.=> mmc listsdh@d4280000: 0 (SD)sdh@d4281000: 2 (eMMC)=> mmc dev 2 #Switch to eMMCswitch to partitions #0, OKmmc2(part 0) is current device#Read 0x1000 blocks from offset 0 into memory address 0x40000000=> mmc read 0x40000000 0 0x1000MMC read: dev # 2, block # 0, count 4096 ... 4096 blocks read: OK#Write 0x1000 blocks from memory address 0x40000000 to offset 0=> mmc write 0x40000000 0 0x1000MMC write: dev # 2, block # 0, count 4096 ... 4096 blocks written: OK#For other usage options, refer to mmc -h -
Common Interfaces For further implementation details, refer to
cmd/mmc.c.
NVMe Driver Configuration and Debugging
This section explains how to configure and debug the NVMe driver. The NVMe driver is primarily used for accessing and testing SSD storage.
-
Configuration via
make menuconfig-
Enter the Configuration Menu
make menuconfig -
Enable NVMe Driver in Device Drivers
Navigate to Device Drivers and enable NVMe-related options:

-
-
DTS Configuration
In the U-Boot device tree configuration, you need to define the device tree node for the NVMe driver.
Example configuration:
//uboot-2022.10/arch/riscv/dts/k1-x.dtsipcie1_rc: pcie@ca400000 {compatible = "k1x,dwc-pcie";reg = <0x0 0xca400000 0x0 0x00001000>, /* dbi */<0x0 0xca700000 0x0 0x0001ff24>, /* atu registers */<0x0 0x90000000 0x0 0x00100000>, /* config space */<0x0 0xd4282bd4 0x0 0x00000008>, /*k1x soc config addr*/<0x0 0xc0c20000 0x0 0x00001000>, /* phy ahb */<0x0 0xc0c10000 0x0 0x00001000>, /* phy addr */<0x0 0xd4282bcc 0x0 0x00000008>, /* conf0 addr */<0x0 0xc0b10000 0x0 0x00001000>; /* phy0 addr */reg-names = "dbi", "atu", "config","k1x_conf", "phy_ahb","phy_addr", "conf0_addr","phy0_addr";k1x,pcie-port = <1>;clocks = <&ccu CLK_PCIE1>;clock-names = "pcie-clk";resets = <&reset RESET_PCIE1>;reset-names = "pcie-reset";bus-range = <0x00 0xff>;max-link-speed = <2>;num-lanes = <2>;num-viewport = <8>;device_type = "pci";#address-cells = <3>;#size-cells = <2>;ranges = <0x01000000 0x0 0x901000000 0x90100000 0x0 0x100000>,<0x02000000 0x0 0x902000000 0x90200000 0x0 0x0fe00000>;interrupts = <142>, <146>;interrupt-parent = <&intc>;#interrupt-cells = <1>;interrupt-map-mask = <0 0 0 0x7>;interrupt-map = <0000 0 0 1 &pcie1_intc 1>, /* int_a */<0000 0 0 2 &pcie1_intc 2>, /* int_b */<0000 0 0 3 &pcie1_intc 3>, /* int_c */<0000 0 0 4 &pcie1_intc 4>; /* int_d */linux,pci-domain = <1>;status = "disabled";pcie1_intc: interrupt-controller@0 {interrupt-controller;reg = <0 0 0 0 0>;#address-cells = <0>;#interrupt-cells = <1>;};};//uboot-2022.10/arch/riscv/dts/k1-x_deb1.dts&pcie1_rc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_pcie1_3>;status = "okay";}; -
Debugging and Verification Enable configuration
CONFIG_CMD_NVME, follow below steps for debugging:=> nvme scan=> nvme detailBlk device 0: Optional Admin Command Support:Namespace Management/Attachment: noFirmware Commit/Image download: yesFormat NVM: yesSecurity Send/Receive: yesBlk device 0: Optional NVM Command Support:Reservation: yesSave/Select field in the Set/Get features: yesWrite Zeroes: yesDataset Management: yesWrite Uncorrectable: yesBlk device 0: Format NVM Attributes:Support Cryptographic Erase: NoSupport erase a particular namespace: YesSupport format a particular namespace: YesBlk device 0: LBA Format Support:LBA Foramt 0 Support: (current)Metadata Size: 0LBA Data Size: 512Relative Performance: GoodBlk device 0: End-to-End DataProtect Capabilities:As last eight bytes: NoAs first eight bytes: NoSupport Type3: NoSupport Type2: NoSupport Type1: NoBlk device 0: Metadata capabilities:As part of a separate buffer: NoAs part of an extended data LBA: No=> nvme read/write addr blk_off blk_cnt -
Common Interfaces For further implementation details, refer to
cmd/nvme.c.
Network Configuration (Net)
-
Configuration via
make menuconfig-
Enter menuconfig Run the following command to enter the configuration menu:
make menuconfig -
Enable network-related options Navigate to Device Drivers and enable the necessary network options:


-
-
DTS Configuration
In the U-Boot device tree, add the node for the Ethernet controller.
Example configuration:
//uboot-2022.10/arch/riscv/dts/k1-x.dtsieth0: ethernet@cac80000 {compatible = "spacemit,k1x-emac";reg = <0x00000000 0xCAC80000 0x00000000 0x00000420>;ctrl-reg = <0x3e4>;dline-reg = <0x3e8>;clocks = <&ccu CLK_EMAC0_BUS>;clock-names = "emac-clk";resets = <&reset RESET_EMAC0>;reset-names = "emac-reset";status = "disabled";};//uboot-2022.10/arch/riscv/dts/k1-x_deb1.dtsð0 {status = "okay";pinctrl-names = "default";pinctrl-0 = <&pinctrl_gmac0>;phy-reset-pin = <110>;clk_tuning_enable;clk-tuning-by-delayline;tx-phase = <90>;rx-phase = <73>;phy-mode = "rgmii";phy-addr = <1>;phy-handle = <&rgmii>;ref-clock-from-phy;mdio {#address-cells = <0x1>;#size-cells = <0x0>;rgmii: phy@0 {compatible = "ethernet-phy-id001c.c916";device_type = "ethernet-phy";reg = <0x1>;};};}; -
Debugging and Verification
Make sure the build configuration includes
CONFIG_CMD_NET, and that the board is connected to an Ethernet cable with a running TFTP server (not covered here).Debugging commands:
=> dhcp #After executing dhcp, if an address is returned, it indicates a successful connection to the network server. Any other situation indicates a connection failure.ethernet@cac80000 Waiting for PHY auto negotiation to complete...... doneemac_adjust_link link:1 speed:1000 duplex:fullBOOTP broadcast 1BOOTP broadcast 2BOOTP broadcast 3BOOTP broadcast 4BOOTP broadcast 5BOOTP broadcast 6BOOTP broadcast 7DHCP client bound to address 10.0.92.130 (7982 ms)=> tftpboot 0x40000000 site11/uImage.itbethernet@cac80000 Waiting for PHY auto negotiation to complete...... doneemac_adjust_link link:1 speed:1000 duplex:fullUsing ethernet@cac80000 deviceTFTP from server 10.0.92.134; our IP address is 10.0.92.130Filename 'site11/uImage.itb'.Load address: 0x40000000Loading: ######################################################################1.1 MiB/sdoneBytes transferred = 66900963 (3fcd3e3 hex)=># booting kernel=>bootm 0x40000000 -
Common Interfaces For further implementation details, refer to
cmd/net.c.
SPI Configuration and Debugging
SPI (Serial Peripheral Interface) is a widely used serial communication protocol for connecting microcontrollers with peripheral devices. In U-Boot, the SPI driver supports NAND or NOR Flash.
-
Configuration via
make menuconfig-
Enter menuconfig Run the following command to enter the configuration menu:
make menuconfig -
Enable SPI support Navigate to Device Drivers and enable the required SPI options:

-
-
DTS Configuration Add SPI nodes in the U-Boot device tree to enable hardware support.
Example configuration:
//k1-x.dtsi/dts-v1/;/ {compatible = "spacemit,k1x", "riscv";#address-cells = <2>;#size-cells = <2>;soc:soc {compatible = "simple-bus";#address-cells = <2>;#size-cells = <2>;ranges;qspi: spi@d420c000 {compatible = "spacemit,k1x-qspi";#address-cells = <1>;#size-cells = <0>;reg = <0x0 0xd420c000 0x0 0x1000>,<0x0 0xb8000000 0x0 0xd00000>;reg-names = "qspi-base", "qspi-mmap";qspi-sfa1ad = <0xa00000>;qspi-sfa2ad = <0xb00000>;qspi-sfb1ad = <0xc00000>;qspi-sfb2ad = <0xd00000>;clocks = <&ccu CLK_QSPI>,<&ccu CLK_QSPI_BUS>;clock-names = "qspi_clk", "qspi_bus_clk";resets = <&reset RESET_QSPI>,<&reset RESET_QSPI_BUS>;reset-names = "qspi_reset", "qspi_bus_reset";qspi-pmuap-reg = <0xd4282860>;spi-max-frequency = <26500000>;qspi-id = <4>;status = "disabled";};};};//k1-x_deb1.dts&qspi {status = "okay";pinctrl-names = "default";pinctrl-0 = <&pinctrl_qspi>;}; -
Debugging and Verification
Make sure
CONFIG_CMD_SPIis enabled to access thesspicommand in the U-Boot shell.Debugging command:
sspi -h"SPI utility command","[<bus>:]<cs>[.<mode>][@<freq>] <bit_len> <dout> - Send and receive bits\n""<bus> - Identifies the SPI bus\n""<cs> - Identifies the chip select\n""<mode> - Identifies the SPI mode to use\n""<freq> - Identifies the SPI bus frequency in Hz\n""<bit_len> - Number of bits to send (base 10)\n""<dout> - Hexadecimal string that gets sent" -
Common Interfaces For further implementation details, refer to
cmd/spi.c.
NAND Configuration and Debugging
The NAND driver in U-Boot is implemented based on the SPI interface, so SPI support must be enabled first. This section provides instructions on configuring and debugging the NAND driver.
-
Configuration via
make menuconfigRun the following command to enter the configuration menu:make menuconfigNavigate to Device Drivers → MTD Support to enable the necessary options for SPI NAND:

For adding support for a new NAND flash device, you can register its JEDEC ID in the corresponding vendor driver.
~/uboot-2022.10$ ls drivers/mtd/nand/spi/*.c -ldrivers/mtd/nand/spi/core.cdrivers/mtd/nand/spi/gigadevice.cdrivers/mtd/nand/spi/macronix.cdrivers/mtd/nand/spi/micron.cdrivers/mtd/nand/spi/other.cdrivers/mtd/nand/spi/toshiba.cdrivers/mtd/nand/spi/winbond.cTo add a new flash to the
Gigadevicechip, follow these steps://uboot-2022.10/drivers/mtd/nand/spi/gigadevice.cstatic const struct spinand_info gigadevice_spinand_table[] = {SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),NAND_ECCREQ(8, 512),SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,&write_cache_variants,&update_cache_variants),0,SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,gd5fxgq4xexxg_ecc_get_status)),SPINAND_INFO("GD5F1GQ5UExxG", 0x51,NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),NAND_ECCREQ(4, 512),SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,&write_cache_variants,&update_cache_variants),0,SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,gd5fxgq5xexxg_ecc_get_status)),};Note: For other NAND vendors, refer to the structure and methods used in the Gigadevice driver.
-
DTS Configuration
Since SPI NAND is a child device under the SPI controller, the node must be defined under the SPI node.
Example configuration:
&qspi {status = "okay";pinctrl-names = "default";pinctrl-0 = <&pinctrl_qspi>;spi-nand@0 {compatible = "spi-nand";reg = <0>;spi-tx-bus-width = <1>;spi-rx-bus-width = <1>;spi-max-frequency = <6250000>;u-boot,dm-spl;status = "okay";};}; -
Debugging and Verification
Enable
CONFIG_CMD_MTDin U-Boot to use themtdcommand for interacting with NAND devices.Sample Commands:
=> mtdmtd - MTD utilsUsage:mtd - generic operations on memory technology devices=> mtd listmtd read[.raw][.oob] <name> <addr> [<off> [<size>]]mtd dump[.raw][.oob] <name> [<off> [<size>]]mtd write[.raw][.oob][.dontskipff] <name> <addr> [<off> [<size>]]mtd erase[.dontskipbad] <name> [<off> [<size>]]Specific functions:mtd bad <name>With:<name>: NAND partition/chip name (or corresponding DM device name or OF path)<addr>: user address from/to which data will be retrieved/stored<off>: offset in <name> in bytes (default: start of the part)* must be block-aligned for erase* must be page-aligned otherwise<size>: length of the operation in bytes (default: the entire device)* must be a multiple of a block for erase* must be a multiple of a page otherwise (special case: default is a page with dump)The .dontskipff option forces writing empty pages, don't use it if unsure.=> mtd list[RESET]spacemit_reset_set assert=1, id=77[RESET]spacemit_reset_set assert=1, id=78clk qspi_bus_clk already disabledclk qspi_clk already disabledccu_mix_set_rate of qspi_clk timeout[RESET]spacemit_reset_set assert=0, id=77[RESET]spacemit_reset_set assert=0, id=78SF: Detected w25q32 with page size 256 Bytes, erase size 64 KiB, total 4 MiBCould not find a valid device for spi-nandList of MTD devices:* nor0- device: flash@0- parent: spi@d420c000- driver: jedec_spi_nor- path: /soc/spi@d420c000/flash@0- type: NOR flash- block size: 0x10000 bytes- min I/O: 0x1 bytes- 0x000000000000-0x000000400000 : "nor0"- 0x0000000a0000-0x000000100000 : "opensbi"- 0x000000100000-0x000000300000 : "uboot"=> mtd read/write partname addr off size -
Common Interfaces For further implementation details, refer to
cmd/mtd.c.
NOR Configuration and Debugging
The NOR driver is based on SPI, so it's necessary to first enable the SPI driver functionality. This section explains how to configure and debug the NOR driver.
-
Configuration via
make menuconfigRun the following command to enter the configuration menu:make menuconfigNavigate to Device Drivers → MTD Support → SPI Flash Support. Enable the following configurations:


Adding Support for a New SPI NOR Flash
-
For supported NOR Flash chips from known vendors (e.g., GigaDevice), simply enable the appropriate config options.
-
To check or extend the JEDEC ID list: The JEDEC ID table is maintained in:
uboot-2022.10/drivers/mtd/spi/spi-nor-ids.cIf your specific NOR chip is missing from the table, you can manually add its JEDEC ID based on the datasheet. (Look for the
manufackeyword; e.g., Winbond's manufacturer ID is0xfe.)
-
-
DTS Configuration
The NOR flash device is configured as a child node under the SPI controller node in the device tree.
Example Configuration:
//k1/uboot-2022.10/arch/riscv/dts/k1-x_deb1.dts&qspi {status = "okay";pinctrl-names = "default";pinctrl-0 = <&pinctrl_qspi>;flash@0 {compatible = "jedec,spi-nor";reg = <0>;spi-max-frequency = <26500000>;m25p,fast-read;broken-flash-reset;status = "okay";};}; -
Debugging and Verification Ensure the following configs are enabled:
CONFIG_CMD_MTD=yCONFIG_CMD_SF=y
Debug NOR using
mtdCommands:=> mtd listList of MTD devices:* nor0- device: flash@0- parent: spi@d420c000- driver: jedec_spi_nor- path: /soc/spi@d420c000/flash@0- type: NOR flash- block size: 0x1000 bytes- min I/O: 0x1 bytes- 0x000000000000-0x000000400000 : "nor0"- 0x0000000a0000-0x0000000e0000 : "opensbi"- 0x000000100000-0x000000200000 : "uboot"=>=> mtdmtd - MTD utilsUsage:mtd - generic operations on memory technology devicesmtd listmtd read[.raw][.oob] <name> <addr> [<off> [<size>]]mtd dump[.raw][.oob] <name> [<off> [<size>]]mtd write[.raw][.oob][.dontskipff] <name> <addr> [<off> [<size>]]mtd erase[.dontskipbad] <name> [<off> [<size>]]Specific functions:mtd bad <name>With:<name>: NAND partition/chip name (or corresponding DM device name or OF path)<addr>: user address from/to which data will be retrieved/stored<off>: offset in <name> in bytes (default: start of the part)* must be block-aligned for erase* must be page-aligned otherwise<size>: length of the operation in bytes (default: the entire device)* must be a multiple of a block for erase* must be a multiple of a page otherwise (special case: default is a page with dump)The .dontskipff option forces writing empty pages, don't use it if unsure.=>=> mtd read uboot 0x40000000Reading 1048576 byte(s) at offset 0x00000000=> mtd dump uboot 0 0x10Reading 16 byte(s) at offset 0x00000000Dump 16 data bytes from 0x0:0x00000000: d0 0d fe ed 00 0d e8 95 00 00 00 38 00 0d e4 44=>Debug NOR using
sf(SPI Flash) Commands:=> sfsf - SPI flash sub-systemUsage:sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI busand chip selectsf read addr offset|partition len - read `len' bytes starting at`offset' or from start of mtd`partition'to memory at `addr'sf write addr offset|partition len - write `len' bytes from memoryat `addr' to flash at `offset'or to start of mtd `partition'sf erase offset|partition [+]len - erase `len' bytes from `offset'or from start of mtd `partition'`+len' round up `len' to block sizesf update addr offset|partition len - erase and write `len' bytes from memoryat `addr' to flash at `offset'or to start of mtd `partition'sf protect lock/unlock sector len - protect/unprotect 'len' bytes startingat address 'sector'=> sf probeSF: Detected w25q32 with page size 256 Bytes, erase size 4 KiB, total 4 MiB=> sf read 0x40000000 0 0x10device 0 offset 0x0, size 0x10SF: 16 bytes @ 0x0 Read: OK=> -
Common Interfaces
include <spi.h>#include <spi_flash.h>struct udevice *new, *bus_dev;int ret;static struct spi_flash *flash;//Specify SPI bus and cs (chip select), e.g. 0,0ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);flash = spi_flash_probe(bus, cs, speed, mode);ret = spi_flash_read(flash, offset, len, buf);
HDMI Configuration and Debugging
This section primarily focuses on how to enable the HDMI (High-Definition Multimedia Interface) driver.
-
Configuration via
make uboot_menuconfigRun the following command to enter the U-Boot configuration menu:make uboot_menuconfigNavigate to: Device Drivers → Graphics support
Enable the following configurations (enabled by default):





-
DTS Configuration The HDMI driver requires device tree support. The relevant nodes must be configured in the U-Boot device tree source files.
Example Configuration:
&dpu {status = "okay";};&hdmi {pinctrl-names = "default";pinctrl-0 = <&pinctrl_hdmi_0>;status = "okay";};
Boot Logo Configuration and Display
This section explains how to configure and display a boot logo during the U-Boot startup phase.
-
Configuration via
make menuconfig-
Ensure HDMI is Enabled First, confirm HDMI support is enabled in U-Boot. Refer to the section HDMI Configuration and Debugging for details.
-
Enable Boot Logo Support Run the following command to open the U-Boot configuration menu:
make menuconfigNavigate to
Device Drivers → Graphics support, and enable the following option:

-
-
Environment Variable Setup Add the following environment variables (
splashimage、splashposandsplashfile) to support boot logo display. These should be defined in U-Boot’s configuration file located atuboot-2022.10/include/configs/k1-x.h//uboot-2022.10/include/configs/k1-x.h... ...... ...#define CONFIG_EXTRA_ENV_SETTINGS \... ...... ..."splashimage=" __stringify(CONFIG_FASTBOOT_BUF_ADDR) "\0" \"splashpos=m,m\0" \"splashfile=bianbu.bmp\0" \... ...... ...BOOTENV_DEVICE_CONFIG \BOOTENV#endif /* __CONFIG_H */Explanation:
splashimage: Memory address where the boot logo image will be loaded.splashpos: Image position on the screen."m,m"means centered both horizontally and vertically.splashfile: Filename of the BMP image to be displayed. This image must be placed in the same partition asbootfs.
-
Packaging the BMP Image into BootFS To ensure the BMP logo is included in BootFS:
-
Prepare the BMP Image Place the
bianbu.bmpimage file under:./buildroot-ext/board/spacemit/k1/The filename must match both:
UBOOT_LOGO_FILEinbuildroot-ext/board/spacemit/k1/prepare_img.sh- The
splashfileenvironment variable
-
Update the Packaging Script Check that
prepare_img.shcorrectly includes the BMP filebianbu.bmp://buildroot-ext/board/spacemit/k1/prepare_img.sh#!/bin/bash######################## Prepare sub-iamges and pack #####################$0 is this file path#$1 is buildroot output images dirIMGS_DIR=$1DEVICE_DIR=$(dirname $0)... ...UBOOT_LOGO_FILE="$DEVICE_DIR/bianbu.bmp"
-
-
Updating the Boot Logo To update the boot logo, simply replace the existing
bianbu.bmpfile located in the following directory:buildroot-ext/board/spacemit/k1/Make sure the new image file retains the same filename (
bianbu.bmp)
Boot Menu Configuration and Usage
This section mainly introduces how to enable and use the Boot Menu feature in U-Boot.
-
Configuration via
make menuconfig-
Launch the configuration menu Run the following command:
make menuconfig -
Enable Boot Menu Support Navigate to Command line interface → Boot commands, and enable the following option:

-
Enable Autoboot Options Then go to Boot options → Autoboot options, and enable the following option:

-
-
Environment Configuration In the file
buildroot-ext/board/spacemit/k1/env_k1-x.txt, add the environment variablesbootdelayandbootmenu_delay.For example:
bootmenu_delay=5: the system waits 5 seconds on the boot menu for user to choose a boot option.bootdelay=5: after a boot option is selected, the system waits another 5 seconds before starting.
//buildroot-ext/board/spacemit/k1/env_k1-x.txtbootdelay=5# Boot menu definitionsboot_default=echo "Current Boot Device: ${boot_device}"flash_default=echo "Returning to Boot Menu..."spacemit_flashing_usb=echo "recovery from usb...... "; \spacemit_flashing usb;spacemit_flashing_mmc=echo "recovery from mmc...... " \spacemit_flashing mmc;spacemit_flashing_net=echo "recovery from net...... " \spacemit_flashing net;bootmenu_delay=5bootmenu_0="-------- Boot Options --------"=run boot_defaultbootmenu_1="Boot from Nor"=run nor_bootbootmenu_2="Boot from Nand"=run nand_bootbootmenu_3="Boot from MMC"=run try_mmcbootmenu_4="Autoboot"=run autobootbootmenu_5="Show current Boot Device"=run boot_defaultbootmenu_6="-------- Flash Options --------"=run flash_defaultbootmenu_7="recovery from usb"=run spacemit_flashing_usbbootmenu_8="recovery from mmc"=run spacemit_flashing_mmcbootmenu_9="recovery from net"=run spacemit_flashing_net -
Accessing the Boot Menu After powering on the board, press and hold the
Esckey to enter the Boot Menu interface.
Fastboot Command Configuration and Usage
This section introduces the Fastboot command support for the K1-DEB1 solution.
Configuration
To enable Fastboot support, follow these steps:
-
Launch the configuration menu
make menuconfig -
Navigate to
Device Drivers → Fastboot support, and enable the Fastboot configuration options:
-
Enable USB Support Since Fastboot relies on USB drivers, also enable
Device Drivers → USB support:

Entering Fastboot Mode
Method 1: Using U-Boot Shell
-
Access U-Boot Shell During system boot-up, press the
skey to enter the U-Boot shell. -
Execute Fastboot Command
=> fastboot 0The default fastboot buffer address/size is defined by the macros
CONFIG_FASTBOOT_BUF_ADDRandCONFIG_FASTBOOT_BUF_SIZE.#or fastboot -l 0x30000000 -s 0x10000000 0,Specify the buffer address and size.=> fastboot 0k1xci_udc: phy_initk1xci_udc probek1xci_udc: pullup 1-- suspend --handle setup GET_DESCRIPTOR, 0x80, 0x6 index 0x0 value 0x100 length 0x40handle setup SET_ADDRESS, 0x0, 0x5 index 0x0 value 0x22 length 0x0handle setup GET_DESCRIPTOR, 0x80, 0x6 index 0x0 value 0x100 length 0x12..
Method 2: From Bianbu OS
If the device boots into Bianbu OS, it can be rebooted it into Fastboot mode using ADB:
adb reboot bootloader
Note: This method may not be supported by all configurations.
Supported Fastboot Commands
For PC-side Fastboot installation, refer to the section 电脑环境安装.
#Native fastboot protocol commands
fastboot devices # Display available devices
fastboot reboot # Restart the device
fastboot getvar [version/product/serialno/max-download-size]
fastboot flash partname image # Flash the image to the partname partition
fastboot erase partname # Erase the partname partition
fastboot stage file # Download the file to the buffer address
# OEM vendor-specific commands and functionalities
fastboot getvar [mtd-size/blk-size] # Get the size of mtd/blk devices; return NULL if not available
fastboot oem read part # Read data from part to buffer address
fastboot get_staged file # Upload data and name it file. Depends on the oem read part command
Files System
-
FAT
=> fatfatinfo fatload fatls fatmkdir fatrm fatsize fatwrite=> fatls mmc 2:550896911 uImage.itb4671 env_k1-x.txt2 file(s), 0 dir(s)=> fatload mmc 2:5 0x40000000 uImage.itb #load uImage.itb到0x4000000050896911 bytes read in 339 ms (143.2 MiB/s)=> -
EXT4
similar to
fatcommand.=> ext4ext4load ext4ls ext4size=> ext4loadext4load - load binary file from a Ext4 filesystemUsage:ext4load <interface> [<dev[:part]> [addr [filename [bytes [pos]]]]]- load binary file 'filename' from 'dev' on 'interface'to address 'addr' from ext4 filesystem=>
Common U-Boot Commands
This section outlines frequently used U-Boot commands
-
Basic Commands
printenv - print environment variablesmd - memory displaymw - memory write (fill)fdt - flattened device tree utility commandshelp - print command description/usage -
fdtThe
fdtcommand is primarily used to print the contents of DTS (Device Tree Source), such as the DTB (Device Tree Blob) file loaded after U-Boot starts.=> fdtfdt - flattened device tree utility commandsUsage:fdt addr [-c] [-q] <addr> [<size>] - Set the [control] fdt location to <addr>fdt move <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it activefdt resize [<extrasize>] - Resize fdt to size + padding to 4k addr + some optional <extrasize> if neededfdt print <path> [<prop>] - Recursive print starting at <path>fdt list <path> [<prop>] - Print one level starting at <path>fdt get value <var> <path> <prop> [<index>] - Get <property> and store in <var>In case of stringlist property, use optional <index>to select string within the stringlist. Default is 0.fdt get name <var> <path> <index> - Get name of node <index> and store in <var>fdt get addr <var> <path> <prop> - Get start address of <property> and store in <var>fdt get size <var> <path> [<prop>] - Get size of [<property>] or num nodes and store in <var>fdt set <path> <prop> [<val>] - Set <property> [to <val>]fdt mknode <path> <node> - Create a new node after <path>fdt rm <path> [<prop>] - Delete the node or <property>fdt header [get <var> <member>] - Display header infoget - get header member <member> and store it in <var>fdt bootcpu <id> - Set boot cpuidfdt memory <addr> <size> - Add/Update memory nodefdt rsvmem print - Show current mem reservesfdt rsvmem add <addr> <size> - Add a mem reservefdt rsvmem delete <index> - Delete a mem reservesfdt chosen [<start> <size>] - Add/update the /chosen branch in the tree<start>/<size> - initrd start addr/sizeNOTE: Dereference aliases by omitting the leading '/', e.g. fdt print ethernet0.=>=> fdt addr $fdtcontroladdr=> fdt print/ {compatible = "spacemit,k1x", "riscv";#address-cells = <0x00000002>;#size-cells = <0x00000002>;model = "spacemit k1-x deb1 board";... ...memory@0 {device_type = "memory";reg = <0x00000000 0x00000000 0x00000000 0x80000000>;};chosen {bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";stdout-path = "serial0:115200n8";};};=> fdt print /chosenchosen {bootargs = "earlycon=sbi console=ttyS0,115200 debug loglevel=8,initcall_debug=1 rdinit=/init.tmp";stdout-path = "serial0:115200n8";};=> -
shell command
U-Boot supports shell-style commands such as
if/fi,echo, etc.=> if test ${boot_device} = nand; then echo "nand boot"; else echo "not nand boot";finot nand boot=> printenv boot_deviceboot_device=nor=> if test ${boot_device} = nor; then echo "nor boot"; else echo "not nor boot";finor boot=>
OpensBI Functionality and Configuration
This section introduces the compilation configuration for OpensBI.
OpensBI Compilation
cd ~/opensbi/
#Note: The toolchain used for compilation must be provided by spacemiT. Using a different toolchain may result in compilation errors.
GCC_PREFIX=riscv64-unknown-linux-gnu-
CROSS_COMPILE=${GCC_PREFIX} PLATFORM=generic \
PLATFORM_DEFCONFIG=k1-x_deb1_defconfig \
PLATFORM_RISCV_ISA=rv64gc \
FW_TEXT_START=0x0 \
make
Generated Compilation Files
~/opensbi$ ls build/platform/generic/firmware/ -l
fw_dynamic.bin # Dynamic firmware image; passes boot parameters to the next stage
fw_dynamic.elf
fw_dynamic.elf.dep
fw_dynamic.itb # FIT image generated from fw_dynamic.bin
fw_dynamic.its
fw_dynamic.o
fw_jump.bin # Jump image that only performs a jump
fw_payload.bin # Payload image that includes the U-Boot image
Configuring OpenSBI Features
To enable or disable optional OpenSBI features by running menuconfig:
make PLATFORM=generic PLATFORM_DEFCONFIG=k1-x_deb1_defconfig menuconfig

OTA Upgrade
Scope and Implementation Notes
This section describes how to add OTA functionality to the k1-bl-v2.2.10-release baseline. The patch applies only to the current k1-bl-v2.2.10-release baseline. Applying it to earlier versions may result in patch conflicts that require manual resolution.
The patch supports eMMC and SPI NAND. It adds the recovery, misc, userdata, and backup U-Boot uboot_b partitions; an independent recovery system; and the recovery-updater, misc-state, ota-start, and reboot-to-recovery tools. U-Boot uses the OTA state stored in misc to determine whether to enter recovery. The updated system restores the normal state after passing a health check.
Note: Initial OTA enablement changes the partition layout and U-Boot boot logic. An OTA package cannot be used to migrate directly from an unadapted earlier firmware. First flash the complete standard flashing package built as described in this section. Full flashing repartitions the device; back up device data beforehand. OTA updates of the
FSBL,opensbi, andrecoverypartitions are not recommended. If power is lost during an update, the next reboot continues in upgrade mode.
The patch package contains:
| Target Repository/Directory | Patch/Source | Purpose |
|---|---|---|
| buildroot-ext | 0001-feat-Add-recovery-system-with-dedicated-partition.patch | Adds recovery system and eMMC OTA partitions |
| buildroot-ext | 0002-add-recovery-updater-and-misc-state-to-system.patch | Integrates upgrade tools, state utilities, and OTA scripts |
| buildroot-ext | 0003-add-state-change-deel.patch | Completes upgrade state transitions |
| buildroot-ext | 0004-add-misc-state-recovery-updater-compile.patch | Enables OTA tools in the K1 v2 default config |
| buildroot-ext | 0005-create-ota.zip.patch | Generates the eMMC OTA package |
| buildroot-ext | 0006-mmc-support-buot_b-flash.patch | Adds eMMC uboot_b partition and upgrade flow |
| buildroot-ext | 0007-support-nand-flash-and-boot.patch | Improves SPI NAND flashing and boot |
| buildroot-ext | 0008-support-nand-ota.patch | Adds SPI NAND recovery, partitions, and OTA package |
| bsp/uboot-2022.10 | 0001-uboot-support-recovery-start.patch | Boots into recovery based on misc state |
| bsp/uboot-2022.10 | 0002-mmc-support-uboot_b-partition-boot.patch | Supports booting from the eMMC backup U-Boot partition |
| bsp/uboot-2022.10 | 0003-support-nand-flash-and-boot.patch | Improves SPI NAND flashing, detection, and boot |
| bsp/uboot-2022.10 | 0004-support-nand-ota.patch | Supports SPI NAND OTA and recovery boot |
| bsp/linux-6.6 | 0001-support-gd-nand.patch | Adds GigaDevice SPI NAND models |
| package-src | misc-state, recovery-updater | OTA state management and recovery updater source code |
Preparing the OTA Patch
The OTA patch package is available from the SpacemiT download server. Run the following commands from the parent directory of the SDK:
cd /path/to/workdir
wget https://archive.spacemit.com/solutions/buildroot_ota/ota_support_adapt_k1-bl-v2.2.10-release.zip
unzip ota_support_adapt_k1-bl-v2.2.10-release.zip
The commands create the ota_support_adapt_k1-bl-v2.2.10-release directory.
The following procedure assumes that the SDK and patch directories are at the same level:
workdir/
├── k1-bl-v2.2.10-release/
└── ota_support_adapt_k1-bl-v2.2.10-release/
Enter the SDK root directory downloaded from k1-bl-v2.2.10-release. Confirm that the SDK builds successfully and contains no local changes. To avoid conflicts, apply the patches to the following commit baselines:
cd /path/to/k1-bl-v2.2.10-release
cd buildroot-ext
gitl
commit aec6a45b44904033159b6143e4f05371b3a50470 (HEAD -> robot-dev, tag: k1-bl-v2.2.10-release, origin/k1-bl-v2.2.y, m/main, k1-bl-v2.2.y)
Merge: 64d5d53 063e2bc
Author: liujing <jing.liu@spacemit.com>
Date: Fri Jun 5 10:42:33 2026 +0800
Update for v2.2.10
Change-Id: Ia51431ef09484d6d308ed79b8b3a2a7294bfb78d
cd ../bsp-src/uboot-2022.10/
gitl
commit 46a4f510352684407c074b7c0e9114b5443dcc59 (HEAD -> robot-dev, tag: k1-bl-v2.2.10-release, origin/k1-bl-v2.2.y, m/main, k1-bl-v2.2.y)
Merge: d61c8c77e2 dcdcab9e95
Author: liujing <jing.liu@spacemit.com>
Date: Fri Jun 5 10:38:21 2026 +0800
Update for v2.2.10
Change-Id: Icd5172b4b621e491617f54fbcf9a0f8dd8276774
cd ../linux-6.6/
gitl
commit 21f2edd50954020f22954d3be8b9202120ae1ae4 (HEAD -> robot-dev, tag: k1-bl-v2.2.10-release, origin/k1-bl-v2.2.y, m/main, k1-bl-v2.2.y)
Merge: 0c505572f3e0 e01ff0f2bc31
Author: liujing <jing.liu@spacemit.com>
Date: Fri Jun 5 10:36:37 2026 +0800
Update for v2.2.10
Change-Id: I5270c04112dd12ffa96f60880c02d32058da572e
If any affected repository contains local changes, stash them with git stash. Then record the absolute path to the patch directory and copy the two source packages:
cp -r ota_support_adapt_k1-bl-v2.2.10-release/package-src/misc-state/ package-src/
cp -r ota_support_adapt_k1-bl-v2.2.10-release/package-src/recovery-updater/ package-src/
Applying Patches
Apply the three patch series in the numeric order specified by their filename prefixes. The following wildcard expansions preserve that order:
# From the SDK root directory
cd buildroot-ext/
git am ../ota_support_adapt_k1-bl-v2.2.10-release/buildroot-ext/*.patch
# Apply patches 0001–0004 (4 U-Boot patches in total)
cd ../bsp-src/uboot-2022.10/
git am ../../ota_support_adapt_k1-bl-v2.2.10-release/bsp/uboot-2022.10/*.patch
# Apply 1 Linux 6.6 patch
cd ../linux-6.6/
git am ../../ota_support_adapt_k1-bl-v2.2.10-release/bsp/linux-6.6/*.patch
The patch application should complete without errors. If a conflict occurs, check for local changes and verify that the repository commits match the v2.2.10 baseline.
Recompiling
The patches modify the eMMC and SPI NAND defconfigs. Before the first OTA firmware build, make envconfig must be run again; an incremental build alone is insufficient.
make envconfig # Select the required target solution/version
make uboot-rebuild && make linux-rebuild && make
First Deployment of OTA Firmware
Initial deployment must use the full flashing package appropriate for the storage medium and capacity. Flash the device completely by following the procedure described earlier in this document:
- eMMC: use
Buildroot-k1_v2.zip - 512 MiB SPI NAND: use
Buildroot-k1_v2_nand-512M.zip. A 256 MiB NAND device does not have sufficient capacity for the default partition layout. Supporting a smaller NAND device requires manually reducing the partition layout.
A complete flash creates the OTA partitions and writes the new SPL/U-Boot, recovery, and system images. Flashing only bootfs or rootfs is not sufficient because the U-Boot boot logic would not match the actual partition table.
After the first boot, verify the OTA tools and initial state:
command -v ota-start
command -v recovery-updater
command -v misc-state
misc-state get-state
The initial output of misc-state get-state must be NORMAL.
Performing eMMC OTA Upgrade
Copy the new Buildroot-k1_v2-ota.zip package to the device's /userdata/ directory. To upgrade the default partitions, run:
# Transfer the OTA package to the board as required.
ota-start /userdata/Buildroot-k1_v2-ota.zip
By default, eMMC OTA upgrades uboot, uboot_b, bootfs, and rootfs. The partitions for an individual upgrade can also be specified:
# Upgrade system partitions only
ota-start -p bootfs,rootfs /userdata/Buildroot-k1_v2-ota.zip
# Upgrade U-Boot and system partitions
ota-start -p uboot,uboot_b,bootfs,rootfs /userdata/Buildroot-k1_v2-ota.zip
ota-start saves the package as /userdata/update.zip, writes the partition list and the UPDATING state to misc, and reboots automatically. After U-Boot enters recovery, recovery-updater writes the images and performs readback verification, then changes the state to UPDATED_PENDING_BOOT. After the new system passes its health check, the state returns to NORMAL and /userdata/update.zip is deleted.
If power is lost during the upgrade, the next boot re-enters upgrade mode according to the misc state. The upgrade is not retried after more than three failed attempts.
Performing SPI NAND OTA Upgrade
Select the OTA package that matches the actual SPI NAND capacity. The 256 MiB and 512 MiB packages are not interchangeable. By default, NAND OTA upgrades uboot, uboot_b, and bootfs. Updating rootfs is not recommended because the userdata partition must reserve space for the OTA package.
# 256 MiB SPI NAND
ota-start /userdata/Buildroot-k1_v2_nand-256M-ota.zip
# 512 MiB SPI NAND
ota-start /userdata/Buildroot-k1_v2_nand-512M-ota.zip
An individual upgrade can also be limited to a subset of the allowed partitions:
ota-start -p bootfs /path/to/Buildroot-k1_v2_nand-512M-ota.zip
SPI NAND OTA permits updates only to uboot, uboot_b, and bootfs. The rootfs, recovery, misc, and env partitions are not included in the NAND OTA allowlist; ota-start rejects requests to update them. To update recovery or rootfs, or to change the NAND partition layout, reflash the device using a full flashing package.
NAND recovery selects partition_256M.json or partition_512M.json according to capacity and uses flash_erase, nandwrite, or ubiformat to write the corresponding MTD partition. Readback verification is enabled by default.
OTA FAQ
NAND 256 MiB Capacity Support
To support a 256 MiB NAND device, use the following configuration. Each partition must accommodate its corresponding image. Adapt the values as required for other capacities.
-
Enable 256 MiB image generation
In
prepare_img.sh, configure:NAND_VARIANTS=("256M:partition_256M.json:2048:126976:128KiB:300:256:256")The parameters are defined as follows:
min_io 2048LEB 126976PEB 128KiBbootfs max LEB 300recovery max LEB 256userdata max LEB 256If only 256 MiB is supported, remove the 512 MiB entry. Retain both entries to generate both packages.
-
Modify U-Boot default partition table
Set
uboot_defconfigto:spi4.0:256K@512K(env),256K@768K(opensbi),2M@1M(uboot),2M@3M(uboot_b),24M@5M(recovery),1M@29M(misc),24M@30M(bootfs),32M@54M(userdata),-@86M(rootfs)The combined configuration is:
CONFIG_MTDPARTS_DEFAULT="spi4.0:256K@512K(env),256K@768K(opensbi),2M@1M(uboot),2M@3M(uboot_b),24M@5M(recovery),1M@29M(misc),24M@30M(bootfs),32M@54M(userdata),-@86M(rootfs)" -
Modify U-Boot DTS
partition@3600000 {label = "userdata";reg = <0x03600000 0x02000000>;};partition@5600000 {label = "rootfs";reg = <0x05600000 0x00000000>;}; -
Modify the 256 MiB flashing JSON
partition_256M.json:{"name": "userdata","offset": "54M","size": "32M","image": "userdata.ubi"},{"name": "rootfs","offset": "86M","size": "170M","image": "rootfs.ubi"} -
Modify the default output symlink
The script currently links the 512 MiB package by default:
ln -sf "${TARGET_IMAGE_BASE}-512M.zip" "$latest_path"For 256 MiB-only support, change it to:
ln -sf "${TARGET_IMAGE_BASE}-256M.zip" "$latest_path" -
Preserve userdata auto-expansion
Retain the following setting. For 256 MiB, the maximum
userdataUBIFS LEB count must be256; do not reuse the previous value of160or the 512 MiB value of80.vol_flags=autoresize
Custom Partition Upgrade Protection
By default, partitions such as fsbl and recovery are protected from OTA updates to prevent a power interruption during an update from leaving the device unbootable.
To customize the protected partitions, first assess the risk associated with a power interruption during the update:
-
OTA allowed update list
Edit
bianbu-linux-pub/buildroot-ext/board/spacemit/k1_nand/target_overlay/usr/sbin/ota-start, line 5:PARTITIONS=uboot,uboot_b,bootfsAlso modify the parameter validation:
case "$part" inuboot|uboot_b|bootfs)Removing a partition from this list prevents the normal system from updating it through
ota-start. -
Recovery default update list
Edit
bianbu-linux-pub/buildroot-ext/board/spacemit/k1_nand/dracut-modules/99recovery/recovery-init, line 119:partitions="uboot,uboot_b,bootfs"# Must remain consistent with the ota-start default list. -
recovery-updater partition policy
Edit
bianbu-linux-pub/package-src/recovery-updater/src/main.c, line 22:static const char *dangerous_partitions[] = {"bootinfo", "fsbl", "env", "opensbi","uboot", "uboot_b", "userdata", "misc", NULL};static const char *nand_default_partitions[] = {"uboot", "uboot_b", "bootfs", NULL};Notes:
nand_default_partitionsspecifies the default partitions permitted for NAND OTA updates.dangerous_partitionsrequires an explicit--partitionsargument; it does not prohibit the update.- For absolute protection, add a
protected_partitions[]array that rejects updates even when-pis explicitly specified.
-
OTA package contents
Edit
bianbu-linux-pub/buildroot-ext/board/spacemit/k1_nand/prepare_img.sh, line 265:zip "$target_ota_zip" \u-boot.itb \bootfs.ubi \partition_512M.jsonDo not include images for protected partitions in the OTA package. Add images for any newly permitted partitions.
State and Recovery
Use the following commands to view the OTA state:
misc-state get-state
misc-state get-bootcount
misc-state get-partitions
| State | Meaning |
|---|---|
| NORMAL | Normal boot, no pending OTA |
| UPDATING | The upgrade package is ready; the next boot enters recovery to perform the update |
| UPDATED_PENDING_BOOT | The partition write succeeded; the new system is awaiting boot and health-check completion |
| RECOVERY_REQUIRED | Recovery is required, or the update failed and is awaiting recovery processing |
To enter recovery manually for investigation, run:
reboot-to-recovery
# After entering recovery, run misc-state clear-all to clear the flags.
This command sets RECOVERY_REQUIRED, clears the boot counter, and reboots. Do not modify the OTA state manually during normal operation. U-Boot and the system health check handle boot retries and state recovery. If repeated boot failures persist, inspect the U-Boot and recovery logs through the serial port, then restore the device using the appropriate full flashing package.
FAQ
This section introduces common issues and their solutions, as well as common debugging methods and frequently encountered problems.
Device Not Detected by TitanFlash During Firmware Flashing
Ensure the USB cable is securely connected to the host PC and that the serial output from the device is visible, as shown below:

If serial output indicates the device is connected but TitanFlash still fails to detect it, proceed to the next checks.
- Check Device Manager (Windows) Open Device Manager and verify whether the device appears under ADB Interface. If not, the required USB driver may be missing.

- Refer to Installation Guide If ADB devices are not listed in Device Manager, please refer to the 电脑环境安装 section for instructions on installing the Fastboot and ADB drivers.
Changes to def_config Do Not Take Effect After Updating Code
If changes are made to the defconfig file but those changes are not reflected during the build process, you must run the following command to update the .config file accordingly:
make menuconfig
This ensures that the new configuration is applied before building.
Merging U-Boot and OpensBI for Loading
The SDK design separates U-Boot and OpensBI loading. Developers can merge the two based on their requirements. Follow these steps.
Step 1: SPL Boot Configuration
-
Disable U-Boot "Second Partition" Setting In U-Boot configuration, deselect the option “Second partition to use to load U-Boot from.”
-
Rename the Partition to
opensbi-ubootUpdate the partition name in the configuration toopensbi-ubootand recompile U-Boot.

Step 2: Generate u-boot-opensbi.itb
-
Create the ITS Description File Create a new file named
u-boot-opensbi.itswith the following contents:/dts-v1/;/ {description = "U-boot FIT image for k1x";#address-cells = <2>;fit,fdt-list = "of-list";images {uboot {description = "U-Boot";type = "standalone";os = "U-Boot";arch = "riscv";compression = "none";load = <0x0 0x00200000>;data = /incbin/("./u-boot-nodtb.bin");};opensbi {description = "OpenSBI fw_dynamic Firmware";type = "firmware";os = "opensbi";arch = "riscv";compression = "none";load = <0x0 0x0>;entry = <0x0 0x0>;data = /incbin/("./fw_dynamic.bin");};fdt_14 {description = "k1-x_MUSE-Card";type = "flat_dt";compression = "none";data = /incbin/("./uboot/k1-x_MUSE-Card.dtb");};};configurations {default = "conf_14";conf_14 {description = "k1-x_MUSE-Card";firmware = "opensbi";loadables = "uboot";fdt = "fdt_14";};};}; -
Generate
uboot-opensbi.itbby placing the required files in the same directoryu-boot-opensbi.itsu-boot-nodtb.binfw_dynamic.bink1-x_MUSE-Card.dtb(Replacek1-x_MUSE-Card.dtbwith the actual DTB name for your platform if different.)
-
Build the Unified Image Run:
uboot-2022.10/tools/mkimage -f u-boot-opensbi.its -r u-boot-opensbi.itb
Step 3: Modify Partition Table
As an example, in partition_universal.json, remove the separate uboot partition and rename the opensbi partition to opensbi-uboot. Ensure the new size accommodates both images, as follows:
~$ cat partition_universal.json
{
"version": "1.0",
"format": "gpt",
"partitions": [
{
"name": "bootinfo",
"offset": "0",
"size": "80B",
"image": "factory/bootinfo_sd.bin"
},
{
"name": "fsbl",
"offset": "128K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"offset": "384K",
"size": "64K"
},
{
"name": "opensbi-uboot",
"offset": "1M",
"size": "3M",
"image": "u-boot-opensbi.itb"
},
{
"name": "bootfs",
"offset": "4M",
"size": "256M",
"image": "bootfs.img",
"compress": "gzip-5"
},
{
"name": "rootfs",
"size": "-"
}
]
}
Step 4: Flashing Procedure
For eMMC devices, use the following fastboot commands:
fastboot stage factory/FSBL.bin
fastboot continue
#sleep to wait for uboot ready
#linux env
sleep 1
#windows env
#timeout /t 1 >null
fastboot stage u-boot-opensbi.itb
fastboot continue
fastboot flash gpt partition_universal.json
#bootinfo_emmc.bin # it is not used during boot, but flashing this partition is still required.
fastboot flash bootinfo factory/bootinfo_emmc.bin
fastboot flash fsbl factory/FSBL.bin
fastboot flash env env.bin
fastboot flash opensbi-uboot u-boot-opensbi.itb
fastboot flash bootfs bootfs.img
fastboot flash rootfs rootfs.ext4
Using TitanFlasher
For using the TitanFlasher tool provided by SpacemiT, make sure to update the fastboot.yaml in the flashing package. Replace any reference to u-boot.itb with:
image: u-boot-opensbi.itb
Define FSBL Location for eMMC Boot
Unlike NOR, NAND, or SD cards, which use a single storage region, eMMC devices have separate boot0 and user regions.
By design, the hardware loads bootinfo and fsbl from the boot0 region — not the user region. So they must be placed in boot0.
During the flashing process, the bootinfo information for eMMC is fixed in the U-Boot code inside the fastboot_oem_flash_bootinfo function. This is done so that the same partition_universal.json partition table can be used for card booting and other purposes.
When flashing the system, U-Boot generates the bootinfo content for eMMC using the fastboot_oem_flash_bootinfo function.
This design allows the same partition_universal.json to be reused across different boot media, such as SD cards and eMMC.
How to Modify FSBL Load Offset on eMMC To change the FSBL load offset for eMMC, edit the following code directly:
//uboot-2022.10/drivers/fastboot/fb_mmc.c
516 void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
517 u32 download_bytes, char *response)
518 {
... ...
554 if (strcmp(cmd, "bootinfo") == 0) {
555 printf("flash bootinfo\n");
556 fastboot_oem_flash_bootinfo(cmd, fastboot_buf_addr, download_bytes,
557 response, fdev);
558 return;
559 }
//uboot-2022.10/drivers/fastboot/fb_spacemit.c
816 void fastboot_oem_flash_bootinfo(const char *cmd, void *download_buffer,
817 u32 download_bytes, char *response, struct flash_dev *fdev)
818 {
830 /*fill up emmc bootinfo*/
831 struct boot_parameter_info *boot_info;
832 boot_info = (struct boot_parameter_info *)download_buffer;
833 memset(boot_info, 0, sizeof(boot_info));
834 boot_info->magic_code = BOOT_INFO_EMMC_MAGICCODE;
835 boot_info->version_number = BOOT_INFO_EMMC_VERSION;
836 boot_info->page_size = BOOT_INFO_EMMC_PAGESIZE;
837 boot_info->block_size = BOOT_INFO_EMMC_BLKSIZE;
838 boot_info->total_size = BOOT_INFO_EMMC_TOTALSIZE;
839 boot_info->spl0_offset = BOOT_INFO_EMMC_SPL0_OFFSET;
840 boot_info->spl1_offset = BOOT_INFO_EMMC_SPL1_OFFSET;
841 boot_info->spl_size_limit = BOOT_INFO_EMMC_LIMIT;
842 strcpy(boot_info->flash_type, "eMMC");
843 boot_info->crc32 = crc32_wd(0, (const uchar *)boot_info, 0x40, CHUNKSZ_CRC32);
844
845 /*flash bootinfo*/
For eMMC boot0, the Fastboot flashing service handles the bootinfo and fsbl partitions specially by writing the image files directly to the boot0 area.
This logic is implemented in uboot-2022.10/drivers/fastboot/fb_mmc.c::fastboot_mmc_flash_write, specifically in the if (strcmp(cmd, "bootinfo") == 0) and if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) branches.
//uboot-2022.10/drivers/fastboot/fb_mmc.c
void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
517 u32 download_bytes, char *response)
518 {
554 if (strcmp(cmd, "bootinfo") == 0) {
555 printf("flash bootinfo\n");
556 fastboot_oem_flash_bootinfo(cmd, fastboot_buf_addr, download_bytes,
557 response, fdev);
558 return;
559 }
563 #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
564 if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
565 dev_desc = fastboot_mmc_get_dev(response);
566 if (dev_desc){
567 #ifdef CONFIG_SPACEMIT_FLASH
568 flash_mmc_boot_op(dev_desc, download_buffer, 1,
569 download_bytes, BOOT_INFO_EMMC_SPL0_OFFSET);
570 fastboot_okay(NULL, response);
571 #else
572 fb_mmc_boot_ops(dev_desc, download_buffer, 1,
573 download_bytes, response);
574 #endif
575 }
576 return;
577 }
Will bootinfo_sd.bin at Address 0 Conflict with the GPT Table?
Placing bootinfo_sd.bin at address 0 on the SD card will not conflict with the GPT table.
The GPT header actually starts at offset 0x100, and bootinfo is not treated as a recognized partition.
How to Set Up Hidden Partitions
The partition table partition_universal.json supports hidden partitions. The hidden tag is used to mark hidden partitions. After flashing and booting, hidden partitions do not appear in the GPT table.
To flash hidden partitions, you must use TitanFlasher or run:
fastboot flash gpt partition_universal.json
After flashing the partition table, you can use Fastboot to flash images to hidden partitions.
Note: Only block devices like eMMC and SSD currently support hidden partitions. The
bootinfopartition is only supported as a hidden partition.
Example: Partition Table with Hidden Partitions
If hidden is not specified, the partition is treated as visible by default.
cat k1/common/flash_config/partition_universal.json
{
"version": "1.0",
"format": "gpt",
"partitions": [
{
"name": "bootinfo",
"hidden": true,
"offset": "0",
"size": "80B",
"image": "factory/bootinfo_sd.bin"
},
{
"name": "fsbl",
"hidden": true,
"offset": "128K",
"size": "256K",
"image": "factory/FSBL.bin"
},
{
"name": "env",
"hidden": true,
"offset": "384K",
"size": "64K",
"image": "u-boot-env-default.bin"
},
{
"name": "opensbi",
"offset": "1M",
"size": "1M",
"image": "opensbi.itb"
},
{
"name": "uboot",
"offset": "2M",
"size": "2M",
"image": "u-boot.itb"
},
{
"name": "bootfs",
"offset": "4M",
"size": "256M",
"image": "bootfs.img",
"compress": "gzip-5"
},
{
"name": "rootfs",
"size": "-"
}
]
}
For U-Boot versions prior to v1.0.9, a patch is required to support hidden partitions.
-
Save the patch file (e.g.,
support-hidden-partition.patch). -
Apply the patch in the U-Boot source directory.
-
Rebuild U-Boot.
cat support-hidden-partition.patch
From 504a003ad33b2dc90749632b4abe05a8fc3a2f21 Mon Sep 17 00:00:00 2001
From: chris <chris.huang@spacemit.com>
Date: Tue, 23 Jul 2024 20:32:54 +0800
Subject: [PATCH] [add]1.support flash hidden partition to blk dev. not support
for mtd dev currently.
Change-Id: Ic78817a3c84e6e02829376990649b477f3c9248d
---
drivers/fastboot/fb_blk.c | 28 ++++++++++++++++++++++++++-
drivers/fastboot/fb_mmc.c | 26 +++++++++++++++++++++++++
drivers/fastboot/fb_spacemit.c | 35 ++++++++++++++++------------------
include/fb_spacemit.h | 10 +++++++++-
4 files changed, 78 insertions(+), 21 deletions(-)
diff --git a/drivers/fastboot/fb_blk.c b/drivers/fastboot/fb_blk.c
index bb756d3f99..11219bc6a6 100644
--- a/drivers/fastboot/fb_blk.c
+++ b/drivers/fastboot/fb_blk.c
@@ -186,6 +186,8 @@ void fastboot_blk_flash_write(const char *cmd, void *download_buffer,
static char __maybe_unused part_name_t[20] = "";
unsigned long __maybe_unused src_len = ~0UL;
bool gzip_image = false;
+ bool is_hidden_part = false;
+ int part_index = 0;
if (fdev == NULL){
fdev = malloc(sizeof(struct flash_dev));
@@ -202,6 +204,15 @@ void fastboot_blk_flash_write(const char *cmd, void *download_buffer,
printf("init fdev success\n");
}
+ for (part_index = 0; part_index < MAX_PARTITION_NUM; part_index++){
+ if (fdev->parts_info[part_index].part_name != NULL
+ && strcmp(cmd, fdev->parts_info[part_index].part_name) == 0){
+ if (fdev->parts_info[part_index].hidden)
+ is_hidden_part = true;
+ break;
+ }
+ }
+
/*blk device would not flash bootinfo except emmc*/
if (strcmp(cmd, "bootinfo") == 0) {
fastboot_okay(NULL, response);
@@ -213,9 +224,24 @@ void fastboot_blk_flash_write(const char *cmd, void *download_buffer,
response, fdev);
return;
}
+
+ if (is_hidden_part){
+ /*find available blk dev*/
+ do_get_part_info(&dev_desc, cmd, &info);
+ if (!dev_desc){
+ fastboot_fail("can not get available blk dev", response);
+ return;
+ }
+
+ strlcpy((char *)&info.name, cmd, sizeof(info.name));
+ info.size = fdev->parts_info[part_index].part_size / dev_desc->blksz;
+ info.start = fdev->parts_info[part_index].part_offset / dev_desc->blksz;
+ info.blksz = dev_desc->blksz;
+ printf("!!! flash image to hidden partition !!!\n");
+ }
#endif
- if (fastboot_blk_get_part_info(cmd, &dev_desc, &info, response) < 0)
+ if (!is_hidden_part && fastboot_blk_get_part_info(cmd, &dev_desc, &info, response) < 0)
return;
if (check_gzip_format((uchar *)download_buffer, src_len) >= 0) {
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index 26e45f4a60..6b417b4ddc 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -528,6 +528,8 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
static char __maybe_unused part_name_t[20] = "";
unsigned long __maybe_unused src_len = ~0UL;
bool gzip_image = false;
+ bool is_hidden_part = false;
+ int part_index = 0;
if (fdev == NULL){
fdev = malloc(sizeof(struct flash_dev));
@@ -544,6 +546,15 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
printf("init fdev success\n");
}
+ for (part_index = 0; part_index < MAX_PARTITION_NUM; part_index++){
+ if (fdev->parts_info[part_index].part_name != NULL
+ && strcmp(cmd, fdev->parts_info[part_index].part_name) == 0){
+ if (fdev->parts_info[part_index].hidden)
+ is_hidden_part = true;
+ break;
+ }
+ }
+
if (strcmp(cmd, "bootinfo") == 0) {
printf("flash bootinfo\n");
fastboot_oem_flash_bootinfo(cmd, fastboot_buf_addr, download_bytes,
@@ -659,6 +670,21 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
}
#endif
+#ifdef CONFIG_SPACEMIT_FLASH
+ if (is_hidden_part){
+ /*find available blk dev*/
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (!dev_desc)
+ return;
+
+ strlcpy((char *)&info.name, cmd, sizeof(info.name));
+ info.size = fdev->parts_info[part_index].part_size / dev_desc->blksz;
+ info.start = fdev->parts_info[part_index].part_offset / dev_desc->blksz;
+ info.blksz = dev_desc->blksz;
+ printf("!!! flash image to hidden partition !!!\n");
+ }
+#endif
+
if (!info.name[0] &&
fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
return;
diff --git a/drivers/fastboot/fb_spacemit.c b/drivers/fastboot/fb_spacemit.c
index ab25ddb1ef..3d2ae02b48 100644
--- a/drivers/fastboot/fb_spacemit.c
+++ b/drivers/fastboot/fb_spacemit.c
@@ -110,12 +110,6 @@ int _clear_env_part(void *download_buffer, u32 download_bytes,
{
u32 boot_mode = get_boot_pin_select();
- /* char cmdbuf[64] = {"\0"}; */
- /* sprintf(cmdbuf, "env export -c -s 0x%lx 0x%lx", (ulong)CONFIG_ENV_SIZE, (ulong)download_buffer); */
- /* if (run_command(cmdbuf, 0)){ */
- /* return -1; */
- /* } */
-
switch(boot_mode){
#ifdef CONFIG_ENV_IS_IN_MMC
case BOOT_MODE_EMMC:
@@ -147,12 +141,6 @@ int _clear_env_part(void *download_buffer, u32 download_bytes,
ret = _fb_mtd_erase(mtd, CONFIG_ENV_SIZE);
if (ret)
return -1;
-
- /*should not write env to env part*/
- /* ret = _fb_mtd_write(mtd, download_buffer, 0, CONFIG_ENV_SIZE, NULL); */
- /* if (ret){ */
- /* pr_err("can not write env to mtd flash\n"); */
- /* } */
}
break;
#endif
@@ -208,7 +196,7 @@ int _write_mtd_partition(struct flash_dev *fdev)
* @brief transfer the string of size 'K' or 'M' to u32 type.
*
* @param reserve_size , the string of size
- * @return int , return the transfer result.
+ * @return int , return the transfer result of KB.
*/
int transfer_string_to_ul(const char *reserve_size)
{
@@ -303,6 +291,7 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
const char *node_file = NULL;
const char *node_offset = NULL;
const char *node_size = NULL;
+ fdev->parts_info[part_index].hidden = false;
cJSON *arraypart = cJSON_GetArrayItem(cj_parts, i);
cJSON *cj_name = cJSON_GetObjectItem(arraypart, "name");
@@ -311,11 +300,12 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
else
node_part = "";
- /*only blk dev would not add bootinfo partition*/
- if (!parse_mtd_partition){
- if (strlen(node_part) > 0 && !strncmp("bootinfo", node_part, 8)){
- pr_info("bootinfo would not add as partition\n");
- continue;
+ cJSON *cj_hidden = cJSON_GetObjectItem(arraypart, "hidden");
+ if (cj_hidden){
+ if ((cj_hidden->type == cJSON_String && strcmp("true", cj_hidden->valuestring) == 0)
+ || cj_hidden->type == cJSON_True){
+ printf("!!!! patr name:%s would set to hidden part !!!!\n", node_part);
+ fdev->parts_info[part_index].hidden = true;
}
}
@@ -374,19 +364,26 @@ int _parse_flash_config(struct flash_dev *fdev, void *load_flash_addr)
if (off > 0)
combine_size = off;
+ /*TODO: support hidden partition for mtd dev*/
if (parse_mtd_partition){
/*parse mtd partition*/
if (strlen(combine_str) == 0)
sprintf(combine_str, "%s%s@%dK(%s)", combine_str, node_size, combine_size, node_part);
else
sprintf(combine_str, "%s,%s@%dK(%s)", combine_str, node_size, combine_size, node_part);
- }else if (fdev->gptinfo.fastboot_flash_gpt){
+ }else if (!fdev->parts_info[part_index].hidden && fdev->gptinfo.fastboot_flash_gpt){
/*parse gpt partition*/
if (strlen(node_offset) == 0)
sprintf(combine_str, "%sname=%s,size=%s;", combine_str, node_part, node_size);
else
sprintf(combine_str, "%sname=%s,start=%s,size=%s;", combine_str, node_part, node_offset, node_size);
}
+
+ /*save part offset and size to byte*/
+ fdev->parts_info[part_index].part_offset = combine_size * 1024;
+ fdev->parts_info[part_index].part_size = transfer_string_to_ul(node_size) * 1024;
+
+ /*save as the next part offset*/
combine_size += transfer_string_to_ul(node_size);
/*after finish recovery, it would free the malloc paramenter at func recovery_show_result*/
diff --git a/include/fb_spacemit.h b/include/fb_spacemit.h
index 801895d7d4..3f633d30a1 100644
--- a/include/fb_spacemit.h
+++ b/include/fb_spacemit.h
@@ -58,8 +58,16 @@ struct flash_volume_image {
struct flash_parts_info {
char *part_name;
char *file_name;
- /*partition size info, such as 128MiB*/
+
+ /*save partition size to string*/
char *size;
+
+ /*partition size info*/
+ u64 part_size;
+
+ /*partition offset info*/
+ u64 part_offset;
+
/*use for fsbl, if hidden that gpt would reserve a raw memeory
for fsbl and the partition is not available.
*/
--
2.25.1
Flashing gzip format image file is not supported
To speed up USB transfers of large image files, SpacemiT’s flashing process compresses them using gzip. By default, the flashing service detects and decompresses gzip data automatically.
If you want to flash gzip images directly to a custom partition (without decompressing), here are two options:
-
Option 1: Skip gzip check for specific partitions For example, to skip gzip handling for a partition named
usbfsas below:diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.cindex 88d8778376..a37cbde596 100644--- a/drivers/fastboot/fb_mmc.c+++ b/drivers/fastboot/fb_mmc.c@@ -689,7 +689,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)return;- if (check_gzip_format((uchar *)download_buffer, src_len) >= 0) {+ if (check_gzip_format((uchar *)download_buffer, src_len) >= 0 && strcmp("usbfs", cmd) != 0) {/*is gzip data and equal part name*/gzip_image = true;if (strcmp(cmd, part_name_t)){ -
Option 2: Disable Gzip Support for Flashing (Not Recommended: Slower Flashing)
//Disable gzip detection in U-Boot//uboot-2022.10diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.cindex 88d8778376..5f8d4f8931 100644--- a/drivers/fastboot/fb_mmc.c+++ b/drivers/fastboot/fb_mmc.c@@ -689,7 +689,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)return;- if (check_gzip_format((uchar *)download_buffer, src_len) >= 0) {+ if (false) {/*is gzip data and equal part name*/gzip_image = true;if (strcmp(cmd, part_name_t)){//Disable image compression with the flash tool//buildroot-ext: You can directly modify the partition_universal.json file inside the flashing package. Make sure the last line in the JSON file does not have a trailing commadiff --git a/board/spacemit/k1/partition_universal.json b/board/spacemit/k1/partition_universal.jsonindex e02a1d0..e9da5a9 100644--- a/board/spacemit/k1/partition_universal.json+++ b/board/spacemit/k1/partition_universal.json@@ -36,15 +36,13 @@"name": "bootfs","offset": "4M","size": "256M",- "image": "bootfs.img",- "compress": "gzip-5"+ "image": "bootfs.img"},{"name": "rootfs","offset": "260M","size": "-",- "image": "rootfs.ext4",- "compress": "gzip-5"+ "image": "rootfs.ext4"}]}