Linux 5.10 + UBIFS RootFS on SPI NOR (W25Q256) + Dual-Kernel Strategy
This article documents a complete OTA firmware update solution on the NUC980 Chili board (with Winbond W25Q256, 32MB, SPI NOR Flash) using:
The design provides:
1. System Architecture Overview
Flash layout (32MB W25Q256):
[td]Name | Start | End | Size |
WHOLE | 0x00000000 | 0x02000000 | 32MB |
uboot | 0x00000000 | 0x000A0000 | 640KB |
kernel1 | 0x000A0000 | 0x004A0000 | 4MB |
kernel2 | 0x004A0000 | 0x008A0000 | 4MB |
rootfs | 0x008A0000 | 0x02000000 | 23MB |
Update flow:
2. Buildroot Setup
Strongly recommended: clone a fresh repository to avoid residual files occupied on kernel image.
$ git clone https://github.com/OpenNuvoton/buildroot_2024
$ cd buildroot_2024
$ make nuvoton_nuc980_chili_defconfig
3. Configure UBIFS as RootFS
$ make menuconfig
Disable RAM filesystem
Filesystem images --->
[ ] initial RAM filesystem linked into linux kernel
[ ] cpio the root filesystem (for use as an initial RAM filesystem)
Enable UBIFS
Filesystem images --->
UBIFS parameters (for W25Q256 SPI NOR)
[td]Parameter | Value |
Physical eraseblock size | 0x10000 |
Sub-page size | 1 |
Logical eraseblock size | 0xFF80 |
Minimum I/O unit size | 0x1 |
Maximum logical eraseblock count | 374 |
Additional mkfs options | -F |
These values must match the SPI NOR geometry.
4. Linux Kernel Configuration
$ make linux-menuconfig
Remove initramfs
General setup --->
[ ] Boot config support
[ ] Initial RAM filesystem and RAM disk support
Enable MTD / UBI / SPI NOR
Device Drivers --->
Memory Technology Device (MTD) support --->
Partition parsers --->
<*> Command line partition table parsing
Enable UBI - Unsorted block images --->
Important: disable 4K sectors (W25Q256 uses 64K erase blocks).
5. Device Tree Partition Layout
Edit the qspi0 session of ./output/build/linux-custom/arch/arm/boot/dts/nuc980-chili.dts
qspi0: spi@b0060000 { status = "okay"; flash: flash@0 { compatible = "jedec,spi-nor"; #address-cells = <1>; #size-cells = <1>; reg = <0>; spi-max-frequency = <30000000>; partition@0 { label = "WHOLE"; reg = <0x00000000 0x02000000>; }; partition@1 { label = "uboot"; reg = <0x00000000 0x000A0000>; }; partition@2 { label = "kernel1"; reg = <0x000A0000 0x00400000>; }; partition@3 { label = "kernel2"; reg = <0x004A0000 0x00400000>; }; partition@4 { label = "rootfs"; reg = <0x008A0000 0x01760000>; }; };};6. Prevent Incorrect mdev Mounting
Since 5 partitions exist, modify ./board/nuvoton/nuc9x0/rootfs-chili/etc/mdev.conf
Change last line:
mtdblock([5-9]+) ...
This prevents unwanted yaffs/jffs2 auto-mount attempts.
7. Add OTA Command to U-Boot
Extract U-Boot source:
$ make uboot-patch
Add following files which are in the attached ZIP to ./output/build/uboot-master/common/ directory.
nuc980_uboot_ota_update_files.zip
Edit ./output/build/uboot-master/common/Makefile
Add following three lines to the Makefile
obj-y += ota_update.oobj-y += check_crc.oobj-y += crc_checksum.oThis adds a custom ota_update command that:
8. U-Boot Environment Configuration
Create env.txt (The file is also in attached ZIP file)
baudrate=115200bootdelay=1stderr=serialstdin=serialstdout=serialimage1_flash_offset=0xA0000image2_flash_offset=0x4A0000image_size=0x400000image1_ram_offset=0x7fc0image2_ram_offset=0x407fc0dtb_flash_offset=0x90000dtb_ram_offset=0x1800000dtb_size=0x10000setspi=sf probe 0 30000000loadkernel1=sf read ${image1_ram_offset} ${image1_flash_offset} ${image_size}loadkernel2=sf read ${image2_ram_offset} ${image2_flash_offset} ${image_size}eraseflash=sf erase ${image1_flash_offset} ${image_size}copykernel=sf write ${image2_ram_offset} ${image1_flash_offset} ${image_size}loaddtb=sf read ${dtb_ram_offset} ${dtb_flash_offset} ${dtb_size}bootcmd=run setspi;run loaddtb;run loadkernel1;run loadkernel2;if ota_update ${image1_ram_offset} ${image2_ram_offset} ${image_size} ${dtb_ram_offset};then run eraseflash;run copykernel;reset;fi;bootargs=noinitrd ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rw console=ttyS0 rdinit=/sbin/init mem=64MBoot logic:
9. Build Everything
$ make
10. Build fwupdate Tool
Setup toolchain:
$ cd
$ source ~/buildroot_2024/output/host/environment_setup
Clone and build:
$ git clone https://github.com/OpenNuvoton/NUC980_Linux_Applications
$ cd NUC980_Linux_Applications/demos/fwupdate
$ make
Copy into rootfs:
$ cp fwupdate ~/buildroot_2024/output/target/usr/bin
$ cd ~/buildroot_2024
$ make
11. Flash Images
From ./output/images directory, use NuWriter to program following files to SPI Flash.
[td]File | Type | Addr/Offset |
uboot.bin | Loader | 0xE00000 |
env.txt | Environment | 0x0080000 |
nuc980-chili.dtb | Data | 0x0090000 |
uImage (kernel1) | Data | 0x00A0000 |
uImage (kernel2) | Data | 0x04A0000 |
rootfs.ubi | Data | 0x08A0000 |
Ensure full erase of rootfs partition before flashing.
12. OTA Update Procedure
For future updates:
Final Notes
This design provides:
| 欢迎光临 牛卧堂MCU技术交流 (http://www.nuvoton-mcu.com/) | Powered by Discuz! X3.2 |