postmarketos-initramfs: switch to udev and kmod (MR 5000)

mdev is slow and missing features, it also requires that we load all the
modules that we include at once making the boot process slower.

udev is required for unl0kr (and buffyboard), it can also load modules
on demand (and asynchronously). Making the boot process considerably
faster on devices, especially for generic images where we have lots of
drivers for different display panels in the initramfs.

Additionally, import full fat modprobe from the kmod package, this is
required to support compressed modules.

This brings us more in line with other distros and generally improves
compatibility.

If devices use broken kernel modules which don't correctly define
modalias', these drivers may not be loaded by udev. This should be fixed
by defining the missing modalias statements in the driver.

This also runs udev earlier in the init, so that display drivers are
loaded before the splash in case they are needed.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Co-authored-by: Clayton Craft <clayton@craftyguy.net>

[ci:ignore-count]
[ci:skip-build]: already built successfully in CI
This commit is contained in:
Caleb Connolly 2024-04-28 16:20:14 +02:00 committed by Clayton Craft
parent 54ef5cdf15
commit 7c98127746
No known key found for this signature in database
GPG key ID: 4A4CED6D7EDF950A
5 changed files with 40 additions and 86 deletions

View file

@ -3,13 +3,19 @@
/bin/sh
/etc/deviceinfo
/etc/unudhcpd.conf
/lib/mdev/persistent-storage
/sbin/blkid
/usr/bin/iskey
/sbin/modprobe
/usr/bin/unudhcpd
/usr/sbin/kpartx
/usr/share/deviceinfo/deviceinfo
/usr/share/initramfs/init.sh:/init
/usr/share/initramfs/init_functions.sh:/init_functions.sh
/usr/share/initramfs/mdev.conf:/etc/mdev.conf
/usr/share/misc/source_deviceinfo
/usr/bin/iskey
/usr/share/libinput/*.quirks
/bin/udevadm
/sbin/udevd
/etc/udev/rules.d
/lib/udev/rules.d
/lib/udev/scsi_id

View file

@ -1,7 +1,7 @@
# Maintainer: Oliver Smith <ollieparanoid@postmarketos.org>
# Co-Maintainer: Clayton Craft <clayton@craftyguy.net>
pkgname=postmarketos-initramfs
pkgver=3.0.0
pkgver=3.1.0
pkgrel=0
pkgdesc="Base files for the postmarketOS initramfs / initramfs-extra"
url="https://postmarketos.org"
@ -20,13 +20,13 @@ depends="
e2fsprogs-extra
f2fs-tools
iskey
kmod
lz4
mdevd
mdev-conf
multipath-tools
parted
postmarketos-fde-unlocker
postmarketos-mkinitfs>=2.2
udev
unudhcpd
util-linux-misc
xz
@ -39,7 +39,6 @@ source="
init.sh
init_functions.sh
unudhcpd.conf
mdev.conf
"
arch="noarch"
license="GPL-2.0-or-later"
@ -78,9 +77,6 @@ package() {
-t "$pkgdir"/usr/share/mkinitfs/files-extra/
mkdir -p "$pkgdir"/etc/mkinitfs/files-extra
install -Dm644 "$srcdir"/mdev.conf \
-t "$pkgdir"/usr/share/initramfs/
mkdir -p "$pkgdir"/usr/share/mkinitfs/hooks
mkdir -p "$pkgdir"/usr/share/mkinitfs/hooks-extra
mkdir -p "$pkgdir"/etc/mkinitfs/hooks
@ -90,10 +86,9 @@ package() {
sha512sums="
59be0649ed87a72d93624bd8a2e3f8c99a0f32f7b7a26f99436de782beba55671472c269eeee86440efc87e0d7148a0bb335fa537791092e73878ca21330544a 00-default.modules
9c0e8f6f61d5da191e03a1aa9d5d0ceb5baf1eae6dbb9bfb0af59817783525119ac8394b135f303f7b6434a3eab0b49185fb90379e06823db847a4999c75ce33 00-initramfs-base.dirs
0fed7dfdf940f5de15ca2fa636214d44ee8549afe5001b81beb0e337e865eb737916e158bc0ed7a7803adc81176386ae8edfc21150de62bb136fdfcdcb888b8b 00-initramfs-base.files
1c64d2da2013213467dfaa40e984e3a7c7e8a885d3327fe164f1e1c091eb9c9f2dfadcc7e1e1ef8a0e7fa36513b2216b4bde97d58c2528a637821a31800ccd34 00-initramfs-base.files
8a4adad3785af474b36a09a05f6a3b2c4b4f43aac331a53b903abfa51ea12be1e3d1d807b7a6e66a1346815f3b0044daf8cd62e21e2dc75d2db13ee265a72985 00-initramfs-extra-base.files
a993c8d3dadf54c7ef942c726f8e238194cf7ad8f9d8d1c43991f1ac9d5f4ec57a72f8005b122ee06bcf5b6fdf22a635cdb234aee2173d073196f7a6f7788ffe init.sh
817c58403af779401932758d70a7c84d6d76a457b60327c1913e1758b66e6dbb19c4fcea8f0d4268e07f86f1b041e8fba47f9b01543c732c84d7c13cca1ff622 init_functions.sh
749865c52a229569c0cd346dd97fe10d49361124eba95bd0dbb25d0737d1efc139c8e2e31f4b7654747ffecfa77403886f1e1fe7d548d47aee03ced43d8ef2eb init.sh
1d3337ace7611853579945dc6563556ced66f386a7f906835425bac9e45c7734682b85b381656dfd5d3b0a727a39e5718e77f0d19af42562c199df25ea9fda59 init_functions.sh
ba3275a9af788c7c782322a22a0f144d5e50e3498ea6886486a29331f23ae89cd32d500a3635cfa7cab369afba92edc18aeca64ccbf0cd589061cce23d15b46c unudhcpd.conf
675e7d5bee39b2df7d322117f8dcaccc274d61beaf4d50ead19bbf2109446d64b1c0aa0c5b4f9846eb6c1c403418f28f6364eff4537ba41120fbfcbc484b7da7 mdev.conf
"

View file

@ -26,18 +26,17 @@ export PATH=/usr/bin:/bin:/usr/sbin:/sbin
mount_proc_sys_dev
setup_log
setup_firmware_path
# Run udev early, before splash, to make sure any relevant display drivers are
# loaded in time
setup_udev
if [ "$IN_CI" = "false" ]; then
# shellcheck disable=SC2154
load_modules /lib/modules/initramfs.load "libcomposite"
setup_framebuffer
show_splash "Loading..."
setup_mdev
setup_dynamic_partitions "${deviceinfo_super_partitions:=}"
else
# loads all modules
setup_udev
fi
setup_dynamic_partitions "${deviceinfo_super_partitions:=}"
run_hooks /hooks
if [ "$IN_CI" = "true" ]; then
@ -60,7 +59,6 @@ mount_subpartitions
wait_boot_partition
mount_boot_partition /boot
extract_initramfs_extra /boot/initramfs-extra
setup_udev
run_hooks /hooks-extra
# For testing the mass storage gadget log export function. We use a flag

View file

@ -5,7 +5,7 @@ ROOT_PARTITION_RESIZED=0
PMOS_BOOT=""
PMOS_ROOT=""
CONFIGFS=/config/usb_gadget
CONFIGFS="/config/usb_gadget"
CONFIGFS_ACM_FUNCTION="acm.usb0"
HOST_IP="${unudhcpd_host_ip:-172.16.42.1}"
@ -100,31 +100,19 @@ setup_firmware_path() {
echo -n /lib/firmware/postmarketos >$SYS
}
# shellcheck disable=SC3043
load_modules() {
local file="$1"
local modules="$2"
[ -f "$file" ] && modules="$modules $(grep -v ^\# "$file")"
# shellcheck disable=SC2086
modprobe -a $modules
}
setup_mdev() {
# Start mdev daemon
mdev -d
}
setup_udev() {
# Use udev to coldplug all devices so that they can be used via libinput (e.g.
# by unl0kr). This is the same series of steps performed by the udev,
if ! command -v udevd > /dev/null || ! command -v udevadm > /dev/null; then
echo "ERROR: udev not found!"
return
fi
# This is the same series of steps performed by the udev,
# udev-trigger and udev-settle RC services. See also:
# - https://git.alpinelinux.org/aports/tree/main/eudev/setup-udev
# - https://git.alpinelinux.org/aports/tree/main/udev-init-scripts/APKBUILD
if command -v udevd > /dev/null && command -v udevadm > /dev/null; then
udevd -d
udevadm trigger --type=devices --action=add
udevadm settle
fi
udevd -d --resolve-names=never
udevadm trigger --type=devices --action=add
udevadm settle
}
get_uptime_seconds() {
@ -663,11 +651,11 @@ setup_usb_configfs_udc() {
# Remove any existing UDC to avoid "write error: Resource busy" when setting UDC again
if [ "$(wc -w <$CONFIGFS/g1/UDC)" -gt 0 ]; then
echo "" > /config/usb_gadget/g1/UDC || echo " Couldn't write to clear UDC"
echo "" > "$CONFIGFS"/g1/UDC || echo " Couldn't write to clear UDC"
fi
# Link the gadget instance to an USB Device Controller. This activates the gadget.
# See also: https://gitlab.com/postmarketOS/pmbootstrap/issues/338
echo "$_udc_dev" > /config/usb_gadget/g1/UDC || echo " Couldn't write new UDC"
echo "$_udc_dev" > "$CONFIGFS"/g1/UDC || echo " Couldn't write new UDC"
}
# $1: if set, skip writing to the UDC
@ -676,7 +664,7 @@ setup_usb_network_configfs() {
local skip_udc="$1"
if ! [ -e "$CONFIGFS" ]; then
echo " /config/usb_gadget does not exist, skipping configfs usb gadget"
echo "$CONFIGFS does not exist, skipping configfs usb gadget"
return
fi
@ -760,10 +748,10 @@ start_unudhcpd() {
# Get usb interface
usb_network_function="${deviceinfo_usb_network_function:-ncm.usb0}"
usb_network_function_fallback="rndis.usb0"
if [ -n "$(cat /config/usb_gadget/g1/UDC)" ]; then
if [ -n "$(cat $CONFIGFS/g1/UDC)" ]; then
INTERFACE="$(
cat "/config/usb_gadget/g1/functions/$usb_network_function/ifname" 2>/dev/null ||
cat "/config/usb_gadget/g1/functions/$usb_network_function_fallback/ifname" 2>/dev/null ||
cat "$CONFIGFS/g1/functions/$usb_network_function/ifname" 2>/dev/null ||
cat "$CONFIGFS/g1/functions/$usb_network_function_fallback/ifname" 2>/dev/null ||
echo ''
)"
else
@ -797,12 +785,12 @@ setup_usb_acm_configfs() {
active_udc="$(cat $CONFIGFS/g1/UDC)"
if ! [ -e "$CONFIGFS" ]; then
echo " /config/usb_gadget does not exist, can't set up serial gadget"
echo " $CONFIGFS does not exist, can't set up serial gadget"
return 1
fi
# unset UDC
echo "" > /config/usb_gadget/g1/UDC
echo "" > $CONFIGFS/g1/UDC
# Create acm function
mkdir "$CONFIGFS/g1/functions/$CONFIGFS_ACM_FUNCTION" \
@ -1142,7 +1130,7 @@ create_logs_disk() {
export_logs() {
local loop_dev=""
usb_mass_storage_function="mass_storage.0"
active_udc="$(cat /config/usb_gadget/g1/UDC)"
active_udc="$(cat $CONFIGFS/g1/UDC)"
loop_dev="$(losetup -f)"
@ -1155,7 +1143,7 @@ export_logs() {
setup_usb_network_configfs "skip_udc"
else
# Unset UDC
echo "" > /config/usb_gadget/g1/UDC
echo "" > $CONFIGFS/g1/UDC
fi
mkdir "$CONFIGFS"/g1/functions/"$usb_mass_storage_function" || return

View file

@ -1,33 +0,0 @@
#
# This is an mdev config for the postmarketOS initramfs
#
# Devices:
# Syntax: %s %d:%d %s
# devices user:group mode
$MODALIAS=.* 0:0 0660 @modprobe -q -b "$MODALIAS"
# null does already exist; therefore ownership has to be changed with command
null 0:0 0666 @chmod 666 $MDEV
zero 0:0 0666
full 0:0 0666
random 0:0 0666
urandom 0:0 0444
hwrandom 0:0 0660
console 0:0 0600
kmem 0:0 0640
mem 0:0 0640
# Set up /dev/disk/by-* symlinks
dasd.* 0:0 0660 */lib/mdev/persistent-storage
mmcblk.* 0:0 0660 */lib/mdev/persistent-storage
nbd.* 0:0 0660 */lib/mdev/persistent-storage
nvme.* 0:0 0660 */lib/mdev/persistent-storage
sd[a-z].* 0:0 0660 */lib/mdev/persistent-storage
sr[0-9]+ 0:0 0660 */lib/mdev/persistent-storage
vd[a-z].* 0:0 0660 */lib/mdev/persistent-storage
xvd[a-z].* 0:0 0660 */lib/mdev/persistent-storage