Install a Kernel Image Safely with Debian's installkernel
You will use Debian's installkernel to copy a kernel image and its System.map into a chosen directory, with an optional kernel configuration copied alongside them. The guide starts in a temporary directory, so you can verify the file naming and backup behaviour before considering a real /boot install. Allow about 15 minutes for a controlled test and longer if you need to schedule a real reboot.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Check the installed command and inputs
- 2. Prepare a harmless staging directory
- 3. Install into the staging directory
- 4. Check optional configuration copying
- 5. Understand replacements and links before using /boot
- 6. Perform a real install only with a deliberate maintenance step
- 7. Diagnose failures without guessing
Warning
Installing into /boot changes boot files. A bad image, map or post-install hook can leave a machine unable to boot or can change bootloader state. Keep the currently working kernel, have console or recovery access, and do not reboot until the new files and your bootloader configuration have been checked.
1. Check the installed command and inputs
This guide describes Debianutils 5.17build1, the version installed on this machine. The local manual page documents the interface as installkernel version zImage System.map [directory]. The installed shell script also accepts a fifth argument for compatibility, but it ignores that argument, so do not use it to convey configuration.
$ command -v installkernel
/usr/sbin/installkernel
$ dpkg-query -W -f='${Package} ${Version}\n' debianutils
debianutils 5.17build1
$ installkernel
Usage: installkernel <version> <image> <System.map> <directory>
The command needs three positional values: a version string, the image file and a System.map file. The optional fourth value is the destination directory. If you omit it, the installed script uses /boot. That default is the main safety trap in quick experiments.
2. Prepare a harmless staging directory
Run this part as your ordinary user. Use real paths for an image produced by your kernel build later, but first create small stand-in files so the installation logic can be inspected without changing the boot partition:
$ workdir=$(mktemp -d /tmp/installkernel-test.XXXXXX)
$ mkdir "$workdir/boot"
$ printf 'test kernel image\n' > "$workdir/image"
$ printf 'test symbol map\n' > "$workdir/System.map"
$ printf 'CONFIG_TEST=y\n' > "$workdir/.config"
$ chmod 600 "$workdir/image" "$workdir/System.map" "$workdir/.config"
Keep $workdir in the same shell. It points to a new directory under /tmp, not to the real /boot.
Checkpoint
Confirm that the input files exist and are readable before invoking the installer:
$ ls -l "$workdir/image" "$workdir/System.map" "$workdir/.config"
$ test -r "$workdir/image" && test -r "$workdir/System.map" && echo inputs-readable
inputs-readable
3. Install into the staging directory
Pass the version, image, map and staging directory explicitly. The image argument is called zImage in the manual, but the installed script accepts any readable image file. It stores the result as vmlinuz-VERSION, unless the image basename is exactly vmlinux, in which case it uses vmlinux-VERSION.
$ installkernel 6.1.0-test "$workdir/image" "$workdir/System.map" "$workdir/boot"
$ find "$workdir/boot" -maxdepth 1 -type f -printf '%f\n' | sort
System.map-6.1.0-test
vmlinuz-6.1.0-test
$ cmp "$workdir/image" "$workdir/boot/vmlinuz-6.1.0-test"
$ cmp "$workdir/System.map" "$workdir/boot/System.map-6.1.0-test"
A successful command is quiet and returns status 0. The two cmp commands are also quiet when the copies match. No symbolic link is created by this first run because the staging directory did not contain one.
4. Check optional configuration copying
The installed script looks for .config beside the System.map argument. If it exists, it copies it to config-VERSION. This is useful when the map and configuration came from the same kernel build tree, but it is not a substitute for checking that the image was built from the configuration you intended.
$ installkernel 6.1.1-test "$workdir/image" "$workdir/System.map" "$workdir/boot"
$ test -f "$workdir/boot/config-6.1.1-test" && echo config-copied
config-copied
$ cmp "$workdir/.config" "$workdir/boot/config-6.1.1-test"
In this example the map is in $workdir, so the script finds $workdir/.config. If your map is in another directory, the configuration lookup follows that directory, not the current working directory.
5. Understand replacements and links before using /boot
For a repeated install of the same version, the script moves an existing versioned file to a matching .old name before writing the replacement. It also handles an existing unversioned vmlinuz, vmlinux or System.map according to whether it is a regular file or a symbolic link. The manual describes vmlinuz and vmlinuz.old; inspect the directory rather than assuming a link layout.
$ ls -la "$workdir/boot"
$ readlink "$workdir/boot/vmlinuz" 2>/dev/null || true
$ find "$workdir/boot" -maxdepth 1 -type f -o -type l | sort
Do not use > or mv to edit boot files around the command. If a staged test is wrong, discard the temporary directory after recording anything you need. For a real installation, your recovery is the previously installed kernel and its normal bootloader entry, not an improvised copy made after the failure.
6. Perform a real install only with a deliberate maintenance step
Once the staging test matches your intended layout, use the actual kernel build outputs and choose the destination explicitly. Writing to /boot normally requires elevated privileges:
$ sudo installkernel 6.1.1-custom /path/to/linux/arch/x86/boot/bzImage /path/to/linux/System.map /boot
The exact image path depends on the architecture and kernel build. Do not paste this example unchanged. Check both paths first, and use a version string that is distinct from a kernel you need to preserve:
$ test -r /path/to/linux/arch/x86/boot/bzImage
$ test -r /path/to/linux/System.map
$ sudo installkernel 6.1.1-custom /path/to/linux/arch/x86/boot/bzImage /path/to/linux/System.map /boot
$ sudo ls -l /boot/vmlinuz-6.1.1-custom /boot/System.map-6.1.1-custom
When the destination is exactly /boot, the installed script runs every executable in /etc/kernel/postinst.d with the version and installed image path as arguments. Those hooks may update bootloader or initramfs state and may fail the command. Review the hooks and their output before rebooting. A custom destination does not run this hook directory.
7. Diagnose failures without guessing
A usage message means the argument count was wrong. An error opening an image, map or configuration usually means the path or permission is wrong. Check with ls -l and test -r; do not solve a missing file by pointing at a different build tree without checking that its version and architecture match.
If a /boot install fails while running a post-install hook, keep the command's error output and inspect the files already written. Do not immediately rerun with a new version or remove the old kernel. First check whether the versioned image and map exist, then repair the specific hook or bootloader state using the distribution's normal kernel maintenance procedure.
There is no separate uninstall command in this interface. Removing a versioned kernel file can be destructive, and deleting the only working boot entry is an avoidable recovery problem. Prefer the package manager or your documented bootloader workflow for cleanup after the new kernel has booted successfully.
Done means
- You checked the installed
debianutilsversion and command path. - You tested the copy layout in a temporary directory first.
- The versioned image and
System.mapmatch their build outputs. - You understand that
/bootis the default and that it runs post-install hooks. - You kept an older working kernel and have a recovery path before rebooting.