Skip to content

Instantly share code, notes, and snippets.

@RealYukiSan
Last active April 21, 2024 12:36
Show Gist options
  • Save RealYukiSan/c69d9cc9120c1e5d7b5afcf371e3f79d to your computer and use it in GitHub Desktop.
Save RealYukiSan/c69d9cc9120c1e5d7b5afcf371e3f79d to your computer and use it in GitHub Desktop.
Play with linux system on QEMU

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

Requirement

  • compiled linux kernel
  • compiled static-linked busybox
  • installed qemu

Creating initramfs

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

Creating boot image

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.

Run it on QEMU

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.

Alternative

  • 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

Note

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.

Unanswered Question

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?

Link and References

@RealYukiSan
Copy link
Author

RealYukiSan commented Apr 15, 2024

it's kinda unique that busybox using soft-link and applet mechanism to refer to a specific program

@RealYukiSan
Copy link
Author

RealYukiSan commented Apr 15, 2024

I think the reason Nir Lichtman replace the default init from busybox is for the sake of simplicity, the busybox itself mention about it on their FAQ about building full bootable system

@RealYukiSan
Copy link
Author

also see other gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment