# Build Alpine's Root Filesystem (Bootstrap) ###### tags: `Alpine`, `Virtual Machine`, `QEMU`, `bootstrap`, `aarch64` ## Prepare RAW Disk 1. Create the disk image and have partitions: **Boot** and **Root** partition ```shell= $ dd if=/dev/zero of=~/qemu-images/simple-alpine.img bs=8M count=16 16+0 records in 16+0 records out 134217728 bytes (134 MB, 128 MiB) copied, 0.086382 s, 1.6 GB/s $ fdisk -l ~/qemu-images/simple-alpine.img Disk /home/zack/qemu-images/simple-alpine.img: 128 MiB, 134217728 bytes, 262144 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ac31012 Device Boot Start End Sectors Size Id Type /home/zack/qemu-images/simple-alpine.img1 * 2048 206847 204800 100M b W95 FAT32 /home/zack/qemu-images/simple-alpine.img2 206848 262143 55296 27M 83 Linux ``` 2. Format the the **Boot** and **Root** partition ```shell= $ mkfs.vfat -v --offset=2048 ~/qemu-images/simple-alpine.img $((100*1024*1024/1024)) $ mkfs.ext4 -E offset=$((512*206848)) ~/qemu-images/simple-alpine.img ``` ## Have the Kernel and Initial RAM Disk from Alpine Download the NETBOOT image from [Alpine's download](https://alpinelinux.org/downloads/). And, decompress it. Here is another place to download https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/netboot/ ## Bootstrap with QEMU VM 1. Launch the QEMU aarch64 VM with the NETBOOT. We are going to take the normal aarch64 QEMU VM as the example. So, choose the NETBOOT image's **vmlinuz-lts** and **initramfs-lts** as the kernel and initial RAM disk ```shell= $ qemu-system-aarch64 \ -smp 2 \ -M virt \ -cpu cortex-a57 \ -m 1G \ -kernel ~/alpine-image/temp/boot/vmlinuz-lts \ -initrd ~/alpine-image/temp/boot/initramfs-lts \ --append "console=ttyAMA0 ip=dhcp alpine_repo=http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ modloop=http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/netboot/modloop-lts" \ -hda ~/qemu-images/simple-alpine.img \ -serial stdio ``` 2. Mount the root partition of the disk image in the VM ```shell= # mount -t ext4 /dev/vda2 /mnt/ ``` 3. Build the root filesystem with Alpine's bootstrap. And, the target root path is `/mnt/` ```shell= # apk add apk-tools-static # apk.static --arch $(uname -m) \ -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ \ -U \ --allow-untrusted \ --root /mnt/ \ --initdb add alpine-base ``` 4. Add `ttyAMA0::respawn:/sbin/getty -L 0 ttyAMA0 vt100` into `/mnt/etc/inittab` to get the VM's serial tty 5. Set `/etc/fstab` ```shell= # cat /mnt/etc/fstab /dev/vda2 / ext4 rw,relatime 0 0 /dev/vda1 /boot vfat rw,relatime 0 0 # mkdir /mnt/boot ``` 6. Set Network * Set interface ```shell= # cat /mnt/etc/network/interfaces auto eth0 iface eth0 inet dhcp ``` * Set hostname ```shell= # echo "alpine-arm64" > /mnt/etc/hostname ``` * Enable networking service for each boot ```shell= # chroot /mnt/ # rc-update add networking ``` 7. Exit the chroot and poweroff the VM 8. Can launch a new QEMU aarch64 VM with own built kernel and the disk image ```shell= $ qemu-system-aarch64 \ -smp 2 \ -M virt \ -cpu cortex-a57 \ -m 1G \ -kernel ~/linux-stable/arch/arm64/boot/Image \ --append "console=ttyAMA0 root=/dev/vda2 rw rootfstype=ext4" \ -hda ~/qemu-images/simple-alpine.img \ -serial stdio ``` ## Reference * [fdisk](https://man7.org/linux/man-pages/man8/fdisk.8.html) * [mkfs.vfat](https://man7.org/linux/man-pages/man8/mkfs.vfat.8.html) * [mkfs.ext4](https://man7.org/linux/man-pages/man5/ext4.5.html) * [mount](https://man7.org/linux/man-pages/man8/mount.8.html) * [Bootstrapping Alpine Linux](https://wiki.alpinelinux.org/wiki/Bootstrapping_Alpine_Linux) * [OpenRC in Alpine](https://wiki.alpinelinux.org/wiki/OpenRC)