Mateusz Adamowski Szkolenia

Initramfs

tajemniczy etap startu Linuksa

Mateusz Adamowski

Jesień Linuksowa 2026
Kraków, 2026-10-23


O mnie


initramfs

Komu to potrzebne?


Error


Error


Error


Czy initramfs jest potrzebny?

Często nie

Ale po kolei…


Start systemu


BIOS

Umie wczytać MBR
(446 bajtów)

Nie rozumie tablicy partycji, systemów plików


UEFI


BIOS lub UEFI wczytuje bootloader (GRUB)


GRUB

(w ograniczonym stopniu też: LVM, RAID, LUKS)


GRUB

  1. wczytuje plik konfiguracyjny
  2. ładuje kernel (i initrd)

Kernel

  1. uruchamia się
  2. montuje dysk (root=)
  3. uruchamia proces init (PID 1)

Jak dostać się do dysku systemowego?


initramfs


initrd?


ramdisk vs ramfs


struktura initrd


struktura initramfs


ls


skrypt init


cpio?


Busybox


Narzędzia


cryptroot


Use case #1:

zdalne wprowadzanie hasła


zdalny dostęp do initramfs


dropbear


dropbear


dropbear


Dropbear


initramfs w Debianie


Rozbudowywanie initramfs


conf.d


hooks


przykładowy hook

#!/bin/sh

[ "$1" = "prereqs" ] && exit 0

. /usr/share/initramfs-tools/hook-functions

copy_exec /bin/busybox /bin/busybox.full

hook-functions


skrypty


    init-top        (przed załadowaniem modułów)
        ↓
    init-premount
        ↓
    local-top
        ↓
    local-premount
        ↓
    local-bottom    (po zamontowaniu /)
        ↓
    init-bottom
        ↓
    *** start normalnego systemu ***

szablon skryptu

#!/bin/sh

PREREQ="udev"

prereqs() {
    echo "$PREREQ"
}

case "$1" in
    prereqs)
        prereqs
        exit 0
    ;;
esac

Uwaga

Skrypt jest uruchamiany również w trakcie budowania initramfs w celu ustalenia kolejności wykonywania przez init.

Parametr: prereqs


Use case #2

wireguard


hook

...

copy_exec /usr/bin/wg /usr/bin/wg

manual_add_modules wireguard

copy_file conffile /etc/initramfs/wg0.conf /conf/wg0.conf

wg


skrypt (init-premount)

...

ip link add "$interface" type wireguard
ip link set "$interface" up
wg setconf "$interface" /conf/wg0.conf

ip address add "$addr" dev "$interface"
ip route add "$route" dev "$interface"

Use case #3

wifi


hook

...

copy_file conffile /etc/initramfs-tools/wpa_supplicant.conf \
            /conf/wpa_supplicant.conf

copy_exec /usr/sbin/iw
copy_exec /usr/sbin/wpa_supplicant
copy_exec /usr/sbin/wpa_cli

manual_add_modules mwifiex_sdio

skrypt (init-premount)

...

modprobe "$WLAN_MODULE"
sleep 5

for TTT in 4 8 16 32; do
    wpa_supplicant -B -i wlan0 -c /conf/wpa_supplicant.conf
    ipconfig -t "$TTT" -d wlan0 && exit 0
    wpa_cli -p /run/wpa_supplicant -i wlan0 terminate
    echo "Wifi retrying"
    sleep "$TTT"
done

Use case #4

notyfikacje


ntfy.sh

ntfy


conf.d/ntfy

NTFYSH_HOSTNAME="mojserwer01"
NTFYSH_TOPIC="jesien_linuksowa_2026"

skrypt (init-premount)

(
  attempts=10
  while [ "$attempts" -gt 0 ]; do
    wget -q -T 5 -O /dev/null \
      --no-check-certificate \
      --post-data="$(uname -r)" \
      --header="Title: ${NTFYSH_HOSTNAME}: dropbear ready" \
      --header='Tags: teddy_bear' \
      "https://ntfy.sh/${NTFYSH_TOPIC}" && break

    attempts=$((attempts - 1))
    [ "$attempts" -gt 0 ] && sleep 5
  done
) &

ntfy


Więcej pomysłów


Initramfs from scratch


Budowa własnego initramfs od zera


trywialny init

#!/bin/sh

echo "Welcome to myinitramfs!"
sh

budowa initramfs

mkdir -p initramfs && cd initramfs
mkdir -p bin
cp "$SRC/busybox" bin/busybox
cp "$SRC/init" bin/init
ln -s busybox bin/sh
find . | cpio --owner=0:0 -H newc -o > ../initrd

Diskless?

A gdyby tak nie montować dysku i zostać w RAM-ie na zawsze?


Diskless

(aka LiveCD)


przejście do nowego systemu

mount -t proc proc /proc
memsize="$(sed -ne '/^MemTotal/s/^.*: *\(.*\) kB$/\1/p' /proc/meminfo)"
umount /proc

mkdir -p /newroot
mount -t tmpfs -o "size=${memsize}k,mode=0755" tmpfs /newroot

tar -x -C /newroot --strip-components=1 < /rootfs.tar
exec /bin/run-init /newroot /sbin/init "$@"

A może squashfs?

mkdir -p /rootfs-ro
mount -t squashfs -o loop,ro /rootfs.squashfs /rootfs-ro
mkdir -p /overlay /newroot

memsize="$(sed -ne '/^MemTotal/s/^.*: *\(.*\) kB$/\1/p' /proc/meminfo)"
mount -t tmpfs -o "size=${memsize}k,mode=0755" tmpfs /overlay

mkdir -p /overlay/upper /overlay/work
mount -t overlay overlay \
  -o lowerdir=/rootfs-ro,upperdir=/overlay/upper,workdir=/overlay/work \
  /newroot

Co dalej?


dracut


systemd w initramfs


ukify


ukify

ukify build \
    --linux=kernel-x.y.z" \
    --initrd=initrd-x.y.z.gz" \
    --cmdline="console=tty0" \
    --output="mojsystem.efi"

kexec

kexec -l inny-kernel \
        --append=...cmdline... \
        --initrd=inny-initrd

warsztaty


warsztaty


Materiały

mateusza-szkolenia.github.io


Koniec