Boot from SSD - Outdated description?

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:

Unfortunately, rescueboot will still work only with eMMC. I haven’t looked into that yet, but looking at it’s boot variable suggests that this behaviour might be hardcoded into the FW of some internal chip.

All this change does is shifting all recovery modes upwards by 1 (which @adminX already mentioned here), so that we could boot from mmc0 on LED 2:

  • 1 LED: (Re)boot to SSD
  • 2 LEDs: (Re)boot to eMMC
  • 3 LEDs: Rollback to latest snapshot on eMMC
  • etc.

I quess it might be more readable what happens in that modified bootcmd if we format it:

bootcmd=i2c dev 1;  #select the button device
i2c read 0x2a 0x9 1 0x00FFFFF0;  #read number of LEDs from the button memory (this number is actually shifted, so 1 == 2 LEDs are shining)
setexpr.b rescue *0x00FFFFF0;  #append number of LEDs to the rescue variable
if test $rescue -ge 1; then  #if rescue is equal or greater than 1, then...
    setexpr rescue $rescue - 1;  #subtract 1 from rescue
    if test $rescue -ge 1; then  #if rescue is equal or greater than 1, then run rescueboot
        echo BOOT RESCUE;
        run rescueboot;
    else echo BOOT eMMC FS;  #otherwise boot from eMMC
        run mmcboot;
    fi;
else echo BOOT SSD FS;  # otherwise boot from SSD
    run ssdboot;
fi

To be honest, I can’t remember where I made that assumption. Looking back at the schnapps script, it appears to be still used

You actually could install multiple internal drives by using additional SATA controller in one of the available mPCI slots, which is what I’m planning to do, therefore using UUID seemed like a good idea

I’ve set it that way so that if I break something, I could easily reboot to a functional OS from which I will be able to repair the SSD. Since the rescue modes apply only to the internal eMMC memory, I can’t go back one snapshot using the back button anymore.

The current rescue version can do this if root=/dev/sda1. This may be why the official docs add scsiboot (called ssdboot in mine) and replace root=b301 (meaning /dev/mmcblk0p1) with root=/dev/sda1 in bootargs.

You will lose the MMC based fallback but all rescue modes work on the SSD the same way the work with MMC.

The controller is not detected until after TurrisOS is booted. You can’t boot from them so using UUID is not a great idea as you lose most rescue functionality.

You can use the rescue modes with SSD if root=/dev/sda1. Rescue modes then apply to the SSD and not the MMC.

possible rescue usage with different configurations

Rescue Mode 4 (5 LEDS, Rescue Shell) always works.
Rescue Mode 6 (7 LEDs, Rescue Shell on serial) also works independent of the root setting.
All other Modes depend on root=/dev/sda1 or use MMC.

Replace TurrisOS with another OS on SSD

My goal was to replace TurrisOS(OpenWRT) with a full fledged Linux distribution running on SSD. My ssdboot command even sets different bootargs for the SSD based boot.
This does not support schnapps and required a rescue environment. The main OS on MMC is the rescue system in this case. All rescue modes should work with this “rescue” installtion so if i killed the TurrisOS in MMC i could use medkit to restore it without touching the SSD. This even happened once.

Replace MMC with TurrisOS on mSATA SSD

In this case the rescue modes should not access the MMC but the SSD.
The rescue system handles the special case for root=/dev/sda1 only. In every other case it assumes MMC.
Using root=/dev/sda1 is safe for this configuration because this connects to the platform AHCI controller which is running even before the USB controllers are detected. USB drives do not matter in this case.
So root=/dev/sda1 should be prefered as it allows using all rescue modes the same way they would work on MMC but on SSD.

Replace MMC with TurrisOS on USB drive

If there are multiple USB drives connected you will have to use UUID and lose the rescue modes.
If there is a mSATA SSD you will have to use UUID and lose the rescue modes.
If there is a single USB drive only then root=/dev/sda1 works and allows using all rescue modes for USB.

Other configurations

If you replaced u-boot to enable other hardware as a boot devices you should know what you are doing.
Stock Omnia u-boot can only boot from MMC, mSATA, USB, SPI-Flash (rescue) and maybe network. Network boot does not need a rescue function as it is one.

2 Likes

Nope, verified it doesn’t work. I have SSD boot configured per https://doc.turris.cz/doc/cs/howto/omnia_booting_from_external_storage#spousteni_ze_ssd, with root=/dev/sda1, but rollback (2 LED) doesn’t work. It doesn’t do anything but reboot the router twice (probably once into the rescue boot menu, and then normal reboot). I have the oldest Omnia from Indiegogo. Isn’t what you say true only for the newer Omnias?

🐉 ahead: click to open...

I assume the following is correct and checked as best as possible with my configuration but was not executed as i don’t want to reboot my router now.

If you have a pre-2019 Omnia this needs the updated old rescue image. It basically is:

cd /tmp
wget https://repo.turris.cz/omnia-stable/nor_fw/omnia-initramfs-zimage
mtd -e /dev/mtd1 omnia-initramfs-zimage /dev/mtd1

For some background on flashing and recovering the older images:

Newer Omnias have multiple differences in hardware, u-boot and rescue images. More information about the changes and upcoming changes for older Omnias are in the thread below: