EMMC boot though spi flash?

I dug a into the issue and fortunately it can be handled without recompiling the kernel.

The partition table for mtd is defined in the device tree, originally in the linux kernel source in

/linux/arch/riscv/boot/dts/starfive/jh7110.dtsi

as

partitions {
     compatible = "fixed-partitions";
     #address-cells = <1>;
     #size-cells = <1>;

     spl@0 {
             reg = <0x0 0x20000>;
     };
     uboot@100000 {
             reg = <0x100000 0x300000>;
     };
     data@f00000 {
             reg = <0xf00000 0x100000>;
      };

Unfortunately, this is outdated or was never right.

@mzs posted hopefully better table based on information in JH7110 Boot User Guide and found a glitch there, too.

Now since the device table is separate (binary) file in the /boot directory, the table can be fixed there as a workaround. The procedure is as follows:

# apt-get install device-tree-compiler # get dtc
# cd /boot/boot/dtbs/starfive
# cp jh7110-visionfive-v2.dtb jh7110-visionfive-v2.dtb.orig
# dtc -I dtb -O dts jh7110-visionfive-v2.dtc > jh7110-visionfive-v2.dts # convert to source
# vi jh7110-visionfive-v2.dts # replacing the section as below
# dtc -I dts -O dtb jh7110-visionfive-v2.dts > jh7110-visionfive-v2.dtb # convert to binary
# reboot

The section in question need to be replaced by

partitions {
  compatible = "fixed-partitions";
  #address-cells = <0x01>;
  #size-cells = <0x01>;

  spl@0 {
    reg = <0x00 0x80000>;
  };

  ubootenv@0 {
    reg = <0xF0000 0x10000>;
  };

  payload@100000 {
    reg = <0x100000 0x400000>;
  };

  reserved@600000 {
    reg = <0x600000 0xa00000>;
  };
};            

which is hopefully a bit better.

After the reboot, try

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00080000 00001000 "spl"
mtd1: 00010000 00001000 "ubootenv"
mtd2: 00400000 00001000 "payload"
mtd3: 00a00000 00001000 "reserved"

(Note that the erase sizes shown differ from @mzs 's table.)

Now the u-boot environment should be accessible by fw_printenv. Install the utility using apt-get install libubootenv-tool. The utility must be configured. Create a file /etc/fw_env.config containing:

# MTD device name       Device offset   Env. size       Flash sector size       Number of sectors
/dev/mtd1               0x00000         0x10000         0x10000

Now as good as i understand, the u-boot environment is not persistent by default. Thus fw_printenv would show you an empty environment.

Being connected to the UART, reboot and enter the u-boot dialog:

StarFive # env save

Now /dev/mtd1 is populated and will be used by u-boot. Boot into linux and try:

# fw_printenv
baudrate=115200
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
...
ver=U-Boot 2021.10 (Jan 08 2023 - 18:04:54 +0800)
visionfive2_mem_set=fdt memory ${memory_addr} ${memory_size};

Parts of the configuration is also /etc/u-boot-initial-env, which can best be produced now:

# fw_printenv > /etc/u-boot-initial-env

If anything fails, the original configuration can be restored in u-boot using

StarFive # env default -a

Note that the utility contains a fw_setenv command, too.

Hope it helps, good luck!

4 Likes