The idea came from Nir Lichtman video with the title: 'Making Simple Linux Distro from Scratch'
this gist just re-document it in the form of text
- compiled linux kernel
- compiled static-linked busybox
- installed qemu
install busybox to specific directory, I suggest to use /tmp/distro
as working directory
and on the busybox source code directory:
make CONFIG_PREFIX=/tmp/distro/initramfs install
delete linuxrc
file and replace it with init
file
cat > ./initramfs/init << "EOF"
#!/bin/sh
/bin/sh
EOF
compress initramfs with cpio
:
cd initramfs
find . | cpio -o -H newc > ../init.cpio
you can cross-check the content of init.cpio with cpio -v -t -F init.cpio
on linux, you'll need to install dosfstools
package to be able create FAT file system
dd if=/dev/zero of=boot.img bs=1M count=50
mkfs -t fat boot.img
mount boot.img /mnt
syslinux -i /mnt
Use a loopback device, which allows a disk file to be treated as a device. Using a loopback device you can create a three megabyte file on your hard disk and build the filesystem on it.
TIL, such file is called loop-back device.
Try to mount the image to /mnt/whatever
and execute command findmnt -A
to see the loop-back device, reference.
qemu-system-x86_64 -drive format=raw,file=./boot.img,index=0,media=disk \
-initrd ./init.cpio -kernel ./bzImage \
-nographic -enable-kvm -append "root=/ console=ttyS0"
tested on arch linux.
- You can use
TigerVNC
to connect to your guest OS - You can place bzImage and init.cpio to the boot image instead of pass it as parameter to qemu command
just mount the boot image, copy the file, and unmount
but you'll need to specify the path to bzImage later when running the guest, the prompt looks like this:
boot: <path-to-kernel-image>
boot: /bzImage -initrd=/init.cpio
see other kernel parameter option (initrd, console, root):
curl -L -s https://raw.githubusercontent.com/torvalds/linux/master/Documentation/admin-guide/kernel-parameters.txt | less
instead of provide your custom init shell script, it is possible to work with default init by busybox. You just need to provide the /dev
directory and other default standard linux directory for Virtual File System + /etc/fstab
, see LFS chapter 7.3.
you can use extlinux
instead of syslinux
for bootloader on ext file system.
you can use truncate
command instead of dd
.
if you are not providing bootloader configuration, you'll need to specify the path of kernel image.
also, it's possible to build linux system without initramfs, so no need to create archived cpio file and instead, just install the busybox to the disk image or other drive.
when emulate the linux system on QEMU make sure the disk image have read and write permission and it is recommended to pass rw
to kernel parameter.
Does the following statement from tldp:
When the kernel is completely loaded, it initializes device drivers and its internal data structures. Once it is completely initialized, it consults a special location in its image called the ramdisk word. This word tells it how and where to find its root filesystem. A root filesystem is simply a filesystem that will be mounted as ``/''. The kernel has to be told where to look for the root filesystem; if it cannot find a loadable image there, it halts.
have something to do with the Creating Boot Image and the kernel parameter root
?
what's relation between firmware of BIOS/UEFI and the partition layout table such as MBR or GPT?
- stackoverflow.com turns out it's possible to running qemu without TigerVNC
- unix.stackexchange.com - there's 2 possibilities if you encounter rootfs unknown block
- unix.stackexchange.com - missing init can lead to
rootfs unknown block
error
I'm curious what kernel parameters or command line options are passed when the kernel is booted on my current linux distro, and did a little searching.
in the linux distro that I use, it turns out that it is in the grub configuration in the
/boot/grub/grub.cfg
file. specifically located in themenuentry 'linux'
sectionapart from that, I also tried to find out how initramfs works in Linux, and here's the explanation from official documentation
it states that after initramfs is extracted, the kernel will look for the
init
file, so I wanted to make sure it was in the linux distro that was being used.to be able to confirm it, I need to extract the initramfs image in the
/boot
directory:sudo zstd -d /boot/initramfs-linux.img -o /tmp/decompressed.img sudo cpio --verbose -t -F /tmp/decompressed.img | less
and indeed it exists!