Steffen Nurpmeso wrote in
<20230908233854.Xni_j%steffen(a)sdaoden.eu>:
|Michael Kjörling wrote in
| <f948d06c-14f4-40bd-8e32-4db1c5b1dd21(a)home.arpa>:
||On 5 Sep 2023 17:53 +0200, from steffen(a)sdaoden.eu (Steffen Nurpmeso):
...
||> Of course i am no real Linux expert but only a do-it-yourself guy.
||
||If your need is restricted to a highly specific use case and you are
||trying to keep it as small as possible, then it should be possible to
...
Actually maybe someone may find it funny, even though it is
neither historic nor very sophisticated. Let me post it.
In the end it takes some time to get there.
I would expect almost all of you will not be interested in the
lengthy rest of this mail.
Ciao, and a nice Sunday i wish from Germany!
All you need are statically linked busybox (and cryptsetup with
encryption), and a kernel with EFI_STUB on the EFI partition, so
it can be booted directly. The distribution kernels i have
(ArchLinux, AlpineLinux) have it enabled; if your EFI is large
enough you could simply copy it and all its masses of modules to
EFI.
Otherwise the kernel needs all the firmware and modules to boot
and to access all filesystems where the real stuff is. My own
kernel has a lot of things statically built-in, but it can load
more via modules (stage2 uses "the same" kernel later, and does).
Kernels on stage2 need kexec, i have
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_ARCH_HAS_KEXEC_PURGATORY=y
# CONFIG_KEXEC_SIG is not set
CONFIG_KEXEC_CORE=y
-s1.sh and -s2.sh are docu-commented at the top; they can also be
used to create the necessary environment. If i recall correctly
cd /boot
sh linit-init-s2.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP
mount EFI-PARTITION
cd EFI-PARTITION
sh linit-init-s1.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP
This only creates files and directories etc, and beat me if it
does any harm otherwise.
I use a specific naming scheme, the script reacts in particular
on -old and -new to select sensible defaults.
#?0|kent:/boot# ll ideapad*.efi
-rwxr-xr-x 1 root root 10112672 Aug 26 18:44 ideapad-stage1.efi*
-rw-r--r-- 1 root root 10120512 Sep 2 19:52 ideapad-6_1.efi
-rw-r--r-- 1 root root 10120512 Sep 9 18:18 ideapad-6_1-old.efi
-rw-r--r-- 1 root root 10121376 Sep 9 18:18 ideapad-6_1-new.efi
That very kernel (series) is in fact shared in between several
computers of a similar series, kent is the one i write this on:
#?1|kent:/boot# v kent.sh
#!/busybox.static sh
#@ kent, step 1., via EFI.
PART_ROOT=/dev/nvme0n1p?
ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
PART_ROOT1=/dev/nvme0n1p8
ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
INIT_S2=/boot/kent-2.sh
. /linux-init-s1.sh
#?0|kent:/boot# v kent-2.sh
#@ kent, stage 2
KERNEL_ID=ideapad
^ restrict kernel selection for kexec:
^ [ "${k##*$KERNEL_ID-*.efi}" != "$k" ] || continue
PART_SWAP=/dev/nvme0n1p6
SWAP_INPUT=y
^ you can have additional interactive random for swap encryption
^ (it is a lie i use that in practice)
INITRD_PATH=/boot/.kent.initrd
KEXEC_ARGS="--append=\"rtw88_pci.disable_aspm=1 rc.hostname=kent\""
FILE_CHECK='kent-direct.sh kent.sh ideapad-stage1.efi'
SWITCH_ROOT=media/initrd
Stage 2 config file is sourced automatically, so no need to source
linux-init-s2.sh yourself (stage 2 uses switch_root).
I also have a direct boot, but have not used it for long:
#?0|kent:~# v /boot/kent-direct.sh
#!/busybox.static sh
#@ kent-direct, sole step 1., via EFI.
PART_ROOT=/dev/nvme0n1p8
ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
PART_ROOT1=/dev/nvme0n1p8
ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
PART_SWAP=/dev/nvme0n1p6
PIVOT_OLDROOT=media/initrd
. /linux-init-s1.sh
This does not use kexec, but only pivot_root's to the decrypted
filesystem, starting sbin/init there. The kernel from EFI
continues to run.
It is pretty cool how i now can drive several computers easily
simply by creating a shell script with some variable assignments.
In fact the filesystem is shared in between multiple computers
(with only selective partitions being truly unique, but still
backed up everywhere), and all those text configs are in /boot.
Only the VFAT EFI partition is truly system-specific (ie, in that
it only holds the stage1 config file for $HOSTNAME).
I like that very much, and hope Linux continues to be so flexible.
(Not that one day you need systemd-early to get into Linux to get
to systemd-later, or something.)
The EFI boot is driven via efibootmgr(8) and has config like
#@ /root/hosts/self/efiboot
d=/dev/nvme0n1p1
maxno=1
b1=0x01 L1=kent l1=ideapad-stage1
u1='root='${d}' rootfstype=vfat init=/kent.sh'
driven by /root/bin/efiboot.sh (shortened):
#!/bin/sh
: ${HOSTNAME:=$(uname -n)}
: ${DBG:=}
if [ -f /root/hosts/${HOSTNAME}/efiboot ]; then
. /root/hosts/${HOSTNAME}/efiboot
else
echo >&2 "MISS /root/hosts/${HOSTNAME}/efiboot"
exit 1
fi
if [ "$1" = create ]; then
obo=$(efibootmgr | grep -E ^BootOrder: | sed -E
's/^BootOrder:[[:space:]]*//')
if [ -z "$obo" ]; then
echo >&2 'Cannot determine previous boot order'
exit 1
fi
nbo= i=1
while [ $i -le $maxno ]; do
eval ${DBG} efibootmgr -c -b \$b$i -L \\\"\$L$i\\\" -d \$d$i
-l \\\"\$l$i.efi\\\" -u \\\"\$u$i\\\" #>/dev/null
[ -n "$nbo" ] && nbo=$nbo,
eval nbo=\$nbo\$b$i
i=$((i + 1))
done
${DBG} efibootmgr -o $nbo,$obo #> /dev/null
elif [ "$1" = delete ]; then
i=1
while [ $i -le $maxno ]; do
eval ${DBG} efibootmgr -B -b \$b$i #>/dev/null
i=$((i + 1))
done
else
echo >&2 'Synsopsis: efiboot.sh create|delete'
exit 1
fi
${DBG} efibootmgr -v -u
This is of course git managed, so i can distribute it easily.
(Further even, the entire ideapad series configurations differ in
only 193 lines, and most of those are the different SSH keys.
The rest are different device names, ie network, display, volume
etc, disk partitions, host names.)
I am pretty lucky i found a way to manage my systems like this.
I have several git branches in root.git, linux.kconfig, bin,
iwd.network, and one for each computer. I can then "git merge"
selectively together what is necessary. For example my web
vserver only needs bin and its own configuration, whereas the
laptops also need iwd.network. Etc etc. Like this every computer
only knows the selective minimum. The full git repo is on an
encrypted volume stored away.
And it is not Puppet or Ansible or any of those programs, it is
nothing but git and its branches.
But now i really left manually driven cryptsetup by far.
Ciao!
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)