EMMC boot though spi flash?

This post suggests that there may be another way to write the U-Boot environment variables, but it seems like there might be issues with it. I haven’t looked into this at all; proceed with caution!

1 Like

The problem I noticed is that the partition table on the QSPI NOR FLASH from Linux is seen as:

|device name|Device offset|Env. size |Flash sector size|Label|
|-----------|-------------|----------|-----------------|-----|
|/dev/mtd1  |0x0000000    |0x00020000|0x00020000       |SPL  |
|/dev/mtd2  |0x0100000    |0x00300000|0x00300000       |UBOOT|
|/dev/mtd3  |0x0F00000    |0x01000000|0x01000000       |DATA |

But the way that it is actually used by U-Boot according to the “JH7110Boot User Guide (page 8)” is:

|device name|Device offset|Env. size |Flash sector size|Contents                         |
|-----------|-------------|----------|-----------------|---------------------------------|
|           |0x0000000    |0x00080000|0x00080000       |SPL                              |
|           |0x00F0000    |0x00010000|0x00010000       |U-Boot environment variables     |
|           |0x0100000    |0x00400000|0x00400000       |fw_payload.img (OpenSBI + U-Boot)|
|           |0x0600000    |0x01000000|0x01000000       |Reseved                          |

So from Linux there is currently no raw partition to access the U-Boot environment variables using “libubootenv”. You could create a new partition that points to the U-Boot environment variables and create a /etc/fw_env.config file that point to that, but probably far safer to wait on the next image to arrive which will probably align the partitions with the documentation, although I just spotted a typo, but it is nothing important.

Hmm, but linux reports yet other sizes:

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00001000 "spl"
mtd1: 00300000 00001000 "uboot"
mtd2: 00100000 00001000 "data"

Note mtd2 is smaller than mtd1 here. While your figures would allow to store a trimmed down kernel into the nor flash, it would not be possible, if /proc/mtd info above were right.

@msz, I would also love to get / set the environment via fw_printenv, but i’m not certain about the geometry, yet. Unfortunately, digging into the u-boot or kernel source does not help much, if the figures there are not right w.r.t. the last partition. One could look at the chips specs, though. Where did you get the sector sizes from, btw?

The RVspace Doc Center is a good place to look for information.
There you will also find the following, for example: Software SDK Developer Guide for U- Boot

2 Likes

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

Since important information like MAC address are storaged inside external eeprom, I think we could completely re-arrange spi partition layout. I think this also might help solve problems happened on current opensuse image:https://en.opensuse.org/HCL:VisionFive2#Manual_Installation
Also, we could separate OpenSBI image and U-Boot to update them independently.

Hmm, while paging through the u-boot env and the related processes, i came over
https://u-boot.readthedocs.io/en/latest/develop/distro.html
I wonder how common u-boot related kernel installations and upgrades currently are. I’ve seen a u-boot-update script in Debian that hooks into the regular kernel installion. Does SuSE have a likely infrastructure or is this all new ground for everyone?

Perhaps this and the next entry in the blog below might be of interest for this topic,
https://blog.mobian.org/posts/2023/01/25/efficient-tooling/
since many distributions struggled to cope commonly with SPI and U-BOOT installations.
https://blog.mobian.org/posts/2022/03/30/universal-images/

1 Like

With new image of debian I just was able to boot without sd card :sunny:
(but just once :anger: )

please make sure you press&hold more than 3 second

1 Like

this is just hard reset - correct?
I just reinstalled image on eMMC and after all it’s booting again, I’ll play now with that to see if it’s everything ok. Eventually I would like to start from m.2 slot only, for now sdcard-less booting is just better than earlier. :slight_smile:

yes, just for hardware reset.

Have you also managed to load SPL and u-Boot from the eMMC, as well? I’m still stuck on that part.

My current setup is:

SPL and U-Boot: SPI flash
FAT boot partition: eMMC
Linux partition: NVMe

I’ve set up partitions 1 and 2 (starting at sectors 4096 and 8192, as described in the JH7110 Boot User Guide), set them with the correct type UUIDs, and copied the u-boot-spl.bin.normal/out and visionfive2_fw_payload.img contents to them, as described in the new section 4.3.2 in the VisionFive2 Quick Start Guide.

But it doesn’t work: When I switch the dip switches to eMMC boot, there is no output.

I see some people have managed to get SD card images that do have working u-Boot installations on them. If I write one of those to an SD card and set the dip switches for SDIO3.0 boot, then u-Boot is read from the SD card.

Has anyone gotten U-Boot to be read from the eMMC device? If so, what’s the magic incantation?

I downloaded starfive-jh7110-202302-eMMC-minimal-desktop.img.bz2 as described and linked here:

Unfortunately, it seems that my new eMMC died and my eMMC to Micro-SD adapter got lost before I could test the current image. But over the course of today, two eMMC should arrive, as well as an eMMC to Micro-SD adapter and a USB 3.1 to eMMC adapter. I have to work a night shift tonight and will probably not be able to report until tomorrow morning.

3 Likes

UPS was here 40 minutes ago and unfortunately I don’t have good results to show.
starfive-jh7110-202302-eMMC-minimal-desktop.img.bz2 was quickly written using USB to eMMC adapter. eMMC inserted into VF2 v1.3B, boot mode set to eMMC, my headless terminal (Raspberry Zero W with USB to UART adapter) started, logged in and Minicom started, then VF2 switched on. Red LED comes on, green LED doesn’t even blink and not a single character arrives in Minicom!

VF2 switched off, boot mode set to SDIO and VF2 switched on again. System starts normally, so I start tightvncserver so that I can comfortably start gparted on the headless VF2. eMMC is recognised and expanding the / partition happens without problems. VF2 switched off, boot mode set to eMMC, green LED does not flash again, but at least something arrives in the Minicom, five lines are written with each new power on.

ÿdwmci_d: DATA ERROR!
dwmci_s: Timeout.
BOOT fail,Error is 0xffffffff
dwmci_s: Response Timeout.
BOOT fail,Error is 0xffffffff

Tomorrow, after the night shift, I will first do a firmware upgrade of the QSPI flash to v2.10.4 to try to boot the eMMC in QSPI flash boot mode and then put the VF2 v1.3B aside and try my VF2 v1.2A with an eMMC instead.

2 Likes

Let me just introduce a little bit about how I do it.

  1. Switch boot mode to SDIO, then power up and boot it from TF card;
  2. Transfer eMMC image into system (either over ethernet or USB etc.) ;
  3. Use dd command to flash eMMC image into eMMC(mmcblk0), such as dd if=starfive-jh7110-202302-eMMC-minimal-desktop.img of=/dev/mmcblk0 bs=4M status=progress
  4. Input sync command and power down;
  5. Switch boot mode to eMMC mode and power up;

Note:
Please make sure you press&hold the reset button for more than 3 seconds if you need reset the system.

2 Likes

I have repeated all the steps again using your method. Unfortunately, I can only very rarely boot an eMMC on my Kickstarter Early Bird - 4GB VF2 v1.3B after many resets.

I just remembered, at first the boot from eMMC worked, I was able to install openssh-server with keyboard and screen, change the passwords of root and user and after a reboot I was able to install headless my favourite editor, setup using apt-cacher-ng as proxy, as well as set up my bash environment for my liking. later I take a break shut down the system and hours later could only boot it with difficulty sometimes.

On my 8GB VF2 v1.2A from Waveshare I then carried out all the steps with a second 64GB eMMC and so far everything works here.

I will test the two “non-functioning” eMMC 32GB and 64GB with the VF2 v1.2A later.

I get these bus speed messages on the debug terminal very rarely with the VF2 v1.2A and very often with the VF2 v1.3B.

[   12.935725] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 400000Hz, actual 399193HZ )
[   13.192614] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 100000000Hz, actual 990000)
[   13.768426] starfive-eth-plat 16030000.ethernet end0: Link is Up - 1Gbps/Full - flow control rx/x

Debian GNU/Linux
Debian GNU/Linux bookworm/sid vfive2-8 hvc0

vfive2-8 login:  bookworm/sid vfive2-8 ttyS0

vfive2-8 login: [   34.486172] mipi_0p9: disabling
[   39.445859] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 400000Hz, actual 399193HZ )
[   39.712463] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 100000000Hz, actual 990000)

I use the same PD power supply on both boards and have also installed the same cooler/fan combination.

2 Likes

@SunWukong are there any log outputting from unbootable board?

Most often, I get this message when I connect the power supply or do a reset:

dwmci_s: Response Timeout.
BOOT fail,Error is 0xffffffff
dwmci_s: Response Timeout.
BOOT fail,Error is 0xffffffff

I must correct myself, in the meantime I can do a cold start as often as I want, no other message comes up.

For clarity, I have attached my boot mode settings as a photo.
Boot mode eMMC

By the way, after setting up the eMMC using your method, I did not change anything on my 4GB VF2 v1.3B except the boot mode. Now I will boot from SD again.

For clarification, I have attached my, now changed, boot mode settings again as a photo.
Boot mode SDIO3.0

Now the log, from the boot from the SD, while the eMMC is still inserted.

It gave me no peace and I tried to boot from eMMC a few more times, this time again with success. Here is the boot log:

After a few minutes, these messages were recorded.

vfive2-4 login: [   34.484858] mipi_0p9: disabling
[   40.054464] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 400000Hz, actual 399193HZ div = 248)
[   40.297621] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 100000000Hz, actual 99000000HZ div = 1)
[   52.405321] mmc0: cache flush error -110
[   52.624411] mmc_host mmc0: Bus speed (slot 0) = 198000000Hz (slot req 400000Hz, actual 399193HZ div = 248)
[   54.136729] mmc0: tried to HW reset card, got error -110
[   54.142093] mmcblk0: recovery failed!
[   54.145897] blk_update_request: I/O error, dev mmcblk0, sector 2321376 op 0x1:(WRITE) flags 0x800 phys_seg 3 prio class 0
[   54.157129] Aborting journal on device mmcblk0p4-8.
[   54.164594] EXT4-fs error (device mmcblk0p4): ext4_journal_check_start:83: comm systemd-journal: Detected aborted journal
[   54.172669] mmcblk0: recovery failed!
[   54.179324] blk_update_request: I/O error, dev mmcblk0, sector 2318336 op 0x1:(WRITE) flags 0x20800 phys_seg 1 prio class 0
[   54.190472] Buffer I/O error on dev mmcblk0p4, logical block 262144, lost sync page write
[   54.198667] JBD2: Error -5 detected when updating journal superblock for mmcblk0p4-8.
[   54.216911] mmcblk0: recovery failed!
[   54.220578] blk_update_request: I/O error, dev mmcblk0, sector 221184 op 0x1:(WRITE) flags 0x23800 phys_seg 1 prio class 0
[   54.231648] Buffer I/O error on dev mmcblk0p4, logical block 0, lost sync page write
[   54.239531] EXT4-fs (mmcblk0p4): I/O error while writing superblock
[   54.245851] EXT4-fs (mmcblk0p4): Remounting filesystem read-only
[   58.416492] mmcblk0: recovery failed!
[   58.420267] blk_update_request: I/O error, dev mmcblk0, sector 221192 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   58.431605] Buffer I/O error on dev mmcblk0p4, logical block 1, lost async page write
[   58.449277] mmcblk0: recovery failed!
[   58.452983] blk_update_request: I/O error, dev mmcblk0, sector 223320 op 0x1:(WRITE) flags 0x103000 phys_seg 2 prio class 0
[   58.464138] Buffer I/O error on dev mmcblk0p4, logical block 267, lost async page write
[   58.472162] Buffer I/O error on dev mmcblk0p4, logical block 268, lost async page write
[   58.489946] mmcblk0: recovery failed!
[   58.493641] blk_update_request: I/O error, dev mmcblk0, sector 223352 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   58.504798] Buffer I/O error on dev mmcblk0p4, logical block 271, lost async page write
[   58.522432] mmcblk0: recovery failed!
[   58.526143] blk_update_request: I/O error, dev mmcblk0, sector 223488 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   58.537298] Buffer I/O error on dev mmcblk0p4, logical block 288, lost async page write
[   58.555078] mmcblk0: recovery failed!
[   58.558760] blk_update_request: I/O error, dev mmcblk0, sector 223552 op 0x1:(WRITE) flags 0x103000 phys_seg 4 prio class 0
[   58.569920] Buffer I/O error on dev mmcblk0p4, logical block 296, lost async page write
[   58.577943] Buffer I/O error on dev mmcblk0p4, logical block 297, lost async page write
[   58.585966] Buffer I/O error on dev mmcblk0p4, logical block 298, lost async page write
[   58.603610] mmcblk0: recovery failed!
[   58.607300] blk_update_request: I/O error, dev mmcblk0, sector 223608 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   58.628226] mmcblk0: recovery failed!
[   58.631932] blk_update_request: I/O error, dev mmcblk0, sector 223760 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   58.652853] mmcblk0: recovery failed!
[   58.667104] mmcblk0: recovery failed!
[   58.681367] mmcblk0: recovery failed!
[   58.695599] mmcblk0: recovery failed!
[   58.709935] mmcblk0: recovery failed!
[   58.724180] mmcblk0: recovery failed!
[   58.738478] mmcblk0: recovery failed!
[   58.752809] mmcblk0: recovery failed!
[   58.767069] mmcblk0: recovery failed!
[   58.781352] mmcblk0: recovery failed!
[   58.795728] mmcblk0: recovery failed!
[   58.809922] mmcblk0: recovery failed!
[   58.824215] mmcblk0: recovery failed!
[   58.838599] mmcblk0: recovery failed!
[   58.852796] mmcblk0: recovery failed!
[   58.867110] mmcblk0: recovery failed!
[   58.881448] mmcblk0: recovery failed!
[   58.895696] mmcblk0: recovery failed!
[   58.909968] mmcblk0: recovery failed!
[   58.924302] mmcblk0: recovery failed!
[   58.938543] mmcblk0: recovery failed!
[   58.952812] mmcblk0: recovery failed!
[   58.967184] mmcblk0: recovery failed!
[   58.981378] mmcblk0: recovery failed!
[   58.995686] mmcblk0: recovery failed!
[   59.010022] mmcblk0: recovery failed!
[   59.024217] mmcblk0: recovery failed!
[   59.038488] mmcblk0: recovery failed!
[   59.052819] mmcblk0: recovery failed!
[   59.067079] mmcblk0: recovery failed!
[   59.081334] mmcblk0: recovery failed!
[   59.095706] mmcblk0: recovery failed!
[   59.109900] mmcblk0: recovery failed!
[   59.124148] mmcblk0: recovery failed!
[   59.138526] mmcblk0: recovery failed!
[   59.152718] mmcblk0: recovery failed!
[   59.156479] print_req_error: 35 callbacks suppressed
[   59.156493] blk_update_request: I/O error, dev mmcblk0, sector 4415488 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   59.182453] mmcblk0: recovery failed!
[   59.186206] blk_update_request: I/O error, dev mmcblk0, sector 4415616 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   59.197487] buffer_io_error: 50 callbacks suppressed
[   59.197501] Buffer I/O error on dev mmcblk0p4, logical block 524304, lost async page write
[   59.220413] mmcblk0: recovery failed!
[   59.224090] blk_update_request: I/O error, dev mmcblk0, sector 4415744 op 0x1:(WRITE) flags 0x103000 phys_seg 2 prio class 0
[   59.234503] mmcblk0: recovery failed!
[   59.235332] Buffer I/O error on dev mmcblk0p4, logical block 524320, lost async page write
[   59.247282] Buffer I/O error on dev mmcblk0p4, logical block 524321, lost async page write
[   59.255615] blk_update_request: I/O error, dev mmcblk0, sector 4677648 op 0x1:(WRITE) flags 0x103000 phys_seg 1 prio class 0
[   59.266874] Buffer I/O error on dev mmcblk0p4, logical block 557058, lost async page write
[  172.271745] mmc0: cache flush error -110
[  172.718977] mmc0: tried to HW reset card, got error -110
[  172.724409] mmcblk0: recovery failed!
[  172.728221] blk_update_request: I/O error, dev mmcblk0, sector 1540072 op 0x0:(READ) flags 0x80700 phys_seg 4 prio class 0
[  172.750250] mmcblk0: recovery failed!
[  172.753988] blk_update_request: I/O error, dev mmcblk0, sector 1540072 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[  293.514518] mmcblk0: recovery failed!
[  293.518227] blk_update_request: I/O error, dev mmcblk0, sector 1540072 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[  414.264491] mmcblk0: recovery failed!
[  414.268268] blk_update_request: I/O error, dev mmcblk0, sector 1540072 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[  535.013142] mmcblk0: recovery failed!
[  535.016927] blk_update_request: I/O error, dev mmcblk0, sector 1540072 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
1 Like

This eMMC module works well on your VF2 1.2A, right? Maybe I assume this is the connection issue? or is there some thing on your J9 connctor ?

2 Likes

I also thought of a connection issue with the module last time. Before the last attempt on the 20th, I had pressed the module firmly onto the board, but as careful as I always am, not firmly enough. After you expressed your suspicions, I took another close look at the board from the side and saw that the eMMC module was sitting very slightly crooked. It looks like the module was not pressed into J99 properly, which means that J9 is not making good contact. So I pressed the module into J99 with a lot of force and now it works perfectly.

6 Likes