Boot from SSD - Outdated description?

Hi,

I want to boot my Turris Omnia router from a mSata SSD instead of using the eMMC. My router is a 2019 version with the latest, stable system installed.

I tried to follow the instructions on the following page: https://doc.turris.cz/doc/en/howto/omnia_booting_from_external_storage. I was able to interrupt the U-Boot bootloader by pressing the Enter key in the serial console and then got the ‘⇒’ prompt. However, I was unable to run the ‘run rescueboot’ command because the rescueboot argument is unknown.
After that I tried another way - without knowing whether this was really an alternative. I booted the router directly into rescue mode with a special reset command and logged into the router via SSH, with the PC connected directly to LAN port 4. I think this has only been possible since the 2019 version of the Omnia router. I was able to log in without a password, but I’m not sure if this mode (run level?) is the same as booting with the ‘run rescueboot’ command.
However in this mode (or run level) I am missing the device of my SSD. There is only one /dev/sd? device - that of my USB stick. After the router has started normally, both devices (/dev/sda and /dev/sdb) are present.

Any ideas what is going wrong?

Is it still possible to boot from an SSD and use it via the eMMC?

Thanks in advance,

Heiko

1 Like

Try :slight_smile: rescueboot run :slight_smile:

1 Like

IIRW the 2019 version has new uboot (and boot script) so probably the uboot environment description for ssd boot is outdated.
Did you try

env default -a

at uboot promp?
You might be able to find the default uboot environment in the gitlab if this does not work.
Here is my uboot environment for booting from /dev/sda1 in an old omnia version

Summary

root@turris:~# fw_printenv baudrate=115200 bootdelay=3 ethact=neta2 fdt_high=0x10000000 initrd_high=0x10000000 rescueboot=i2c mw 0x2a.1 0x3 0x1c 1; i2c mw 0x2a.1 0x4 0x1c 1; mw.l 0x01000000 0x00ff000c; i2c write 0x01000000 0x2a.1 0x5 4 -s; setenv bootargs "$bootargs omniarescue=$rescue"; sf probe; sf read 0x1000000 0x100000 0x700000; bootz 0x1000000 openwrt_bootargs=earlyprintk console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=auto rootwait openwrt_mmcload=setenv bootargs "$openwrt_bootargs cfg80211.freg=$regdomain"; fatload mmc 0 0x01000000 zImage; fatload mmc 0 0x02000000 armada-385-turris-omnia.dtb factory_mmcload=setenv bootargs "$bootargs cfg80211.freg=$regdomain"; btrload mmc 0 0x01000000 boot/zImage @; btrload mmc 0 0x02000000 boot/dtb @ mmcboot=run openwrt_mmcload || run factory_mmcload; bootz 0x01000000 - 0x02000000 bootargs=earlyprintk console=ttyS0,115200 rootfstype=btrfs rootwait root=/dev/sda1 rootflags=subvol=@,commit=5 rw bootcmd=i2c dev 1; i2c read 0x2a 0x9 1 0x00FFFFF0; setexpr.b rescue *0x00FFFFF0; if test $rescue -ge 1; then echo BOOT RESCUE; run rescueboot; else echo BOOT eMMC FS; run scsiboot; fi scsiboot=setenv bootargs "$bootargs cfg80211.freg=$regdomain"; scsi scan; btrload scsi 0:1 0x01000000 boot/zImage @; btrload scsi 0:1 0x02000000 boot/dtb @; bootz 0x01000000 - 0x02000000

1 Like

Thanks, but it also doesn’t work.

Hi,

I’ve tried setting “env default -a”, but after that neither “run rescueboot” nor “rescueboot run” works.

I don’t understand your second suggestion.

In the original document at first the SSD was partioned and formated with BTRFS. After that the saved snapshot was recovered on the SSD. At least the new boot commands args were saved.

Is your summary only the environment part of the steps?

Do you’ve run these commands in the rescue mode or in the normal mode?

What do you mean with default uboot environment?

Thanks for your help,

Heiko

ok I am not an expert. IIRW, you could try “env default -a” and then “saveenv”. If this works you will boot from the emmc as before what you have done.
If this doesn’t work, put here the output of “printenv” for someone with new uboot to help you.
You could also search in gitlab for the default settings(environment) in uboot so you could set them with setenv command at uboot prompt.
Otherwise, you will need to contact the support.
PS: Uboot is a boot loader (like grub). Read this for more info.
PS2: Do you access uboot using uart cable?

1 Like

Thanks, your information pointed me in the right direction. I’ve just booted the router the first time from the SSD.
My u-boot environment is different from yours and also from the one in the description from Turris. In my environment a lot of things are already done for booting the system from a SSD. I’m going to make some tests to be sure everything is running and ok and I also must make the changes permanent with saveenv - I think. After that I’ll post my steps to boot from SSD.

But it would be helpful, if you could answer the following questions:

  1. Does the command “env default -a” reset all environment variables to it’s factory state?
  2. Until now, I’ve never run the command “saveenv”. If I run printenv at the u-boot prompt, everything is fine, but if I run fw_printenv at the normal system prompt, an error message about an CRC error is printed. Is the reason for that, that I’ve never run saveenv before?
  1. I think so

  2. If you do not issue “saveenv” after the next boot it is likelly that your changes will be lost. Some people argue that “saveenv” is inherent in “setenv” but i do not know if this is true for the uboot version used on omnia.

  3. The CRC error probably means that your /etc/fw_env.config is not properly set. Here is mine

    root@turris:~# cat /etc/fw_env.config
    /dev/mtd0 0xC0000 0x10000 0x40000

ps: you could paste here your environment for future reference by other users

1 Like

I’ve the same content in the file /etc/fw_env.config. Therefore the warning “Warning: Bad CRC, using default environment” must have another reason. But everything else is working now. I think that I’ll open another thread for this issue.

I’ve just written down all the necessary steps to boot from a mSata SSD. I think, that it will be useful to post it here (together with the original output of printenv on my router, as you suggested).

Probably /etc/fw_env.config has wrong configuration for the new uboot on your 2019 omnia. Search the forum first for the new uboot, then If none else answers here contact the support and ask them for the correct values (maybe @Pepe could provide them?). You could also try (not easy) to determine these values yourself using the instructions in the openwrt wiki.

edit: check also this
edit2: Here is your answer

1 Like

How to boot from a mSata SSD
The steps listed below differ from the steps in the original instructions. They (the steps below) apply to a Turris Omnia Router from 2019 (TurrisOS 5.1.4, U-Boot 19.7). The decisive difference, however, lies in the environment of the U-Boot bootloader.
The environment of the U-Boot loader can be output with printenv via the serial console in the U-Boot loader prompt. In the version on which this is based, most of it is already intended for booting the system from the SSD. The printenv command delivered the following original environment before the changes:

Original environment
arch=arm
baudrate=115200
board=turris_omnia
board_name=turris_omnia
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr ${fdtcontroladdr};fi;load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_net_pci_enum=pci enum
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets=mmc0 scsi0 usb0 pxe dhcp 
bootcmd=run distro_bootcmd
bootcmd_dhcp=run boot_net_usb_start; run boot_net_pci_enum; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00010:UNDI:003000;setenv bootp_arch 0xa;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
bootcmd_mmc0=devnum=0; run mmc_boot
bootcmd_pxe=run boot_net_usb_start; run boot_net_pci_enum; dhcp; if pxe get; then pxe boot; fi
bootcmd_scsi0=devnum=0; run scsi_boot
bootcmd_usb0=devnum=0; run usb_boot
bootdelay=3
console=ttyS0,115200
cpu=armv7
distro_bootcmd=scsi_need_init=; for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
eth1addr=d8:58:d7:01:37:87
eth2addr=d8:58:d7:01:37:88
ethact=ethernet@34000
ethaddr=d8:58:d7:01:37:89
fdt_addr_r=0x2000000
fdt_high=0x10000000
fdtcontroladdr=7fb43a68
fdtfile=armada-385-turris-omnia.dtb
initrd_high=0x10000000
kernel_addr_r=0x1000000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
omnia_reset=0
pxefile_addr_r=0x1900000
ramdisk_addr_r=0x2200000
regdomain=**
sata_boot=if sata dev ${devnum}; then devtype=sata; run scan_dev_for_boot_part; fi
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x1800000
scsi_boot=run scsi_init; if scsi dev ${devnum}; then devtype=scsi; run scan_dev_for_boot_part; fi
scsi_init=if ${scsi_need_init}; then scsi_need_init=false; scsi scan; fi
soc=mvebu
stderr=serial@12000
stdin=serial@12000
stdout=serial@12000
usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi
vendor=CZ.NIC

Environment size: 4356/65532 bytes

The environment consists of a number of variables. Some of them define values and possible alternatives and other commands are executed during the boot process. The following changes must be made so that the SSD can be booted:
setenv boot_prefixes / /boot/ /@/boot/
setenv boot_targets scsi0 mmc0 usb0 pxe dhcp

All the necessary steps including these changes are described below.

Installation of an mSata SSD in the router
  1. Installation instructions see YouTube video.
  2. After booting, log into the router via ssh.
  3. Verify that the SSD is recognized:
    ls /dev/sd*
    If no USB stick has been inserted and the SSD has not yet been partitioned, the command should return the following output:
    /dev/sda
Back up the system for the SSD
  1. Log in to the router via ssh.
  2. Create a copy (snapshot) of the current system:
    schnapps create "Snapshot for the SSD"
  3. Check what number the snapshot got:
    schnapps list
  4. Connect an USB stick to the router and mount it:
    mkdir /mnt/usb
    mount /dev/sdb1 /mnt/usb
  5. Export the snapshot (e.g. with the number 3) to the USB stick:
    schnapps export 3 /mnt/usb
    • For example, this creates the following files:
      /mnt/usb/omnia-medkit-rhodan-3.info
      /mnt/usb/omnia-medkit-rhodan-3.tar.gz
    • The latter is required below to prepare the SSD.
Prepare SSD
  1. Install the “cfdisk” program:
    opkg update
    opkg install cfdisk
  2. Partition SSD:
    cfdisk /dev/sda
    1. If no partition table has been created yet, cfdisk asks first for the type. I chose the old type (DOS) here.
    2. Create at least one primary partition using the New button, which should be at least as large as the original partition (from the eMMC).
    3. Use the Bootable button to mark the partition as bootable (probably not necessary).
    4. Write the partition data to the SSD using the Write button.
    5. Quit cfdisk using the Quit button
    6. Now the new partition must exist as /dev/sda1 in the file system.
  3. Format new partition:
    mkfs.btrfs /dev/sda1
  4. Mount partition:
    mkdir /mnt/ssd
    mount /dev/sda1 /mnt/ssd
  5. Create BTRFS subvolume for the root directory:
    btrfs subvol create /mnt/ssd/@
  6. Copy the secured system from the USB stick to the SSD:
    cd /mnt/ssd/@
    tar -xfvf /mnt/usb/omnia-medkit-rhodan-3.tar.gz
    • The file omnia-medkit-rhodan-3.tar.gz will have a different name for everyone. It was created with schnapps above.
Set up bootloader U-Boot for the SSD
  1. Connect the serial cable to the router and the PC (USB). This is described in detail here.
  2. Launch the serial console on the PC. On a Linux PC e.g. with:
    sudo screen /dev/ttyUSB0 115200
  3. Restart the router and immediately press the “RETURN” key several times until the U-Boot prompt “=>” appears. This works best if the router can be switched on from the PC via a smart socket, since you only have a few seconds (approx. 3). But you can also enter the command “reboot” and watch the right moment after shutting down.
  4. The U-Boot environment can now be checked with the following command (it is best to switch on the log file beforehand with “Ctrl-a H”; the Ctrl-a commands are probably dependent on the program used - here screen):
    printenv
  5. In particular, the two variables to be changed should look like this before the change:
    boot_prefixes=/ /boot/
    boot_targets=mmc0 scsi0 usb0 pxe dhcp
  6. They can also be checked individually with:
    printenv boot_prefixes
    printenv boot_targets
  7. Temporary changes for booting from the SSD (temporary means that the changes will be gone with the next reboot; this is recommended for the first attempt):
    setenv boot_prefixes / /boot/ /@/boot/
    setenv boot_targets scsi0 mmc0 usb0 pxe dhcp
    • The first change takes into account that the boot directory with the script file to be started is located in the subvolume @.
    • The second one changes the boot sequence from mmc0, scsi0,… to scsi0, mmc0. The SSD is “hidden” behind scsi0.
  8. Now the temporary change can be tested with:
    run distro_bootcmd
  9. If everything goes as desired, the router will now boot from the SSD. This can be checked after booting using the mount command:
    mount
    In the output you can see that the root directory (/) has now been mounted by /dev/sda1. That looks e.g. like this:
    /dev/sda1 on / type btrfs (rw,noatime,ssd,space_cache,commit=5,subvolid=257,subvol=/@)
  10. In order to write the changes permanently to the router, it must be rebooted again via the serial console into the “=>” prompt. The following commands must now be entered here:
    setenv boot_prefixes / /boot/ /@/boot/
    setenv boot_targets scsi0 mmc0 usb0 pxe dhcp
    saveenv
  11. Finally boot the router with (the serial console is no longer required afterwards):
    run distro_bootcmd
Final work

According to the original instructions, it is still necessary to configure schnapps for the new root partition. But this should not be true for the current version. Therefore I’ve removed this step.:

  1. Log into the router via ssh or serial console.
  2. Back up the current system with:
    schnapps create "Initial version on SSD"
  3. Read the “Problems ahead” section in the original Document.

Note: In my original posting - and original setup - I wrote the line ROOT_DEV="/dev/sda1" to the file /etc/schnapps/config. Now this is not only superfluous, but also bad. With this option the command schnaps -d /mnt create always creates a backup of the Root partition and ignores the option -d.

9 Likes

Thanks, the link to the answer “fixed” the problem with fw_printenv.

For which version of operating system the above procedure applies ?

1 Like

The procedure applies for
TurrisOS: 5.1.4
U-Boot: 2019.07

I think the U-Boot version is the relevant one. But I suspect that the environment variables do not only depend on the U-Boot version.

If I understand correctly, there is also a change underway in the next 5.1.5 update or later for old omnias.

2 Likes

I think you are right, I’ve read this also at another place.

The environment looks a little bit different from mine, but it contains the same variables (with similar values - only " usb0 pxe dhcp" is missing), that I’ve changed and therefore I think, that my instructions should work too after that update on the old routers.

That article on user wiki has been outdated for quite some time, schnapps actually has been rewritten to accommodate for changed root partition automatically, also the configuration has been moved under UCI (/etc/config/schnapps)

Btw, I think your solution with changing those two variables is by far one of the simplest. What I did personally was a bit more involved, inspired by these two posts on the forum:

1 Like

sda for the internal SSD always worked for me even if there was an external USB SSD connected.
But this may have changed and be more complicated with multiple SATA drives.

My real bootcmd is

bootcmd=i2c dev 1; i2c read 0x2a 0x9 1 0x00FFFFF0; setexpr.b rescue *0x00FFFFF0 ; if test $rescue -ge 1 ; then setexpr rescue $rescue - 1 ; if test $rescue -ge 1 ; then echo BOOT RESCUE ; run rescueboot ; else echo BOOT eMMC FS ; run mmcboot ; fi ; else echo BOOT SSD FS ; run ssdboot ; fi

It supports mmcboot as first rescue mode with all other rescue modes shifted upwards. I didn’t publish it back then as i was concerned someone will forget it and wonder why rescue modes not work like they should.

2 Likes

Thanks for the hint, so /etc/schnapps/config won’t be used any more?

It seems, that you’re a schnapps expert. Therefore it would be fine, if you could take a look at the following post.

You’re right, in general using the UUID is better, but I think the only way you can get into trouble is if you have two internal hard drives - which the Omnia Router can’t do. As far as I know, USB devices are always created later.

Last year I’ve lost my first Omnia router, caused by a dammaged eMMC :sob:
Therefore I hope, that I must never ever use the eMMC again :slight_smile:

Thanks for the hints.

Interesting. And if you run the rescueboot using this way, does it work with SSD? Or only with eMMC? Actually, how would it know which one to alter? :slight_smile: