找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[NUC980] Implementing OTA Firmware Update on NUC980 Chili Board

[复制链接]
跳转到指定楼层
楼主

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:

  • Buildroot 2024 / Linux kernel 5.10
  • UBIFS as root filesystem
  • Dual-kernel layout (kernel1/kernel2)
  • Custom U-Boot OTA command
  • fwupdate userspace tool

The design provides:

  • UBIFS rootfs on SPI NOR
  • Safe kernel update via A/B strategy
  • Automatic copy from kernel2 → kernel1 after validation

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:

  • System runs kernel1.
  • OTA writes new kernel to kernel2.
  • On next boot, U-Boot validates kernel2.
  • If valid → copy to kernel1.
  • Reset and boot updated system.

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  --->
   

ubi image containing an ubifs root filesystem

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  --->
           

UBI Fastmap
        SPI NOR device support  --->
            [ ] Use small 4096 B erase sectors

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.

  • ota_update.c
  • check_crc.c / .h
  • crc_checksum.c / .h

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.o

This adds a custom ota_update command that:

  • Validates kernel2
  • Performs CRC check
  • Returns success/failure

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=64M

Boot logic:

  • Always load both kernels
  • If kernel2 valid and differ from kernel1 → copy to kernel1
  • Reset system
  • Otherwise continue booting kernel1

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:

  • Use NuWriter to pack new kernel image (targeting kernel2 offset).
  • Transfer pack file to device.
  • Run fwupdate to overwrite kernel2 region.
  • Reboot.
  • U-Boot validates and copies kernel2 → kernel1.
  • System reboots into updated firmware.

Final Notes

This design provides:

  • UBIFS rootfs on SPI NOR
  • Dual-kernel safety
  • CRC-verified upgrade
  • No NAND required
  • No initramfs dependency
  • Deterministic boot behavior







分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
牛卧堂
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU