INITRAMFS-TOOLS(7)
๐ initramfs-tools ๐
okay bestie, this is the manual section 7 page from the Linux Programmer's Manual, and it's all about initramfs-tools ๐ง let's get into it ๐
โจ NAME โจ
initramfs-tools is an intro to writing scripts for mkinitramfs ๐
โจ DESCRIPTION โจ
okay so initramfs-tools has one main script and two different sets of subscripts ๐ซถ they run during different phases of execution. we'll go through each one separately, using an imaginary tool that frobnicates an lvm partition before the root partition gets mounted ๐ฅ
Kernel Command Line
the boot loader picks the root filesystem for the kernel, same as always ๐ the old-school root=/dev/sda1 style device spec still works โจ if you use a label like root=LABEL=rootPart, the initrd will search every available device for a filesystem with that label and mount it as root ๐ธ and root=UUID=uuidnumber mounts the partition with that UUID as root ๐
Standard
init= "<path to real init>"โ the binary that takes over on the root fs once the initramfs scripts are finished ๐ฆinitramfs.clearโ clears the screen at the very beginning ๐งนinitramfs.runsizeโ sets the size of the/runtmpfs mount point. you can give it in bytes (suffixes work too) or as a percentage of your physical RAM ๐ง it gets passed as thesizemount option to tmpfs. checkhttps://www.kernel.org/doc/Documentation/filesystems/tmpfs.txtfor the full details ๐ the default is 10% ๐root= "<path to blockdevice>"โ the device node to mount as the root file system ๐ the recommended move is to use the UUID, likeroot=UUID=xxx๐ซถrootfstypeโ sets the root file system type ๐roottimeoutโ sets a timeout in seconds for how long mountroot waits for root to show up โฐ the default is 30 seconds ๐rootdelayโ an alias forroottimeout๐rootflagsโ sets the file system mount option string ๐loop= "<path to image>"โ a path inside the original root file system that gets loop-mounted and used as the real root file system ๐loopfstypeโ sets the loop file system type, if that applies ๐ธloopflagsโ sets the loop file system mount option string, if that applies ๐ฆnfsrootโ can be eitherauto, which tries to grab the info from DHCP, or a string shaped likeNFSSERVER:NFSPATHorNFSSERVER:NFSPATH:NFSOPTS๐ useroot=/dev/nfsso NFS kicks in ๐ you can look upNFSOPTSinnfs(5)โจipโ tells it how to configure the IP address ๐ง this lets you name a different NFS server than the DHCP server. checkDocumentation/filesystems/nfsroot.txtin any recent Linux source for the deets ๐ it's an optional parameter for NFS root ๐ซถvlanโ tells it to create a VLAN tagged device ๐ท๏ธ you can set up one or multiple VLAN tagged devices with thevlan=$name.$id:$parentsyntax, e.g.vlan=eth0.1:eth0โจ also optional for NFS root ๐BOOTIFโ a MAC address in pxelinux format, with leading01-and-as separators ๐ฅ pxelinux passes along the MAC address of the network card it PXE booted with using this bootarg ๐bootโ eitherlocalorNFS๐ this decides which initramfs scripts run, so check the "Subdirectories" section under boot scripts ๐งresumeโ the resume hook tries to autodetect the resume partition and uses the first swap partition as its best guess ๐ you can set theRESUMEvariable in/etc/initramfs-tools/conf.d/resume๐ธ the boot variablenoresumeoverrides all of this ๐ โโ๏ธresume_offsetโ the offset from the partition given byresume=where the swap header of the swap file lives ๐ฆquietโ cuts down the amount of text printed to the console during boot ๐คซroโ mounts the rootfs read-only ๐rwโ mounts the rootfs read-write ๐blacklistโ stops specific modules from loading ๐ซ use the boot parameterblacklist=module1,module2,module3๐
Debug
panicโ sets a timeout on panic ๐ญpanic=<sec>is a documented security feature, since it disables the debug shell ๐debugโ generates LOTS of output ๐ it writes a log to/run/initramfs/initramfs.debug. but if you pass it an arbitrary argument, the output goes to the console instead ๐ฅ๏ธ for example,debug=vc๐breakโ spawns a shell in the initramfs image at the phase you pick (top,modules,premount,mount,mountroot,bottom,init) ๐ this happens before the matching scripts (see the "Boot scripts" section) or action actually run ๐ฌ you can list several phases separated by commas ๐ซถ if you don't pick one, the default ispremount๐ท
โ ๏ธ beware: if bothpanicandbreakare present, initramfs won't spawn any shells and will reboot instead ๐
netconsoleโ loads the netconsole linux modules with the args you choose ๐กall_generic_ideโ loads generic IDE/ATA chipset support on boot ๐ฟ
โจ SCRIPTS โจ
okay so valid boot and hook script names are made up only of alphabetics, numerics, dashes and underscores ๐ค anything else gets discarded ๐๏ธ bye bye ๐
Configuration hook scripts
these let you override the user configuration when you really need to ๐ ๏ธ for example, forcing busybox to be used instead of klibc utilities ๐งฐ
Hook scripts
these run when an initramfs image gets created, and they are not part of the image itself ๐๏ธ they can still cause files to be included in the image though ๐ฆ hook scripts run under errexit, so a hook script can abort the mkinitramfs build on errors (anything with exitcode != 0) ๐จ
Boot scripts
these are included in the initramfs image and usually run during kernel boot in early user-space, before the root partition gets mounted ๐
โจ CONFIGURATION HOOK SCRIPTS โจ
config hook scripts live in /usr/share/initramfs-tools/conf-hooks.d ๐ mkinitramfs sources them after the config files in /etc and before it runs any hook scripts ๐งฉ they can override any of the variables documented in initramfs.conf(5), but only do this if it's absolutely necessary ๐ for example, if a package's boot script needs commands that klibc-utils doesn't provide, it should also install a configuration hook that sets BUSYBOX=y ๐
โจ HOOK SCRIPTS โจ
hooks can live in two places: /usr/share/initramfs-tools/hooks and /etc/initramfs-tools/hooks ๐ they run while the initramfs image is being generated, and they're responsible for pulling in every component the image needs ๐ฆ there are no guarantees about the order the scripts run in, unless you set up the prereqs in your script ๐คทโโ๏ธ
๐จ heads up:PREREQis only honored inside a single directory ๐ซฃ so the scripts in/usr/share/initramfs-toolsget ordered by theirPREREQvalues and run first ๐ฅ then all the scripts in/etc/initramfs-toolsget ordered by theirPREREQvalues and run ๐ฅ which means a local script in/etc/initramfs-toolscan never run before one from the package in/usr/share/initramfs-tools๐ญ
if a hook script needs config beyond the exported variables listed further down, it should read its own private config file that lives separately from the /etc/initramfs-tools directory ๐ it must not read initramfs-tools config files directly ๐
โโ๏ธ
Header
to support prereqs, every script should start with these lines ๐
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
# Begin real processing below this line
for example, if you're writing a new hook script that relies on lvm, change the PREREQ line to PREREQ="lvm" โจ that way the lvm hook script is guaranteed to run before yours ๐ซถ
Help functions
/usr/share/initramfs-tools/hook-functions has a bunch of functions that handle common hook script tasks ๐งฐ slay ๐
manual_add_modulesโ adds a module (plus any modules it depends on) to the initramfs image ๐งฉ- example:
manual_add_modules isofs
- example:
add_modules_from_fileโ reads a file with a list of modules (one per line) and adds them to the initramfs image ๐ the file can have comments (lines starting with#), and you can pass arguments to a module by writing them on the same line as the module name ๐- example:
add_modules_from_file /tmp/modlist
- example:
force_loadโ adds a module (and its dependencies) to the initramfs image AND unconditionally loads it during boot ๐ช you can pass arguments to the module by listing them after the module name ๐ฅ- example:
force_load cdrom debug=1
- example:
copy_modules_dirโ copies an entire module directory from/lib/modules/KERNELVERSION/into the initramfs image ๐- example:
copy_modules_dir kernel/drivers/ata
- example:
Including binaries
if you need to copy an executable or shared library into the initramfs, use something like this ๐ฆ
copy_exec /sbin/mdadm /sbin
mkinitramfs automatically detects which libraries your stuff depends on and copies them in for you ๐ค this means most executables, unless they were compiled with klibc, will pull glibc into the image too ๐ฉ which can bloat it by several hundred kilobytes ๐
โจ BOOT SCRIPTS โจ
okay so boot scripts are basically hook scripts' hype cousin ๐ they live in two places too: /usr/share/initramfs-tools/scripts/ and /etc/initramfs-tools/scripts/. Inside those are a bunch of subdirectories, and each one decides when during boot the scripts get run ๐
Header
same deal as hook scripts: there's no promise about what order the scripts in one subdirectory (see "Subdirectories" below) run in ๐ if you want to set an order, you use a similar header as hook scripts:
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
and yes, you tweak PREREQ to list any other scripts in the same subdirectory that need to go first if you need that ๐ซถ
Help functions
there's a bunch of helper functions (mostly for output stuff) that boot scripts get for free, living in /scripts/functions โจ these are giving toolkit energy:
log_success_msgโ logs a success message ๐ Example:log_success_msg "Frobnication successful"log_failure_msgโ logs a failure message ๐ Example:log_failure_msg "Frobnication component froobz missing"log_warning_msgโ logs a warning message โ ๏ธ Example:log_warning_msg "Only partial frobnication possible"log_begin_msgโ logs a message that some processing step has begun ๐ธlog_end_msgโ logs a message that some processing step is finished ๐ฆ
Example:
log_begin_msg "Frobnication begun"
# Do something
log_end_msg
panicโ logs an error message and drops you into a shell inside the initramfs image so you can poke around and figure out what went wrong ๐ Example:panic "Frobnication failed"add_mountroot_fail_hook NN-nameโ Deprecated! this one is now a stub that basically does nothing ๐ it's going to be removed in a future version, so please go remove mountroot failure hooks from your existing packages accordingly ๐ฅบ
Subdirectories
both /usr/share/initramfs-tools/scripts and /etc/initramfs-tools/scripts have the following subdirectories, and the name of each one tells you its boot stage ๐
init-topโ the first scripts to run after sysfs and procfs get mounted ๐ this one also runs the udev hook that fills up the/devtree (udev keeps running until init-bottom).init-premountโ runs after the modules from hooks and/etc/initramfs-tools/moduleshave been loaded ๐งlocal-topORnfs-topโ once these have run, the root device node is expected to be there (local) or the network interface is expected to be usable (NFS) ๐ฅlocal-blockโ these scripts get called with the name of a local block device ๐ after they've run, that device node should exist. if thelocal-toporlocal-blockscripts fail to make the device node you wanted, thelocal-blockscripts will keep getting called periodically to try again, so they're basically persistent ๐ฅนlocal-premountORnfs-premountโ these run after the root device's sanity has been checked (local) or the network interface has been brought up (NFS), but before the actual root fs gets mounted ๐ธlocal-bottomORnfs-bottomโ these run after the rootfs has been mounted (local) or the NFS root share has been mounted ๐ฆinit-bottomโ the very last scripts before procfs and sysfs get moved over to the real rootfs and control gets handed to the init binary (which should now be in the mounted rootfs). udev gets stopped here ๐ซถ
Boot parameters
/conf/param.conf lets boot scripts change the exported variables that are listed at the top of init. just write the new values into it! it gets sourced after a boot script run if it exists โจ
โจ EXAMPLES โจ
Hook script
an example hook script would look something like this (and it would usually go in /etc/initramfs-tools/hooks/frobnicate) ๐
#!/bin/sh
# Example frobnication hook script
PREREQ="lvm"
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
# Begin real processing below this line
if [ ! -x "/sbin/frobnicate" ]; then
exit 0
fi
force_load frobnicator interval=10
copy_exec /sbin/frobnicate /sbin
exit 0
Boot script
an example boot script would look something like this (and it would usually go in /etc/initramfs-tools/scripts/local-top/frobnicate) ๐ง
#!/bin/sh
# Example frobnication boot script
PREREQ="lvm"
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /scripts/functions
# Begin real processing below this line
if [ ! -x "/sbin/frobnicate" ]; then
panic "Frobnication executable not found"
fi
if [ ! -e "/dev/mapper/frobb" ]; then
panic "Frobnication device not found"
fi
log_begin_msg "Starting frobnication"
/sbin/frobnicate "/dev/mapper/frobb" || panic "Frobnication failed"
log_end_msg
exit 0
Exported variables
init sets a bunch of variables for the boot scripts environment ๐
ROOTโ matches the root boot option ๐ advanced boot scripts like cryptsetup or live-initramfs need to play tricks with it. otherwise, leave it alone!ROOTDELAY,ROOTFLAGS,ROOTFSTYPE,IPโ match the rootdelay, rootflags, rootfstype or ip boot options. Use ofROOTDELAYis deprecated ๐ instead of delaying or polling, you should write alocal-blockboot script.DPKG_ARCHโ lets you do arch-specific boot actions ๐blacklist,panic,quiet,resume,noresume,resume_offsetโ set according to their relevant boot options ๐breakโ super useful for manual intervention during setup and when you're coding a boot script ๐ ๏ธREASONโ the argument passed to the panic helper function. use it to figure out why you ended up in the initramfs shell ๐initโ passes the path to init(8), usually/sbin/initโจreadonlyโ the default for mounting root, and it matches therobootarg. it gets overridden by therwbootarg ๐rootmntโ the path where root gets mounted, usually/root๐ฆdebugโ indicates that a debug log is captured for further investigation ๐
โจ UPDATING THE INITRAMFS FROM ANOTHER PACKAGE โจ
okay this part is important, bestie ๐จ package maintainer scripts should not run update-initramfs directly ๐
โโ๏ธ instead, a package that installs hooks for initramfs-tools should ship a triggers file containing:
activate-noawait update-initramfs
kernel packages have their own rules: they must call the kernel hooks as documented in the Debian Kernel Handbook ๐
and a package that needs an initramfs to function, but isn't a kernel package, should ship a triggers file containing:
activate-await update-initramfs
โจ KERNEL HOOKS โจ
initramfs-tools comes with hook scripts that kernel packages call on installation and removal, so the initramfs gets created, updated or deleted automatically when needed ๐ค the hook scripts do nothing if the environment variable INITRD is set to No. that happens for kernel packages built with make deb-pkg (with CONFIG_BLK_DEV_INITRD not set in the kernel config), or built with make-kpkg without using the --initrd option ๐
โจ DEBUG โจ
it's super easy to peek inside the generated initramfs and check what's in it ๐ you might want to double-check that it has the binaries, libs or modules you need:
lsinitramfs /boot/initrd.img-3.16-3-amd64
โจ FILES โจ
/run/initramfs/fsck.logโ log of the fsck commands run inside the initramfs, with their output ๐/run/initramfs/fsck-rootโ only exists if fsck ran successfully on the root filesystem โ/run/initramfs/fsck-usrโ only exists if fsck ran successfully on the/usrfilesystem โ
โจ AUTHOR โจ
the initramfs-tools were written by Maximilian Attems <maks@debian.org>, Jeff Bailey <jbailey@raspberryginger.com> and numerous others ๐ซถ
this manual was written by David Hรคrdeman <david@hardeman.nu>, and updated by Maximilian Attems <maks@debian.org> ๐
โจ SEE ALSO โจ
go check out these bestie-approved references ๐ initramfs.conf(5), mkinitramfs(8), update-initramfs(8), lsinitramfs(8) ๐
๐ that's a wrap! this page comes from initramfs-tools, dated 2018/07/18, and it's INITRAMFS-TOOLS(7) ๐ go forth and frobnicate responsibly, periodt ๐ โจ
๐ฆ where this page comes from
- ubuntu jammy: initramfs-tools-core 0.140ubuntu13
- ubuntu jammy: initramfs-tools-core 0.140ubuntu13.5
- ubuntu noble: initramfs-tools-core 0.142ubuntu25
- ubuntu noble: initramfs-tools-core 0.142ubuntu25.8
- ubuntu questing: initramfs-tools-core 0.150ubuntu3
- ubuntu questing: initramfs-tools-core 0.150ubuntu3.1 ยท GPL-2.0-or-later
- ubuntu resolute: initramfs-tools-core 0.151ubuntu1 ยท GPL-2.0-or-later
- ubuntu stonking: initramfs-tools-core 0.151ubuntu3 ยท GPL-2.0-or-later
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms