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
- Installation instructions see YouTube video.
- After booting, log into the router via ssh.
- 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
- Log in to the router via ssh.
- Create a copy (snapshot) of the current system:
schnapps create "Snapshot for the SSD"
- Check what number the snapshot got:
schnapps list
- Connect an USB stick to the router and mount it:
mkdir /mnt/usb
mount /dev/sdb1 /mnt/usb
- 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.
- For example, this creates the following files:
Prepare SSD
- Install the “cfdisk” program:
opkg update
opkg install cfdisk
- Partition SSD:
cfdisk /dev/sda
- If no partition table has been created yet, cfdisk asks first for the type. I chose the old type (DOS) here.
- Create at least one primary partition using the New button, which should be at least as large as the original partition (from the eMMC).
- Use the Bootable button to mark the partition as bootable (probably not necessary).
- Write the partition data to the SSD using the Write button.
- Quit cfdisk using the Quit button
- Now the new partition must exist as /dev/sda1 in the file system.
- Format new partition:
mkfs.btrfs /dev/sda1
- Mount partition:
mkdir /mnt/ssd
mount /dev/sda1 /mnt/ssd
- Create BTRFS subvolume for the root directory:
btrfs subvol create /mnt/ssd/@
- 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
- Connect the serial cable to the router and the PC (USB). This is described in detail here.
- Launch the serial console on the PC. On a Linux PC e.g. with:
sudo screen /dev/ttyUSB0 115200
- 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.
- 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
- 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
- They can also be checked individually with:
printenv boot_prefixes
printenv boot_targets
- 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.
- Now the temporary change can be tested with:
run distro_bootcmd
- 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=/@)
- 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
- 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.:
- Log into the router via ssh or serial console.
- Back up the current system with:
schnapps create "Initial version on SSD"
- 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
.