Multi-boot for other OS in Librem 5

I compiled the 5.11.4-librem5 kernel with kexec support, so kexec --load ... worked fine, but I got a black screen on kexec -e… perhaps kexec is broken at the moment? However, I never worked with it before, so maybe I didn’t use it correctly :slight_smile:

There also seems to be some bootmenu support in u-boot, but I don’t know if all required drivers are available in u-boot yet (video/framebuffer etc)?

As a workaround, one could modify the u-boot script to get kexec-like functionality. For this, I added the following at the top of /etc/flash-kernel/bootscript/bootscr.uboot-generic:

if test -z "${alt_boot}"; then
  setenv alt_boot 0
  saveenv
fi

if test "${alt_boot}" -ne 0; then
  setenv alt_boot 0
  saveenv
  setenv bootargs "${alt_cmdline}"
  load ${devtype} ${devnum}:${partition} ${kernel_addr_r} ${alt_kernel} \
  && load ${devtype} ${devnum}:${partition} ${fdt_addr_r} ${alt_fdt} \
  && load ${devtype} ${devnum}:${partition} ${ramdisk_addr_r} ${alt_initrd} \
  && echo "Booting alternative kernel from ${devtype} ${devnum}:${partition}..." \
  && booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
  setenv bootargs
fi

Then run flash-kernel and reboot. Perhaps one should backup the u-boot script /boot/boot.scr before that in case anything goes wrong :wink: The reboot is necessary so that saveenv is called at least once. Now, the idea is to use fw_setenv to modify the u-boot environment variables. For this one needs to create the file /etc/fw_env.config with the following content:

# Block device		Device offset	Env. size
/dev/mmcblk0boot0	0x3fe000	0x2000

To check that this works, one can call fw_printenv, which should show a line alt_boot=0. Now one can run the following to reboot with a new kernel cmdline:

echo 0 > /sys/block/mmcblk0boot0/force_ro
fw_setenv alt_boot 1
fw_setenv alt_kernel vmlinuz
fw_setenv alt_initrd initrd.img
fw_setenv alt_fdt dtb
fw_setenv alt_cmdline "console=ttymxc0,115200 console=tty1 plymouth.enable=0 fsck.repair=yes security=apparmor root=/dev/mmcblk0p2"
sync
echo 1 > /sys/block/mmcblk0boot0/force_ro
reboot

This should reboot PureOS but showing the kernel messages etc instead of the splash screen. The path of alt_kernel etc is relative to /boot/. The next boot should be “normal” again, so the change is not permanent, like a kexec. One needs to call fw_setenv alt_boot 1 again in order to enable the alternative boot settings for the next reboot.

I just booted linux from SD by modifying root in the alt_cmdline :slight_smile: For me this workaround is fine for experiments for now. I guess one could use something like this to get Petitboot to work. Still, it would be cool (and cleaner) to use kexec instead of the workaround above.

7 Likes