Bootloader bauen auf Basis von Bekanntem mit u‑root

Daniel Maslowski Agenda

Introduction u‑root as a Build Tool Booting Kernels with kexec Understanding Bootloaders Introduction Recap: LinuxBoot Let do it provides device drivers and networking initramfs with utilities, bootloader, whatever you wish on top of vendor UEFI : remove DXEs, build Linux with EFI stub u‑root

A universal root filesystem written in Golang, easily portable all open, meant for studying and understanding many small Unix‑like tools offers various bootloaders tooling for single binary with multiple entry points like BusyBox

https://u‑root.org/ u‑root as a Build Tool Building an initrd

The u-root command builds an initrd and can be given files, templates, and additional Go sources to be built in. u-root\ -filesfiles/rc.elv:.elvish/rc.elv\ -filesbootsplash.png\ bootcore github.com/u-root/u-root/cmds/exp/fbsplash Templates A select few templates exist for common applications, such as core utilities and boot utilities.

templates.go

/* ... */ "boot": { "github.com/u-root/u-root/cmds/boot/*boot*", }, // Absolutely everything, including experimental commands. "world": { "github.com/u-root/u-root/cmds/*/*", }, // Core should be things you don't want to live without. "core": { "github.com/u-root/u-root/cmds/core/*", }, /* ... */ Booting Kernels with kexec Prerequisites

$ man kexec

DESCRIPTION kexec is a system call that enables you to load and boot into another kernel from the currently running kernel. kexec performs the function of the boot loader from within the kernel. The primary difference between a standard system boot and a kexec boot is that the hardware initialization normally performed by the BIOS or firmware (depending on architecture) is not performed during a kexec boot. This has the effect of reducing the time required for a reboot.

Make sure you have selected CONFIG_KEXEC=y when configuring the kernel. The CONFIG_KEXEC option enables the kexec system call. kexec After Kernel Upgrade

#!/bin/sh

CMDLINE=`cat /proc/cmdline`

kexec \ --load /boot/vmlinuz-linux \ --append="$CMDLINE" \ --initrd=/boot/initramfs-linux.img

kexec -e What kexec does entry = 0x33b5f7740 flags = 0x3e0000 nr_segments = 4 segment[0].buf = 0x7f23954d9010 segment[0].bufsz = 0x188eade segment[0].mem = 0x336f71000 segment[0].memsz = 0x188f000 segment[1].buf = 0x7f2396d6be10 segment[1].bufsz = 0x72d460 segment[1].mem = 0x338800000 segment[1].memsz = 0x2d4a000 segment[2].buf = 0x556c6262bd70 segment[2].bufsz = 0x3f4b segment[2].mem = 0x33b5f3000 segment[2].memsz = 0x4000 segment[3].buf = 0x556c62624b70 segment[3].bufsz = 0x70e0 segment[3].mem = 0x33b5f7000 segment[3].memsz = 0x9000 What the BIOS does

$ journalctl -b-1 -o cat | grep 'BIOS-'

BIOS-provided physical RAM map: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved BIOS-e820: [mem 0x0000000000100000-0x00000000bff24fff] usable BIOS-e820: [mem 0x00000000bff25000-0x00000000c29fffff] reserved BIOS-e820: [mem 0x00000000f0000000-0x00000000f3ffffff] reserved BIOS-e820: [mem 0x00000000fed40000-0x00000000fed44fff] reserved BIOS-e820: [mem 0x00000000fed90000-0x00000000fed91fff] reserved BIOS-e820: [mem 0x0000000100000000-0x000000033b5fffff] usable kexec, which is a bootloader in disguise, uses the original E820 layout to pass to the kexec‑ed kernel.

See arch/x86/kernel/e820.c#L45 :) From Firmware to Kernel

https://0xax.gitbooks.io/linux‑insides/content/Booting/linux‑bootstrap‑ 1.html Using u‑root’s kexec import ( "github.com/u-root/u-root/pkg/boot" "github.com/u-root/u-root/pkg/boot/kexec" ) func main() { /* read files ... */ image := &boot.LinuxImage{ Kernel: kernel, Initrd: initrd, Cmdline: cmdline, } if err := image.Load(true); err != nil { log.Fatalf("error failed to kexec into new kernel:%v", err) } if err := kexec.Reboot(); err != nil { log.Fatalf("error failed to Reboot into new kernel:%v", err) } } Understanding Bootloaders $ ls pkg/boot/{grub,}/ pkg/boot/grub/: config_test.go entry.go grub.go testdata/ echo_test.go entry_test.go grub_test.go testdata_new/

pkg/boot/syslinux/: config_test.go syslinux.go syslinux_test.go testdata/

GRUB and syslinux

very well‑known bootloaders used by many distros, both on disk and live ISOs configuration files mostly well‑documented ▶ we could just write new parsers ▶ mostly supported in u‑root by now ▶ GRUB is more complex GRUB and syslinux

very well‑known bootloaders used by many distros, both on disk and live ISOs configuration files mostly well‑documented ▶ we could just write new parsers ▶ mostly supported in u‑root by now ▶ GRUB is more complex $ ls pkg/boot/{grub,syslinux}/ pkg/boot/grub/: config_test.go entry.go grub.go testdata/ echo_test.go entry_test.go grub_test.go testdata_new/

pkg/boot/syslinux/: config_test.go syslinux.go syslinux_test.go testdata/ Example

title Fedora 19 (Rawhide) version 3.8.0-2.fc19.x86_64 machine-id 6a9857a393724b7a981ebb5b8495b9ea options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 architecture x64 linux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux initrd /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd

BLS (Boot Loader Spec) / sd‑boot

https://systemd.io/BOOT_LOADER_SPECIFICATION/ … single boot configuration format that is based on drop‑in files BLS (Boot Loader Spec) / sd‑boot

https://systemd.io/BOOT_LOADER_SPECIFICATION/ … single boot configuration format that is based on drop‑in files Example

title Fedora 19 (Rawhide) version 3.8.0-2.fc19.x86_64 machine-id 6a9857a393724b7a981ebb5b8495b9ea options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 architecture x64 linux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux initrd /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd Bootloader Support in u‑root

u‑root supports a wide range of bootloader applications. $ ls pkg/boot/ acpi/ ebda/ jsonboot/ multiboot/ util/ bls/ esxi/ kexec/ multiboot.go zimage/ bootcmd/ grub/ linux.go netboot/ boot.go ibft/ linux_test.go stboot/ boottest/ initrd.go localboot/ syslinux/ bzimage/ initrd_test.go menu/ systembooter/ webboot wraps u‑root’s build tool to create an initramfs ▶ includes Wi‑Fi utilities from NiChrome uses u‑root’s pkgs to parse and boot ISO images ▶ for unsupported distros, pass boot config manually offers a menu with bookmarks ▶ custom entries can be created easily run webboot from and cache ISOs on USB drive ▶ it could run from flash with LinuxBoot Questions? 樂 Links

Slides ▶ https://metaspora.org/u‑root‑bootloaders‑LinuxDay2020.pdf ▶ https://github.com/orangecms/u‑root‑bootloaders u‑root project https://u‑root.org GitHub ▶ https://github.com/u‑root/u‑root ▶ https://github.com/u‑root/webboot Thanks! 