Milk-V Mars CM (eMMC)

U-Boot for the Mars CM uses the same U-Boot binaries as the VisionFive 2 board. Devicetree selection is made in U-Boot SPL at runtime, dependent on the content of EEPROM.

Device-tree selection

U-Boot will set variable $fdtfile to starfive/jh7110-milkv-marscm-emmc.dtb dependent on the content of EEPROM.

To overrule this selection the variable can be set manually and saved in the environment

env set fdtfile my_device-tree.dtb
env save

StarFive JH-7110 RISC-V SoC

  • JH-7110 working frequency 1.5GHz ambient operating temperature range -20 ℃ to +85 ℃ (JH-7110 Datasheet)

  • JH-7110I working frequency 1.5GHz ambient operating temperature range -40 ℃ to +85 ℃ (JH-7110I Datasheet)

  • JH-7110S working frequency 1.25GHz

JH-7110 is a 4+1 core RISC-V System on Chip:

  • U74-MC Core Complex

    • S7 monitor core RV64IMAC

      • Physical Memory Protection

      • 16KB L1 Instruction cache

      • 8KB Data Tightly-Integrated Memory

    • U74 application core RV64GC (x4)

      • Sv39 Memory Management Unit

      • Floating Point Unit

      • 32KB L1 Instruction cache

      • 32KB L1 Data cache

      • Physical Memory Protection

    • Core-Local INTerruptor

    • Platform-Level Interrupt Controller

    • Debug

    • Bus Matrix

      • 2MB L2 cache

        • Memory Port → 128-bit AXI4

      • System Port → 64-bit AXI4

      • Peripheral Port → 64-bit AXI4

      • Front Port ← 64-bit AXI4

  • Block

    • RV32IMAFCB E24 co-processor

      • 16KB Instruction cache

      • 32KB Tightly-Integrated Memory “A”

      • 32KB Tightly-Integrated Memory “B”

    • Mailbox

    • SGDMA

  • Network-on-Chip/AXI bus

  • Memory

    • SRAM 256KB/BootROM 32KB

    • LPDDR4/DDR4/LPDDR3/DDR3 32-bit 2800 Mbps (2133 Mbps supported working speed)

    • QSPI Flash Controller

  • Interfaces

    • PCIe2.0 1-lane x2

    • Ethernet MAC 10/100/1000 Mbps x2

    • USB 2.0 Host/Device

    • SDIO3.0 x2

    • CAN2.0B x2

  • Audio

    • Cadence Tensilica HiFi-4 Audio DSP defined by U74MC or E24

      • 4x 32x32-bit MACs

      • some 72-bit accumulators

      • limited support for 8x 32x16-bit MACs

      • fourth VLIW slot

      • two 64-bit loads per cycle

      • optional floating point unit for four single-precision MACs per cycle

    • I2S/PCM-TDM

    • I2S/PCM

    • PDM x4

    • SPDIF

  • Graphics

    • Epicsemi ISP

    • IMG BXE-4-32 Integrated GPU with 3D Acceleration

    • 12-bit DVP

    • MIPI-CSI

  • Cryptographic function

    • TRNG

    • OTP

    • Security HW Engine AES/DES/3DES/HASH/PKA

  • Block

    • PAD_SHARE used for reset

    • Power Management Unit Clock Reset Generator

    • PLL x3

    • JTAG

    • RTC

    • Temperature Sensor

Supported SoC drivers:

  • ns16550 UART

  • StarFive JH-7110 clock

  • StarFive JH-7110 reset

  • Cadence QSPI controller

  • DesignWare MMC for eMMC/SD support

  • PLDA PCIe controller

  • Cadence USB2.0/3.0 controller

Supported common peripherals:

  • AXP15060 Power Management Unit

  • LPDDR4 2GB / 4GB / 8GB DRAM memory

  • AT24C04F 4K bits (512 x 8) EEPROM

  • QSPI NOR Flash 16M or SoC ROM UART loader for boot (selectable by GPIO)

Extra supported peripherals present on some boards:

  • Motorcomm YT8531C Gigabit Ethernet PHY

  • On-board VL805 PCIE-USB controller driver

  • Status LED RGPIO3

Build U-Boot

  1. Add a RISC-V toolchain to your PATH.

  2. Set cross compilation environment variable if needed:

    export CROSS_COMPILE=<riscv64 toolchain prefix>
    
  3. U-Boot for JH-7110 requires OpenSBI v1.5+ generic platform object fw_dynamic.bin to be included in the Flattened Image Tree blob. OpenSBI may first be built as below:

    # clone and/or update OpenSBI sources
    git clone https://github.com/riscv/opensbi.git opensbi.git
    git -C opensbi.git checkout v1.7
    # always clean build directory when building OpenSBI due to incomplete
    # dependency tracking
    make -C opensbi.git -O opensbi clean
    make -C opensbi.git -O opensbi PLATFORM=generic
    
  4. Now build the First Stage BootLoader (U-Boot Secondary Program Loader) and Second Boot Loader (OpenSBI + U-Boot Main):

    git clone https://source.denx.de/u-boot/u-boot.git u-boot.git
    make -C u-boot.git -O u-boot starfive_visionfive2_defconfig
    export OPENSBI=opensbi/build/platform/generic/firmware/fw_dynamic.bin
    make -C u-boot.git -O u-boot
    

    This will generate the U-Boot SPL image object post-processed with StarFive SPL headers (u-boot/spl/u-boot-spl.bin.normal.out) as well as the FIT image (u-boot/u-boot.itb) of OpenSBI and U-Boot Main.

    Note: Debug UART is not available from U-Boot SPL when U-Boot Main uses the SBI interface for this. Add the following configuration changes above to enable early debug UART in U-Boot SPL:

    u-boot.git/scripts/config --file u-boot/.config \
     --set-val DEBUG_UART_BASE 0x10000000 \
     --set-val DEBUG_UART_CLOCK 24000000 \
     --enable DEBUG_UART_NS16550 \
     --disable DEBUG_SBI_CONSOLE \
     --set-val SPL_DEBUG_UART_BASE 0x10000000 \
     --set-val DEBUG_UART_SHIFT 2
    
    make -C u-boot.git -O u-boot olddefconfig
    

Boot description

JH-7110 reset vectors (one 36-bit address per each of four U7 cores) are located split into four pairs of SYS SYSCON registers. The default value for all four reset vectors is 2a000000.

Execute-in-place BootROM code located at 2a000000 is not published by StarFive however may be generally described as deciding based on [RGPIO2:RGPIO0] state where to transfer SPL data from, verify headers and CRC, and then jump to code execution in L2 LIM.

Zero Stage Program Loader

RGPIO2

Boot Vector

ZSPL function

0

0x2A00_0000

On-chip 32KB BootROM

1

0x2100_0000

QSPI XIP Flash (256mb)

JH-7110 ZSPL functionally consists of the selection of reset vector register defaults at chip-design time in concert with BootROM code at 2a000000. JH-7110 Technical Reference Manual says “if XIP flash is disabled in OTP configuration, system cannot boot from XIP flash”. Presumably there is some OTP configuration involved but there is no documentation available with which to expand on that topic.

Zero Stage BootLoader

JH-7110 ZSBL is typically StarFive loader code in BootROM selected by RGPIO2 pull-down.

RGPIO1

RGPIO0

StarFive loader function @ 0x2A00_0000

0

0

1-bit QSPI Flash offset 0x0

0

1

SDIO3.0 (deprecated)

1

0

eMMC5.0 or eMMC5.1 (deprecated)

1

1

UART Serial XMODEM loader

According to JH-7110 Boot User Guide BootROM the StarFive loader code reads content to SRAM @ 0x0800_0000 from different media selected by [RGPIO1,RGPIO0].

Description of StarFive loader by the StarFive VisionFive2 board maintainer:

The SD card boot mode is supported but the mmc driver of BootROM is not compatible with a few SD cards. If you can’t boot from a SD card, you can change another card for a try.

The eMMC boot mode loads SPL from sector 0, while the SD card boot mode loads GPT header from sector 1 and then finds the partition whose GUID is 2E54B353-1271-4842-806F-E436D6AF6985 to load SPL. So if we try to use GPT partition in eMMC, it will fail to boot and report CRC (stored at 0x290) failure. The workaround is using the backup load address. After the CRC failure happens, it will try to load the SPL from the backup address (stored at 0x4~0x7). That is why we write 0x00100000 to 0x4~0x7. But this workaround is not a standard process and may destroy the partition information stored in sector 0.

There are additional unexplained GUID references in the JH-7110 MaskROM so the description given is not complete. Attribution and modifications to the GPL2.0+ source code used in StarFive loader have not been published as of this writing. Due to the lack of verifiable documentation the upstream Linux devicetree does not contain hints for mmc0 and mmc1 interfaces to be included in U-Boot SPL. As of U-Boot release v2025.10 and newer the U-Boot specific devicetree override of hints for mmc0 and mmc1 interfaces that are required for the deprecated modes have been dropped marking the deprecation of these boot modes in U-Boot.

Supported modes in U-Boot SPL are QSPI Flash and UART Serial XMODEM loader as accepted by upstream Linux Kernel for StarFive JH-7110 common devicetree.

First Stage BootLoader

JH-7110 FSBL is typically U-Boot SPL or any vendor flash programming tool.

U-Boot SPL initializes DRAM and configures PLLs needed by CPU and peripherals.

RGPIO1

RGPIO0

U-Boot SPL function

0

0

BOOT_DEVICE_SPI @ offset 0x100000 (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)

0

1

BOOT_DEVICE_MMC2 @ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION

1

0

BOOT_DEVICE_MMC1 @ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION

1

1

BOOT_DEVICE_UART @ YMODEM

U-Boot SPL function is selected by configuration of [RGPIO1:RGPIO0] then copies data to the start of DRAM and executes.

Address

Description

0x040000000

start of DRAM

0x240000000

uncached alias of DRAM

Note: The largest DRAM size with JH7110 is 8GB because the uncached alias of DRAM begins at +8GB following the start of DRAM.

Second Stage BootLoader (OpenSBI fw_dynamic.bin + U-Boot Main)

U-Boot Main is supported in S-mode and depends on prior stage M-mode SBI runtime services provided by OpenSBI FW_DYNAMIC firmware.

Loading U-Boot

Vendored versions of U-Boot (as pre-installed on supported boards) are generally capable in U-Boot console of UART data transfer and updating QSPI Flash. Additionally there may be a vendor Board Support Package using the deprecated SDIO3.0 / eMMC5.0 boot modes. It is not documented here how to update U-Boot in vendor BSP data images, nor use of the deprecated boot modes. The recommended upgrade path is to update QSPI Flash in U-Boot console or from GNU/Linux OS.

Flash offset

Length

Data source

0x000000

0x0f0000 (CONFIG_ENV_OFFSET)

u-boot/spl/u-boot-spl.bin.normal.out

0x0f0000

0x010000 (CONFIG_ENV_SIZE)

runtime generated defaults if bad CRC

0x100000

0xf00000

u-boot/u-boot.itb

Recovery U-Boot console

With UART serial USB adapter and tio serial terminal:

tio /dev/ttyUSB0 -o 1
    tio 3.9
    Press ctrl-t q to quit
    Connected to /dev/ttyUSB0

# Power on the board with [RGPIO1:RGPI0]=3
    (C)StarFive
    CC
    (C)StarFive
    CCC

(Control-t-x)
    Please enter which X modem protocol to use:
     (0) XMODEM-1K send
     (1) XMODEM-CRC send
     (2) XMODEM-CRC receive

0
    Send file with XMODEM-1K
    Enter file name:

u-boot/spl/u-boot-spl.bin.normal.out
    Sending file 'u-boot/spl/u-boot-spl.bin.normal.out'
    Press any key to abort transfer
    ...|
    Done

# U-Boot SPL on the board with [RGPIO1:RGPI0]=3
    U-Boot SPL 2025.10 (Oct 23 2025 - 17:01:49 -0700)
    DDR version: dc2e84f0.
    Trying to boot from UART
    CCC

(Control-t-y)
    Send file with YMODEM
    Enter file name:

u-boot/u-boot.itb
    Sending file 'u-boot/u-boot.itb'
    Press any key to abort transfer
    ...|
    Done
    Loaded 3122637 bytes

    OpenSBI v1.7
       ____                    _____ ____ _____
      / __ \                  / ____|  _ \_   _|
     | |  | |_ __   ___ _ __ | (___ | |_) || |
     | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
     | |__| | |_) |  __/ | | |____) | |_) || |_
      \____/| .__/ \___|_| |_|_____/|____/_____|
            | |
            |_|

    Platform Name               : Pine64 Star64
    Platform Features           : medeleg
    Platform HART Count         : 4
    Platform IPI Device         : aclint-mswi
    Platform Timer Device       : aclint-mtimer @ 4000000Hz
    Platform Console Device     : uart8250
    Platform HSM Device         : ---
    Platform PMU Device         : ---
    Platform Reboot Device      : pm-reset
    Platform Shutdown Device    : pm-reset
    Platform Suspend Device     : ---
    Platform CPPC Device        : ---
    Firmware Base               : 0x40000000
    Firmware Size               : 353 KB
    Firmware RW Offset          : 0x40000
    Firmware RW Size            : 97 KB
    Firmware Heap Offset        : 0x4c000
    Firmware Heap Size          : 49 KB (total), 3 KB (reserved), 12 KB (used), 33 KB (free)
    Firmware Scratch Size       : 4096 B (total), 400 B (used), 3696 B (free)
    Runtime SBI Version         : 3.0
    Standard SBI Extensions     : time,rfnc,ipi,base,hsm,srst,pmu,dbcn,fwft,legacy,dbtr,sse
    Experimental SBI Extensions : none

    Domain0 Name                : root
    Domain0 Boot HART           : 4
    Domain0 HARTs               : 1*,2*,3*,4*
    Domain0 Region00            : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
    Domain0 Region01            : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
    Domain0 Region02            : 0x0000000040040000-0x000000004005ffff M: (R,W) S/U: ()
    Domain0 Region03            : 0x0000000040000000-0x000000004003ffff M: (R,X) S/U: ()
    Domain0 Region04            : 0x000000000c000000-0x000000000fffffff M: (I,R,W) S/U: (R,W)
    Domain0 Region05            : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
    Domain0 Next Address        : 0x0000000040200000
    Domain0 Next Arg1           : 0x0000000042200000
    Domain0 Next Mode           : S-mode
    Domain0 SysReset            : yes
    Domain0 SysSuspend          : yes

    Boot HART ID                : 4
    Boot HART Domain            : root
    Boot HART Priv Version      : v1.11
    Boot HART Base ISA          : rv64imafdcbx
    Boot HART ISA Extensions    : zihpm,sdtrig
    Boot HART PMP Count         : 8
    Boot HART PMP Granularity   : 12 bits
    Boot HART PMP Address Bits  : 34
    Boot HART MHPM Info         : 2 (0x00000018)
    Boot HART Debug Triggers    : 8 triggers
    Boot HART MIDELEG           : 0x0000000000000222
    Boot HART MEDELEG           : 0x000000000000b109


    U-Boot 2025.10 (Oct 23 2025 - 17:01:49 -0700)

    CPU:   sifive,u74-mc
    Model: Pine64 Star64
    DRAM:  4 GiB
    Core:  160 devices, 29 uclasses, devicetree: board
    WDT:   Not starting watchdog@13070000
    MMC:   mmc@16010000: 0, mmc@16020000: 1
    Loading Environment from SPIFlash...
    SF: Detected gd25lq128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
    *** Warning - bad CRC, using default environment

    StarFive EEPROM format v2

    --------EEPROM INFO--------
    Vendor : PINE64
    Product full SN: STAR64V1-2310-D004E000-0000xxxx
    data version: 0x2
    PCB revision: 0xc1
    BOM revision: A
    Ethernet MAC0 address: 6c:cf:39:00:xx:xx
    Ethernet MAC1 address: 6c:cf:39:00:xx:xx
    --------EEPROM INFO--------

    starfive_7110_pcie pcie@9c0000000: Starfive PCIe bus probed.
    In:    serial@10000000
    Out:   serial@10000000
    Err:   serial@10000000
    Net:   eth0: ethernet@16030000, eth1: ethernet@16040000
    starting USB...
    Register 2000820 NbrPorts 2
    Starting the controller
    USB XHCI 1.00
    Bus usb@0: 4 USB Device(s) found
           scanning usb for storage devices... 0 Storage Device(s) found
    Working FDT set to ff717fe0
    Hit any key to stop autoboot: 2 1 0

(enter)
    StarFive #

Update QSPI Flash using U-Boot console

With UART serial USB adapter and tio serial terminal:

tio /dev/ttyUSB0 -o 1
    tio 3.9
    Press ctrl-t q to quit
    Connected to /dev/ttyUSB0

(enter)
    StarFive #

sf probe
    StarFive # sf probe
    SF: Detected gd25lq128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB

loady && sf update $loadaddr 0 $filesize
    StarFive # loady && sf update $loadaddr 0 $filesize
    ## Ready for binary (ymodem) download to 0x82000000 at 115200 bps...
    CCC

(Control-t-y)
    Send file with YMODEM
    Enter file name:

u-boot/spl/u-boot-spl.bin.normal.out
    Sending file 'u-boot/spl/u-boot-spl.bin.normal.out'
    Press any key to abort transfer
    ...|
    Done
    ## Total Size      = 0x00024eb7 = 151223 Bytes
    ## Start Addr      = 0x82000000
    device 0 offset 0x0, size 0x24eb7
    151223 bytes written, 0 bytes skipped in 0.634s, speed 243096 B/s
    StarFive #

env erase
    StarFive # env erase
    Erasing Environment on SPIFlash... OK
    StarFive #

loady && sf update $loadaddr 100000 $filesize
    StarFive # loady $loadaddr && sf update $loadaddr 100000 $filesize
    ## Ready for binary (ymodem) download to 0x82000000 at 115200 bps...
    CCC

(Control-t-y)
    Send file with YMODEM
    Enter file name:

u-boot/u-boot.itb
    Sending file 'u-boot/u-boot.itb'
    Press any key to abort transfer
    ...|
    Done
    ## Total Size      = 0x002fa5cd = 3122637 Bytes
    ## Start Addr      = 0x82000000
    device 0 offset 0x100000, size 0x2fa5cd
    3122637 bytes written, 0 bytes skipped in 18.137s, speed 176272 B/s
    StarFive #

Update QSPI Flash from GNU/Linux OS

With mtd-utils:

cat /proc/mtd
    dev:    size   erasesize  name
    mtd0: 000f0000 00001000 "spl"
    mtd1: 00010000 00001000 "uboot-env"
    mtd2: 00f00000 00001000 "uboot"

flashcp --verbose u-boot/spl/u-boot-spl.bin.normal.out /dev/mtd0
    Erasing blocks: 37/37 (100%)
    Writing data: 147k/147k (100%)
    Verifying data: 147k/147k (100%)

flashcp --verbose --erase-all /dev/zero /dev/mtd1
    Erasing blocks: 16/16 (100%)
    Writing data: 0k/0k (100%)
    Verifying data: 0k/0k (100%)

flashcp --verbose u-boot/u-boot.itb /dev/mtd2
    Erasing blocks: 763/763 (100%)
    Writing data: 3049k/3049k (100%)
    Verifying data: 3049k/3049k (100%)