MKINITCPIO(8)

πŸ“¦ version 42.2, in arch rolling

πŸ’– MKINITCPIO β€” the mkinitcpio manual, section 8, bestie edition πŸ’–

okay so you opened the mkinitcpio manual and it's giving section 8, which is the big-girl sysadmin section, and honestly? iconic. this is the page that tells you how to build your initial ramdisk. no cap, it's a lot, but we're gonna get through it together. grab a snack πŸ“


✨ NAME ✨

mkinitcpio β€” Create an initial ramdisk environment πŸ¦‹


✨ SYNOPSIS ✨

mkinitcpio [options]

✨ DESCRIPTION ✨

so basically, mkinitcpio creates an initial ramdisk environment for booting the Linux kernel. and what even is an initial ramdisk? it's literally a tiny little baby environment (they call it early userspace) that loads up all the kernel modules and sets up the important stuff before handing control over to init. main character energy: it does the chaotic prep work and then dips πŸ’…

why do we even need it? because it makes stuff possible like encrypted root file systems and root file systems on a software RAID array β€” the kernel can't just rawdog those on its own, bestie.

and the good news? mkinitcpio lets you extend it super easily with custom hooks, it does autodetection at runtime, and it has many other features. slay. ✨


✨ OPTIONS ✨

okay here's the whole menu, one by one, no skipping, we eat every crumb πŸ“

  • -A, --addhooks hooks β€” adds extra hooks to the image. these get processed in order after all the other hooks from the config file</u>. multiple hooks? comma-separate them. and yeah you can pass this option multiple times, go off.
  • -c, --config config β€” use config file to generate the ramdisk. default: /etc/mkinitcpio.conf. ⚠️ and listen: if you specify this, then drop-in files in /etc/mkinitcpio.conf.d will be ignored. them's the rules.
  • -d, --generatedir directory β€” set directory as the place where the initramfs gets built. lowkey useful if you wanna generate a shutdown ramfs in /run/initramfs/.
  • -D, --hookdir directory β€” set directory as the place where hooks will be searched for when generating the image.
  • -I, --include path β€” add extra files or directories to the image. these get processed in order after all other files have been included into the image.
    • if the path is a file, you can comma-separate the source and the destination on the image. example: source:destination:mode.
    • if the path is a directory, it will only accept the full directory and include the directory from the root of the image.
    • multiple paths should be comma-separated. this option can be specified multiple times.
  • -g, --generate filename β€” generate a CPIO image as filename. default: no β€” which means nothing gets written to the file system unless you actually specify this option. (yes, that's the default. it does nothing by default. very demure.)
  • -H, --hookhelp hookname β€” output help for the hookname hook. just the one hook, it's not a group thing.
  • -h, --help β€” output a short overview of available command-line switches. the quick lil recap.
  • -k, --kernel kernelversion β€” use kernelversion instead of the current running kernel. this may be:
    • a path to a kernel image (⚠️ only supported for x86-based architectures),
    • a specific kernel version,
    • or the special keyword none. in that last case, no kernel modules are added to the image. just so you know what you're signing up for.
  • -L, --listhooks β€” list all available hooks. window shopping πŸ›οΈ
  • -M, --automods β€” display modules found via autodetection. mkinitcpio will automatically try to figure out which kernel modules are needed to start your computer, and this option lists which modules were detected. it's basically a vibe check for your hardware.
  • -n, --nocolor β€” disable color output. (sad. but sometimes your terminal is doing too much.)
  • --nopost β€” do not run post hooks.
  • -U, --uki filename β€” generate a unified kernel image as filename. if a CPIO image is successfully built, it will be used to generate a unified kernel image for UEFI booting. this combines the initramfs, the kernel, and the kernel cmdline into one executable. super useful for boot chain integrity where the file is signed. πŸ” default: no. for the list of relevant options, see Options for unified kernel image below.
  • -P, --allpresets β€” process all presets contained in /etc/mkinitcpio.d. see the -p option for more detail about presets.
  • -p, --preset preset β€” build initramfs image(s) according to the specified preset. this may be a file in /etc/mkinitcpio.d (without the .preset extension) or a full, absolute path to a file. you can specify this option multiple times to process multiple presets. go big.
  • -R, --remove β€” remove initramfs image(s) generated by the specified preset(s). if used together with -P|--allpresets, it removes the images for all presets. ⚠️ this option can only be used with either -p|--presets or -P|--allpresets. it does not work alone, periodt.
  • -r, --moduleroot root β€” specifies the root directory to find modules in, defaulting to /.
  • -S, --skiphooks hooks β€” skip hooks when generating the image. multiple hooks should be comma-separated. this option can be specified multiple times.
  • -s, --save β€” saves the build directory for the initial ramdisk. default: no β€” meaning the directory will not be retained if you don't specify this option. useful for debugging purposes. πŸ›
  • -t, --builddir tmpdir β€” use tmpdir as the temporary build directory instead of /tmp. tmpdir must exist (no, it won't make it for you). the TMPDIR environment variable is also honored to set this location, but the command line option takes precedence.
  • -V, --version β€” display version information.
  • -v, --verbose β€” verbose output. outputs more information about what is happening during creation of the ramdisk. the yapper mode, we love her.
  • -z, --compress compress β€” override the compression method with the compress program.

✨ OPTIONS FOR UNIFIED KERNEL IMAGE ✨

these are the UKI-specific girlies πŸŽ€ they only matter when you're making a unified kernel image.

  • --cmdline filename β€” use a kernel command line with the unified kernel image. if a directory is given, all files matching *.conf in that directory are used. if none is specified, try one of the files /etc/kernel/cmdline, /usr/lib/kernel/cmdline, /etc/cmdline.d/*.conf, /proc/cmdline.
  • --no-cmdline β€” omit embedding a kernel command line string in the unified kernel image. kernel command line options will need to be passed via the kernel command line. overrides the --cmdline option. so pick a lane, bestie.
  • --splash filename β€” UEFI executables can show a bitmap file on boot. cute lil boot picture 🌸
  • --uefistub filename β€” UEFI stub image used for unified kernel image generation. ⚠️ has no effect if ukify is being used. default: attempts to look for a systemd-boot or gummiboot stub loader.
  • --ukiconfig filename β€” configuration file to pass to ukify. if none is specified, try one of the files /etc/kernel/uki.conf or /usr/lib/kernel/uki.conf. if neither of those exists, ukify will use its internal default.
  • --no-ukify β€” do not use ukify to build UKIs even if it is available. ⚠️ this is not recommended. like, we said it, so now you know.
  • --kernelimage filename β€” include a kernel image for the unified kernel image. default: one of /lib/modules/${KERNELVERSION}/vmlinuz, /lib/modules/${KERNELVERSION}/vmlinux, /boot/vmlinuz-${KERNELVERSION}, /boot/vmlinux-${KERNELVERSION}, /boot/vmlinuz-linux, or /boot/vmlinux-linux. it'll go down the list and take what it finds.
  • --osrelease filename β€” include a os-release file for the unified kernel image. default: /etc/os-release or /usr/lib/os-release.

✨ ABOUT PRESETS ✨

okay so what's a preset? a preset is a pre-defined definition on how to create an initial ramdisk. instead of you standing there typing out the configuration file and the output file every single time you generate a new initial ramdisk β€” exhausting β€” you define a preset once and then just use the -p switch to generate an initial ramdisk according to your preset. it's called being efficient, iykyk πŸ’…

typically, presets are files located in /etc/mkinitcpio.d with the extension .preset, e.g. /etc/mkinitcpio.d/linux.preset for the linux preset. it is possible to use files in other locations, too β€” then the path to this file needs to be specified.

preset files are shell scripts that get sourced by mkinitcpio, and the following variables will influence its behavior.

note, that mkinitcpio calls itself for each preset and passes the options defined in the preset file via command line arguments. those are mentioned in the description of the options below, so refer to the manual of the command line arguments for more information about a particular option.

✨ PRESETS ✨

  • PRESETS β€” an array of preset names defined in this file. these names will be used as prefix to other options to provide preset-specific options. for example, if a PRESET=('custom') is given, then the image is specified via custom_image='/boot/custom.img'.
  • <preset>_kver (defaults to value of ALL_kver β€” one of the two is required) β€” specify the Kernel version (via -k in mkinitcpio).
  • <preset>_config (defaults to value of ALL_config β€” one of the two is required) β€” path to the configuration file (passed via -c to mkinitcpio).
  • <preset>_uki (one of <preset>_uki and <preset>_image is required) β€” output file path for a unified kernel image (passed via -U to mkinitcpio).
  • <preset>_image (one of <preset>_uki and <preset>_image is required) β€” output file path for the generated image (passed via -g to mkinitcpio).
  • <preset>_cmdline (defaults to value of ALL_cmdline) β€” path to the kernel command line file (passed via --cmdline to mkinitcpio). this option is only used when generating unified kernel images.
  • <preset>_splash (defaults to value of ALL_splash) β€” path to the splash image file (passed via --splash to mkinitcpio). this option is only used when generating unified kernel images.
  • <preset>_kerneldest (defaults to value of ALL_kerneldest) β€” kernel destination path that will be passed to post hooks. this overrides the default kernel location (usually /boot) and allows customization of where the kernel should be located for booting. the value is passed to post hooks via the KERNELDESTINATION environment variable.
  • <preset>_options β€” further command line arguments to pass to mkinitcpio as a string or array. they will get appended at the end of the call to mkinitcpio (after all the options mentioned above), so this can be used to overwrite options (for example pass a -S hook here to skip a hook).

and bestie, that is not even the whole page β€” there's more coming πŸ’–

✨ ABOUT INSTALL HOOKS ✨

okay bestie, so install hooks are bash scripts that get sourced while mkinitcpio is running, and their whole job is stuffing modules, binaries and other files into the image πŸŽ€. There's a whole lil toolbox of functions to make that easy, and here they all are, no skips:

add_module modname

Drops the module named by modname into the image ✨. Dependencies get figured out and added automatically, so you don't have to do the detective work yourself πŸ•΅οΈ

add_binary binary [ destination ] [ mode ]

Adds a binary to the image πŸ’–. The binary arg does not have to be an absolute path β€” if a lookup is needed, it'll do one. If the binary is a dynamically linked ELF binary, the dependencies come along automatically. If it's a symlink, both the symlink and the target binary get added 🫢. Optionally you can hand over a destination inside the initramfs image and a file mode. By default, the destination and mode come from the source derived from binary.

add_file path [ destination ] [ mode ]

Adds a file, plus any parent directories it needs to exist, to the image 🌸. If it's a symlink, both the symlink and the target file get added. You can optionally pass a destination within the initramfs image and a file mode. By default, the destination and mode are taken from the source and mode of the file given by path.

add_file_early path [ destination ] [ mode ]

Same energy as add_file πŸ’…, except it drops the file and all needed parent directories into the early uncompressed image. Works the same way as add_file.

add_dir path

Adds a directory and its parents to the image πŸŽ€

add_dir_early path

Adds a directory and its parents to the early uncompressed image ✨. Works exactly the same way as add_dir.

add_full_dir directory [ glob ] [ strip_prefix ]

Recursively adds a whole directory to the image by walking the given path and calling add_file, add_dir and add_symlink as it goes πŸ¦‹. Real talk: this function will not follow symlinks, and it will not add the targets of symlinks either.

If you pass the glob argument, only files and symlinks matching that glob get added πŸ‘‘

If you pass the strip_prefix argument, it gets used to strip the destination path (that's the path inside the initramfs image, iykyk) from the prefix specified by strip_prefix. Super handy when you're writing rootfs-overlay hooks 🌈

Adds a symlink to the image at the given path, optionally pointing at the link-target you specify πŸ“. If link-target isn't provided, it assumes that this symlink exists in the real filesystem and reads the target using readlink(1). Heads up though: no checking is done to make sure the symlink's target actually exists, and symlinks will not be followed recursively πŸ’€

add_all_modules [ -f filter ] pattern

Adds modules to the image, without regard for the autodetect whitelist 😀. pattern should be a subdirectory inside the kernel tree describing which subset of modules you want in. Want even more precision? Pass -f with an extended regular expression and go off πŸ’…

add_checked_modules [ -f filter ] pattern

Same as add_all_modules, except with the constraint that only modules matching the whitelist generated by the autodetect hook make it into the image πŸ‘‘. If the autodetect hook isn't present in the image, this function is literally identical to add_all_modules.

add_runscript scriptname

Adds a runtime hook to the image β€” that's a busybox ash compatible shell script 🧚. The name of the script is guaranteed to match the name of the hook that the script is called from. cute, right?

add_udev_rule rule-file

Adds a udev rule to the image 🌸. Dependencies on binaries get discovered and added for you. The argument can be a rule file name (it'll be discovered from the well known udev paths) or an absolute path ✨

add_all_modules_from_symbol symbol paths

Adds modules from the paths directories that contain the symbol to the image πŸ”₯

add_checked_modules_from_symbol symbol paths

Like add_all_modules_from_symbol, but with the constraint that only modules matching the whitelist generated by the autodetect hook get added πŸ’–. If the autodetect hook isn't present in the image, this function is identical to add_all_modules_from_symbol.

add_initcpio_binary binary [ destination ] [ mode ]

Similar to add_binary, except it goes looking inside /usr/lib/initcpio for the binary to include in the image πŸ‘€. This is the move for hooks that keep files inside that directory without wanting to hardcode the path everywhere.


🌈 ABOUT EARLY CPIO 🌈

mkinitcpio has support for early CPIO, bestie πŸ’œ. These are uncompressed CPIO archives that get prepended to the main compressed CPIO archive. Their whole thing is early loading CPU microcode, or loading ACPI table overrides ✨

Install hooks can install files into this archive by adding them to $EARLYROOT πŸŽ€


πŸ’… ABOUT RUNTIME HOOKS πŸ’…

Runtime hooks that get added to the image via the add_runscript function from an install hook are what let you do extra stuff during early userspace 🌸. Specific functions inside those files will run at different times β€” a hook can define one or more of them. At every hook point, hooks run in the order they're defined in the HOOKS variable, except for cleanup hooks, which run in reverse πŸ”„

run_earlyhook

Functions with this name run once the API mounts have been set up and the kernel command line has been parsed ✨. Daemons that early userspace needs should be started from this hook point πŸ‘‘

run_hook

Functions with this name run after any early hooks, and after the user defined modules have been installed πŸ’–. This is the most common hook point, and this is where stuff like scanning for LVM volumes and mapping encrypted volumes should happen.

run_latehook

Functions with this name run after root has been mounted 🌸. Generally this is for further necessary setup in the real root, like mounting other system partitions.

run_cleanuphook

Functions with this name run as late as possible πŸŽ€. Any daemons you started from a run_earlyhook function should be shut down here, in preparation for switching over to the real root.

run_emergencyhook

Functions with this name run right before the emergency shell gets launched in case of a boot failure 😭. This lets stuff like boot splash screens terminate their process, so users actually notice the failure instead of staring at a pretty logo forever.

getarg argument [ default ]

Use this one inside runtime hooks to grab an argument off the kernel cmdline πŸ¦‹. If argument exists with a value, the value is returned. If argument exists without a value, y is returned. If argument doesn't exist, default is returned. And if default isn't specified, nothing is returned 🀷


⭐ ABOUT POST HOOKS ⭐

Post hooks are executables or scripts that get executed after a successful image generation, for further processing β€” signing, for example πŸ’…. Note that when kernel-install(8) invokes mkinitcpio, post hooks are disabled.

They receive the kernel as the first argument, the image as the second, and optionally the unified kernel image as a third πŸŽ€

Note: if mkinitcpio is invoked with -k none or -k version and the kernel image is not found, the first argument will be empty. 😭

The following environment variables get passed along:

KERNELVERSION

Holds the full version of the kernel that the image has been built from πŸ‘‘

KERNELDESTINATION

The default location where the kernel should live for booting 🌸. This is usually the same as the first argument, but it might differ if mkinitcpio wasn't invoked with -k /boot/*. If no kernel image has been found, this variable will be empty as well. πŸ’€

🌸 EARLY INIT ENVIRONMENT 🌸

okay so here's the tea, bestie: mkinitcpio gives special treatment to certain environment variables that get passed on the kernel command line. here's the whole lineup ✨

  • break[=<premount|postmount>] β€” if you set this, mkinitcpio will start a shell during early init. the optional parameter controls when that happens: with premount or with no parameter at all, the shell launches <em>prior to</em> mounting root. if you say postmount, the shell launches <em>after</em> mounting root. 🐚
  • disablehooks=hooklist β€” a comma separated list of hooks that get skipped during early init. bye bestie πŸ‘‹
  • earlymodules=modulelist β€” a comma separated list of modules that get loaded prior to any others. ngl this is generally not needed, and it usually points to a configuration or kernel problem. 🚩
  • quiet β€” makes mkinitcpio output fewer messages during boot. errors will not be suppressed, so don't think you can hide those. 😭
  • ro β€” says root should be mounted with readonly permissions. this is the default behavior. periodt.
  • rw β€” says root should be mounted with readwrite permissions. this is generally only useful if your initramfs uses the fsck hook. πŸ”§
  • root=rootdevice β€” this variable describes the root partition that early init will mount before passing control to the real init. mkinitcpio understands a variety of formats, the most basic of which is the path to the block device β€” either directly such as /dev/sda2, or using a udev symlink such as /dev/disk/by-label/CorsairF80-root. support for identification by LABEL or UUID tags is also supported, such as, LABEL=CorsairF80-root. as of util-linux 2.22, PARTUUID and PARTLABEL are also supported. identification via hex encoded major/minor device ID is supported for legacy reasons, but should be avoided as it tends to be fragile. πŸ’€
  • rootdelay[=seconds] β€” sets the delay, in seconds, that mkinitcpio is willing to wait for the root device to show up, if it isn't available immediately. this defaults to 10 seconds. if an invalid integer is passed, this variable will have no effect. ⏳
  • rootflags=flaglist β€” a comma-separated list of flags which will be passed onto the mount(8) command when mounting the root file system. acceptable values are file system specific. πŸ—‚οΈ
  • rootfstype=fstype β€” overrides the type of file system being mounted as root. this should <em>almost never</em> be needed as mount(8) usually detects this on its own. she's self-sufficient πŸ’…
  • rd.debug β€” enables shell debug (xtrace). if rd.log is not also a parameter on the kernel command line, this parameter implies rd.log=console. πŸ›
  • rd.log[=<console|file|kmsg|all>] β€” enables logging of early userspace messages. if specified, the optional parameter describes where this information is logged. multiple options can be OR-d together using the pipe (|) character. messages are always logged to the console unless the quiet parameter is passed. if the optional parameter is not specified, kmsg|console is assumed. if rd.log is not present on the kernel command line, no logging will take place. πŸ“
    • console β€” writes output to /dev/console.
    • file β€” writes output to /run/initramfs/init.log.
    • kmsg β€” writes output to the /dev/kmsg device (introduced in Linux 3.5). this option is a no-op if your kernel lacks support for /dev/kmsg.
    • all β€” writes output to all known log targets.
these are only the variables that the core of mkinitcpio honor. additional hooks may look for other environment variables and should be documented by the help output for the hook. πŸ‘‘

πŸ¦‹ REPRODUCIBILITY πŸ¦‹

mkinitcpio aims to create reproducible initramfs images by default. slay.

this means that two subsequent runs of mkinitcpio should produce two files that are identical at the binary level. fr fr.

timestamps within the initramfs are set to the Unix epoch of 1970-01-01. ⏰

note that in order for the build to be fully reproducible, the compressor specified (e.g. gzip, xz) must <em>also</em> produce reproducible archives. at the time of writing, as an inexhaustive example, the lzop compressor is incapable of producing reproducible archives due to the insertion of a runtime timestamp. πŸ’€

more information can be found at https://reproducible-builds.org. 🌈


πŸŽ€ FILES πŸŽ€

  • /etc/mkinitcpio.conf β€” default configuration file for mkinitcpio.
  • /etc/mkinitcpio.conf.d β€” directory containing drop-in configuration files.
  • /etc/mkinitcpio.d β€” directory containing mkinitcpio presets.
  • /etc/initcpio/install, /usr/lib/initcpio/install β€” search path for build time hooks.
  • /etc/initcpio/hooks, /usr/lib/initcpio/hooks β€” search path for early userspace runtime hooks.
  • /etc/initcpio/post, /usr/lib/initcpio/post β€” search path for post generation hooks.

✨ EXAMPLES ✨

  • mkinitcpio β€” perform a dry-run. this will generate an initial ramdisk but will not write anything. use -g to create the real image.
  • mkinitcpio -p linux β€” create an initial ramdisk based on the linux preset.
  • mkinitcpio -g /boot/initramfs-linux.img -k /boot/vmlinuz-linux β€” create an initial ramdisk for the kernel at /boot/vmlinuz-linux. the resulting image will be written to /boot/initramfs-linux.img.
  • mkinitcpio -U /efi/EFI/Linux/systemd-linux.efi β€” create an initial ramdisk for the kernel along with a unified kernel image. the resulting executable will be written to /efi/EFI/Linux/systemd-linux.efi.
  • mkinitcpio -U /efi/EFI/Linux/systemd-linux.efi --splash /usr/share/systemd/bootctl/splash-arch.bmp β€” create an initial ramdisk for the kernel and a unified kernel image. this also includes a splash image which will be used during boot. 🎨

🌸 SEE ALSO 🌸

a more thorough article on configuring mkinitcpio: https://wiki.archlinux.org/title/mkinitcpio

initrd(4), lsinitcpio(1), mkinitcpio.conf(5), bootparam(7) β€” go read these too, bestie, iykyk πŸ“š


πŸ™ˆ BUGS πŸ™ˆ

upon writing this man page, there were no noticeable bugs present. please visit https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/issues for an up to date list. πŸ›βœ¨


πŸ‘‘ AUTHORS πŸ‘‘

mkinitcpio is maintained by the Arch Linux community. refer to the AUTHORS file for a full list of contributors. 🫢


Copyright πŸ„― mkinitcpio contributors. GPL-2.0-only.


and that's a wrap, bestie πŸŽ€ this was mkinitcpio version 42.2, dated 2026-10-01, page MKINITCPIO(8) β€” go build something iconic with it, mwah πŸ’…βœ¨

πŸ“¦ where this page comes from