User:Vaukai/custom initramfs
From Gentoo Wiki
Jump to:navigation
Jump to:search
Initramfs for LVM2
Started from forums topic and based on Custom Initramfs
Kernel
For embedding the initramfs into the kernel image, the kernel option Initramfs source file(s) ( CONFIG_INITRAMFS_SOURCE ) needs to contain the root of the initramfs, (e.g. /usr/src/initramfs):
General setup --->
(/usr/src/initramfs) Initramfs source file(s)
user $
grep CONFIG_INITRAMFS_SOURCE /usr/src/linux-4.19.97-gentoo/.config
CONFIG_INITRAMFS_SOURCE="/usr/src/initramfs"
Directory structure
(From Custom Initramfs)
root #
mkdir --parents /usr/src/initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys}
root #
cp --archive /dev/{null,console} /usr/src/initramfs/dev/
Looks like:
user $
tree /usr/src/initramfs/
/usr/src/initramfs/ ├── bin ├── dev │ ├── console │ └── null ├── etc ├── lib ├── lib64 ├── mnt │ └── root ├── proc ├── root ├── sbin └── sys
Adding busybox
user $
ldd /bin/busybox
not a dynamic executable
root #
lddtree --copy-to-tree /usr/src/initramfs /bin/busybox
(The --copy-to-tree option depends on app-misc/pax-utils built with the python USE flag.)
user $
tree /usr/src/initramfs/
/usr/src/initramfs/ ├── bin │ └── busybox ├── dev │ ├── console │ └── null ├── etc ├── lib ├── lib64 ├── mnt │ └── root ├── proc ├── root ├── sbin └── sys
user $
file /usr/src/initramfs/bin/busybox
/usr/src/initramfs/bin/busybox: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, stripped
Adding LVM2
Here LVM2 is used without the static-libs USE flag.
user $
ldd /sbin/lvm
linux-vdso.so.1 (0x00007fffb07ea000) libdevmapper-event.so.1.02 => /lib64/libdevmapper-event.so.1.02 (0x00007f3f1efc5000) libudev.so.1 => /lib64/libudev.so.1 (0x00007f3f1ef9e000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f3f1ef98000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f3f1ef44000) libdevmapper.so.1.02 => /lib64/libdevmapper.so.1.02 (0x00007f3f1eeeb000) libaio.so.1 => /lib64/libaio.so.1 (0x00007f3f1eee6000) libreadline.so.7 => /lib64/libreadline.so.7 (0x00007f3f1ee94000) libc.so.6 => /lib64/libc.so.6 (0x00007f3f1ecc6000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3f1eca4000) /lib64/ld-linux-x86-64.so.2 (0x00007f3f1f42d000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f3f1ec9b000) libm.so.6 => /lib64/libm.so.6 (0x00007f3f1eb57000) libtinfow.so.6 => /lib64/libtinfow.so.6 (0x00007f3f1eb19000)
root #
lddtree --copy-to-tree /usr/src/initramfs /sbin/lvm
user $
tree /usr/src/initramfs
/usr/src/initramfs ├── bin │ └── busybox ├── dev │ ├── console │ └── null ├── etc ├── lib ├── lib64 │ ├── ld-linux-x86-64.so.2 │ ├── libaio.so.1 │ ├── libblkid.so.1 │ ├── libc.so.6 │ ├── libdevmapper-event.so.1.02 │ ├── libdevmapper.so.1.02 │ ├── libdl.so.2 │ ├── libm.so.6 │ ├── libpthread.so.0 │ ├── libreadline.so.7 │ ├── libtinfow.so.6 │ ├── libudev.so.1 │ └── libuuid.so.1 ├── mnt │ └── root ├── proc ├── root ├── sbin │ └── lvm └── sys
Creating the init script
root #
vim /usr/src/initramfs/init
#!/bin/busybox sh # Install symlinks to all busybox applets first. # /bin/busybox mkdir -p /usr/sbin /usr/bin # /bin/busybox --install -s rescue_shell() { printf '\e[1;31m' # bold red foreground printf "$1 Dropping you to a shell." printf "\e[00m\n" # normal colour foreground # load the keymap [ -f /keymap ] && loadkmap < /keymap exec setsid cttyhack /bin/sh } # initialise mount -t proc none /proc || rescue_shell "mount /proc failed." mount -t sysfs none /sys || rescue_shell "mount /sys failed." mount -t devtmpfs none /dev || rescue_shell "mount /dev failed." # set hardcoded default values crypt_root="" root="" resume="" mount_ro_rw='ro' # parse kernel command line for p in $(cat /proc/cmdline); do case "${p}" in # crypt_root=*) # crypt_root="${p#*=}" # ;; root=*) root="${p#*=}" ;; resume=*) resume="${p#*=}" ;; ro|rw) mount_ro_rw="${p}" ;; esac done # echo root="${root}" # echo resume="${resume}" # sleep 30 # # decrypt # # convert UUID or LABEL to device node # crypt_root="$(findfs "${crypt_root}")" # # decryption is first tried using the key file /crypto_key.bin # # if this fails, prompt for a password # cryptsetup open "${crypt_root}" lvm --type luks --key-file /crypto_key.bin || \ # cryptsetup open "${crypt_root}" lvm --type luks || \ # rescue_shell "Decryption failed." # activate lvm # create /dev/mapper/control lvm vgscan --mknodes || rescue_shell "vgscan failed." # activate all LVM volumes lvm vgchange --sysinit -a ly || rescure_shell "vgchange failed." # create device nodes for the volumes lvm vgscan --mknodes || rescue_shell "vgscan failed." # mount the real root # convert UUID or LABEL to device node # root="$(findfs "${root}")" mount -o "${mount_ro_rw}" "${root}" /mnt/root || rescue_shell "mount ${root} failed." # enable resume from hibernate if [ -n "${resume}" ]; then # copy the major:minor of the swap block device into /sys/power/resume printf '%u:%u\n' $(stat -L -c '0x%t 0x%T' "${resume}") > /sys/power/resume || \ rescue_shell "Activating resume failed." fi # clean up umount /proc umount /sys umount /dev # boot the real system exec switch_root /mnt/root /sbin/init
Recompiling the kernel
user $
cd /usr/src/linux-4.19.97-gentoo
root #
make && make modules_install
See also
- User:NeddySeagoon/DIYinitramfs — build an initramfs which does not contain kernel modules.