This post was translated from Korean into English by AI.
I somehow ended up having to build a Linux image myself. I actually plan to use Yocto, but before doing so, I was curious about what it takes to create a minimally bootable image, so I looked into it.
Make Minimal Bootable Disk
The Linux boot process is fairly complex, but it can be summarized as follows.
- The BIOS, UEFI, or another firmware interface performs various initialization tasks and then looks for a bootable disk.
- If it finds a bootloader in the bootable disk's MBR section or GPT EFI partition, it runs the bootloader.
- The bootloader loads the initramfs and kernel.
- The kernel performs various initialization tasks, including setting up memory management.
- It then runs the init process specified in the initramfs.
- The init process mounts the root file system and starts the required services.
Therefore, creating a minimally bootable image requires the following:
- A kernel
- An initramfs containing an init program
- A bootloader
1. Linux Kernel
- Download and build the kernel. The config file generated by default may not work universally, so it is a good idea to use a config file provided by a distribution such as Ubuntu.
- If you are using Ubuntu or a similar distribution, you can find the file with the
/boot/config-$(uname -r)command. - You may encounter a credential issue. If so, refer to the link below.
- https://askubuntu.com/questions/1329538/compiling-the-kernel-5-11-11/1329625#1329625
- If you are using Ubuntu or a similar distribution, you can find the file with the
- The kernel is created at
arch/x86/boot/bzImage. (For the x86 architecture)
2. Initramfs
- Download busybox to create the initramfs.
git clone git://busybox.net/busybox.git
- Build busybox using make.
make defconfigmake
- Create the initramfs using the
make installcommand. The initramfs is created in the_installdirectory. - Add the following
initscript to the_installdirectory.#!/bin/sh mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none /dev exec /bin/sh - Make the
initscript executable using thechmod +x initcommand. - From the
_installdirectory, create the initramfs using thefind . -print0 | cpio --null -ov --format=newc | gzip -9 > ../../initramfs.cpio.gzcommand.
3. Bootloader
- Prepare a blank disk, then create an EFI partition using the
fdiskcommand.- Be careful not to format the host disk.
- Since the goal is to create a minimally bootable image, do not create any other partitions.
- Format the EFI partition as FAT32 using the
mkfs.fat -F 32 /dev/sdXycommand. - Mount the EFI partition using the
mount /dev/sdXy /mntcommand. - Copy the kernel and initramfs to the
bootdirectory on the EFI partition. (e.g./mnt/boot) - Install GRUB using the
grub-install --boot-directory=/mnt/boot --efi-directory=/mnt /dev/sdXcommand.
References
- Overall instruction: https://medium.com/@ThyCrow/compiling-the-linux-kernel-and-creating-a-bootable-iso-from-it-6afb8d23ba22
- EFI system partition: https://wiki.archlinux.org/title/EFI_system_partition
- GRUB installation: https://wiki.archlinux.org/title/GRUB#Generate_the_main_configuration_file
- Document for
grub-install: http://man.he.net/man8/grub-install
- Document for
- Kernel config: https://wiki.gentoo.org/wiki/Kernel/Configuration