Try   HackMD

Linux on Virtual Machine (QEMU)

contributed by < Dung-Ru Tsai >

Ubuntu Image on QEMU

1. Build and Install QEMU

git clone https://gitlab.com/qemu-project/qemu.git
cd qemu
git submodule init
git submodule update --recursive
git checkout v6.1.0
mkdir build
cd build
../configure --prefix=/usr/local/bin \
             --enable-debug \
             --enable-virtfs
make -j8
sudo make install

Dependency:

sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev

2. Bridge host network with TAP interface

Setting up Qemu with a tap interface

  • Create a bridge interface on Host (by netplan)
vim /etc/netplan/01-network-manager-all.yaml
===== copy start =====
network:
  version: 2
  renderer: networkd

  ethernets:
    eno1:
      dhcp4: false
      dhcp6: false

  bridges:
    br0:
      interfaces: [eno1]
      addresses: [192.168.100.4/24]
      gateway4: 192.168.100.254
      mtu: 1500
      nameservers:
        addresses: [8.8.8.8]
      parameters:
          stp: false
          forward-delay: 4
      dhcp4: false
      dhcp6: true
===== copy end =====
sudo netplan apply
sudo ip tuntap add dev tap0 mode tap sudo ip link set dev tap0 master br0 sudo ip link set dev tap0 up

3. Create Disk image

qemu-img create -f qcow2 kvm-generic.qcow2 30G

4. Install Ubuntu ISO

qemu ubuntu20.04
qemu quick reference

#!/bin/bash PREFIX=/home/jake/mount_1TB/gns3server ISO=${PREFIX}/ubuntu-20.04.3-live-server-amd64.iso # Installation media NET=br0 # bridge name OS=linux # os type VM_DISK=${PREFIX}/kvm-generic.qcow2 # VM image on disk sudo qemu-system-x86_64 \ -machine type=q35,accel=hvf \ -smp 2 \ -hda ${VM_DISK}\ -cdrom ${ISO} \ -m 4096 \ -vga virtio \ -usb \ -device usb-tablet \ -enable-kvm \ -cpu host \ -display default \ -boot d \ -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no \ -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01

QEMU Parameter help

qemu-system-x86_64 -accel ?
qemu-system-x86_64 -netdev ?

  • Connect to VNC: 127.0.0.1:5900
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

5. Running the system

#!/bin/bash
PREFIX=/home/jake/mount_1TB/gns3server
NET=br0 # bridge name
OS=linux # os type
VM_DISK=${PREFIX}/kvm-generic.qcow2 # VM image on disk

sudo ip tuntap add dev tap0 mode tap
sudo ip link set dev tap0 master br0
sudo ip link set dev tap0 up

sudo qemu-system-x86_64 \
  -machine type=q35,accel=hvf \
  -smp 4 \
  -hda ${VM_DISK}\
  -m 4096 \
  -vga virtio \
  -usb \
  -device usb-tablet \
  -enable-kvm \
  -cpu host \
  -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no \
  -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01 \
  -serial telnet:127.0.0.1:4322,server,nowait \
  -display default
  -nographic

Another example
6. Redirect GRUB output to serial console (optional)

SerialConsoleHowto

  • Connect to VNC
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • Edit the /etc/default/grub, redirect serial message to ttyS0
# If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. GRUB_DEFAULT=0 GRUB_TIMEOUT=1 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8" # Uncomment to disable graphical terminal (grub-pc only) GRUB_TERMINAL=serial GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" ...
  • Update the GRUB
sudo update-grub
reboot
# Open another terminal
telnet 127.0.0.1 4322

7. Connect with ssh

ssh dutsai@your-vm-ip

Enlarge the disk on VM

https://www.linuxtechi.com/extend-lvm-partitions/
https://www.tecmint.com/extend-and-reduce-lvms-in-linux/

  • Add new the partition
qemu-img resize kvm-generic.qcow2 +60G sudo fdisk -l sudo fdisk -cu /dev/sda To Create new partition Press n. Change the type using t. Type 8e to change the partition type to Linux LVM. Press w to write the changes. sudo sudo fdisk -l #check

  • Add new physical volume and add to volume group
# Add physical volume sudo pvcreate /dev/sda4 $ sudo pvs PV VG Fmt Attr PSize PFree /dev/sda3 ubuntu-vg lvm2 a-- <29.00g 0 /dev/sda4 ubuntu-vg lvm2 a-- 29.26g 0 # Extend Volume Group sudo vgextend ubuntu-vg /dev/sda4 $ sudo vgs # check volume VG #PV #LV #SN Attr VSize VFree ubuntu-vg 1 1 0 wz--n- <29.00g <9.00g
  • Resize Logical Volume
# Get LV Path sudo lvdisplay # Do it $ sudo lvextend /dev/ubuntu-vg/ubuntu-lv -l+100%FREE $ sudo resize2fs -p /dev/ubuntu-vg/ubuntu-lv $ df -h / Filesystem Size Used Avail Use% Mounted on /dev/mapper/ubuntu--vg-ubuntu--lv 28G 19G 8.1G 70% /

< obsoleted >

ARM64 QEMU Environment Setting

Method01: buildroot

1. Set up the QEMU for aarch64

wget https://download.qemu.org/qemu-2.12.1.tar.xz tar xvJf qemu-2.12.1.tar.xz cd qemu-2.12.1 ./configure --target-list=aarch64-softmmu # Work with VirtIO + 9P sudo apt-get install libcap-dev libattr1-dev ./configure --enable-virtfs --target-list=aarch64-softmmu make

--enable-virtfs : 使得 VirtIO + 9P 可以運作,
--target-list : 只產生可以運行 aarch64 架構的 qemu

耐心等待一段時間之後,在 aarch64-softmmu 目錄下可以找到
qemu-system-aarch64

  • Install the binary qemu-system-aarch64 to /usr/bin/
#$ sudo cp qemu-2.12.1/aarch64-softmmu/qemu-system-aarch64 /usr/bin
sudo make install

Buildroot Guide

2. Build AArch64 image with buildroot

$ sudo apt-get install libncurses-dev $ git clone https://github.com/buildroot/buildroot $ make list-defconfigs # Generate the .config $ make qemu_aarch64_virt_defconfig $ make menuconfig # 使用Kernel 5.0 header $ make linux-menuconfig # 開啟 9P File System $ make

3. Run the emulation Qemu

$ qemu-system-aarch64 -M virt \ -cpu cortex-a53 \ -nographic -smp 1 \ -kernel output/images/Image \ -append "root=/dev/vda console=ttyAMA0" \ -netdev user,id=eth0 -device virtio-net-device,netdev=eth0 \ -drive file=output/images/rootfs.ext4,if=none,format=raw,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -fsdev local,security_model=passthrough,id=fsdev0,path=/tmp \ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=host_mount

注意最後兩行 -fsdev and -device, 是為了掛載 host 的目錄才有的

4. 掛載 host 的目錄

mkdir share mount -t 9p -o trans=virtio host_mount share -oversion=9p2000.L

Reference:
0xff07
9psetup

Method-02: Kernel source

1. Set up the QEMU for aarch64

wget https://download.qemu.org/qemu-2.12.1.tar.xz tar xvJf qemu-2.12.1.tar.xz cd qemu-2.12.1 ./configure --target-list=aarch64-softmmu # Work with VirtIO + 9P sudo apt-get install libcap-dev libattr1-dev ./configure --enable-virtfs --target-list=aarch64-softmmu make

--enable-virtfs : 使得 VirtIO + 9P 可以運作,
--target-list : 只產生可以運行 aarch64 架構的 qemu

耐心等待一段時間之後,在 aarch64-softmmu 目錄下可以找到
qemu-system-aarch64

  • Install the binary qemu-system-aarch64 to /usr/bin/
$ sudo cp qemu-2.12.1/aarch64-softmmu/qemu-system-aarch64 /usr/bin
sudo make install

2. Create initramfs cpio (Create the file system)

$ git clone https://github.com/buildroot/buildroot
$ make list-defconfigs
$ make qemu_aarch64_virt_defconfig
$ make menuconfig
  • Target options —> Target Architecture: 選擇 AArch64 little-endian
  • Toolcahin —> Toolchain type: 選擇 External toolchain
    Toolchain: 選擇 Linaro AArch64 2018.05
  • System configuration —> Run a getty (login prompt) after boot
    TTY port 改為 ttyAMA0
  • Filesystem images —> cpio the root filesystem (for use as an initial RAM filesystem)

儲存之後,進行 make。若無異常,可以在 output/images 目錄底下找到 rootfs.cpio

3. Build aarch64 Kernel from source

git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux-stable cd linux-stable sudo apt-get install gcc-aarch64-linux-gnu make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

Edit the .config for 9P

CONFIG_CMDLINE="console-ttyAMA0" # points at your buildrootimage CONFIG_INITRAMFS_SOURCE="/home/jake/QEMU/rootfs.cpio" # needed for virtfs mount CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y

一切就緒就開始編譯核心

## Build the Kernel make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

The image path will show at arch/arm64/boot/Image or linux/vmlinux

4. Run the emulation QEMU

#!/bin/bash qemu-system-aarch64 \ -machine virt \ -machine type=virt \ -cpu cortex-a57 \ -nographic -smp 1 \ -m 8192 \ -kernel /home/jake/QEMU/linux-stable/arch/arm64/boot/Image \ --append "console=ttyAMA0" \ -fsdev local,security_model=passthrough,id=test_dev,path=/home/jake/Workspace/ -device virtio-9p-pci,id=fsdev0,fsdev=test_dev,mount_tag=host_mount
  • -kernel : 指定第二步驟編譯好的 image path
  • -fsdev, path : 指定共享目錄的路徑
    • path 是在 host 這邊要目錄分享的路徑,這邊是用 /home/jake/Workspace/
    • 而最後面那個 mount_tag=host_mount 是到時候在 guest 裡面 mount 時會用到.

5. 掛載 host 的目錄

透過 VirtIO + 9P 使得 guest 與 host 共享目錄:
mount -t 9p -o trans=virtio host_mount /mnt

  • Exit the QEMU:
    Ctrl+a X

Reference

X86_64 QEMU Environment Setting

[PASS]

Method-01 buildroot source

1. Build the QEMU


wget https://download.qemu.org/qemu-4.2.0.tar.xz
tar xvJf qemu-4.2.0.tar.xz
cd qemu-4.2.0
# Work with VirtIO + 9P
sudo apt-get install libcap-dev libattr1-dev
sudo apt install build-essential kernel-package fakeroot libncurses5-dev libssl-dev ccache flex bison libelf-dev
sudo apt-get install libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev install libnfs-dev libiscsi-dev

./configure --enable-virtfs --target-list=x86_64-softmmu --enable-debug
make -j8
... wait for a while
sudo make install

--enable-virtfs: Enable the virtual file IO system

2. Build the Linux from buildroot

Check the basic build guide incat README

make list-defconfigs
make qemu_x86_64_defconfig
make
# find the kernel, bootloader, root filesystem, etc. in output/images

3. Run the qemu with Linux

Check the qemu startup guide
cat board/qemu/x86_64/readme.txt

qemu-system-x86_64 -M pc \
    -kernel output/images/bzImage \
    -drive file=output/images/rootfs.ext2,if=virtio,format=raw \
    -append "rootwait root=/dev/vda console=tty1 console=ttyS0" \
    -serial stdio \
    -net nic,model=virtio \
    -net user
# Optionally add -smp N to emulate a SMP system with N CPUs.
udhcpc: sending select for 10.0.2.15
udhcpc: lease of 10.0.2.15 obtained, lease time 86400
deleting routers
random: mktemp: uninitialized urandom read (6 bytes read)
adding dns 10.0.2.3
OK

Welcome to Buildroot
buildroot login: root

Method-02 Kernel Source

1. Build the QEMU

sudo apt update -y
sudo apt install libcap-ng-dev libattr1-dev build-essential kernel-package fakeroot libncurses5-dev libssl-dev ccache flex bison libelf-dev libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev libnfs-dev libiscsi-dev ninja-build

wget https://download.qemu.org/qemu-6.2.0.tar.xz
tar xvJf qemu-6.2.0.tar.xz
cd qemu-6.2.0

./configure --enable-virtfs --target-list=x86_64-softmmu --enable-debug
make -j8
... wait for a while
sudo make install

--enable-virtfs: Enable the virtual file IO system

2.1 Create the root file system

$ git clone https://github.com/buildroot/buildroot
$ make list-defconfigs
$ make qemu_x86_64_defconfig
$ make menuconfig
  • Target options —> Target Architecture: 選擇 x86_64
  • Filesystem images —> ext2/3/4 root file system

cpio the root filesystem (for use as an initial RAM filesystem)

儲存之後,進行 make。若無異常,可以在 output/images 目錄底下找到 rootfs.cpio

2.2 Build Kernel from linux source

make ARCH=x86_64 x86_64_defconfig make ARCH=x86_64 menuconfig make -j8
  • Kernel hacking -> Compile the kernel with debug info -> Provide GDB scripts for kernel debugging
  • Reduce debugging information option off
  • Force unload the kernel module: MODULE_FORCE_UNLOAD
  • KGDB
CONFIG_DEBUG_INFO=y
CONFIG_FRAME_POINTER=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
  • Ensure the following 9P options are enabled in the kernel configuration.
    CONFIG_NET_9P=y
    CONFIG_NET_9P_VIRTIO=y
    CONFIG_NET_9P_DEBUG=y (Optional)
    CONFIG_9P_FS=y
    CONFIG_9P_FS_POSIX_ACL=y
    CONFIG_PCI=y
    CONFIG_VIRTIO_PCI=y
    CONFIG_PCI_HOST_GENERIC=y (only needed for the QEMU Arm 'virt' board)

The final image will show in arch/x86/boot/bzImage.

  • ramfile system only
# Only for ramfile system when you choose in builtroot Filesystem images is cpio:
CONFIG_INITRAMFS_SOURCE="/home/jake/QEMU/rootfs.cpio"

3.1 Run qemu with own Linux Kernel (No File system)

qemu-system-x86_64 -s -S\
-kernel arch/x86/boot/bzImage \
-hda /dev/zero \
-append "root=/dev/zero console=ttyS0" \
-serial stdio -display none

Try the KGDB

cd linux
gdb ./vmlinux
(gdb) target remote localhost:1234
(gdb) break start_kernel
(gdb) c
Continuing.

Breakpoint 1, start_kernel () at init/main.c:786
786	{

3.2 Run qemu with own Linux Kernel with Files system

qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
-boot c -m 2049M \
-append "root=/dev/sda rw console=ttyS0,115200 acpi=off nokaslr" \
-hda output/images/rootfs.ext4 \
-fsdev local,security_model=passthrough,id=fsdev0,path=/home/dutsai/Workspace_vm \
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=host_mount \
-nographic \
-monitor telnet::45454,server,nowait \
-serial mon:stdio
  • -kernel : 指定第二步驟編譯好的 image path
  • -fsdev, path : 指定共享目錄的路徑
    • path 是在 host 這邊要目錄分享的路徑,這邊用 /home/dutsai/Workspace_vm
    • mount_tag=host_mount 在 guest 裡面 mount 時會用.
  • -serial mon:stdio Send Ctrl+C to guest
    • Ctrl+a X to exit qemu.

4. Mount host folder

https://wiki.qemu.org/Documentation/9psetup

# In qemu mount -t 9p -o trans=virtio host_mount /root -oversion=9p2000.L

5. KGDB

qemu-system-x86_64 \
-kernel linux-5.16.14/arch/x86/boot/bzImage \
-boot c -m 4096M \
-append "root=/dev/sda rw console=ttyS0,115200 acpi=off nokaslr" \
-hda buildroot/output/images/rootfs.ext4 \
-fsdev local,security_model=passthrough,id=fsdev0,path=/home/dutsai/Workspace_vm \
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=host_mount \
-nographic \
-monitor telnet::45454,server,nowait \
-serial mon:stdio \
-S -gdb tcp::33004

Try to open another terminal to run gdb.

cd linux
gdb ./vmlinux
(gdb) target remote localhost:33004
(gdb) break start_kernel
(gdb) c
Continuing.

Breakpoint 1, start_kernel () at init/main.c:786
786	{

Method-03 Ycoto

RISC-V Embedded Linux - Get started with Buildroot/Yocto

Update Linux Kernel

$ sudo apt-get install liblz4-tool libc6-dev libncurses5-dev openssl wget ca-certificates bc libzstd-dev zstd $ sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison dwarves $ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.17.9.tar.xz $ cp /boot/config-`uname -r` .config $ make menuconfig 選擇 load 再選擇 save # make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig $ scripts/config --disable SYSTEM_TRUSTED_KEYS $ scripts/config --disable SYSTEM_REVOCATION_KEYS CONFIG_DEBUG_INFO_BTF=n # Build $ make -j12 $ make modules -j12 # Install $ sudo make INSTALL_MOD_STRIP=1 modules_install -j 4 $ sudo make install $ sudo mkinitramfs /lib/modules/5.17.9/ -o /boot/initrd.img-5.17.9 $ sudo update-grub2 # Install Method2 $ su -c "make modules_install install"

Update the GRUB

vim /etc/default/grub

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.10.130-0510130-generic"
# GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=8
$ sudo update-grub

Patch RT (Linux)

build kernel command

$ sudo apt-get update $ sudo apt-get install build-essential linux-tools-common linux-tools-generic cmake automake libtool libusb-1.0-0-dev openssh-server samba vim linux-headers-`uname -r` can-utils libpopt-dev $ mkdir -p kernel $cd kernel # Download the kernel linux-4.4.60.tar.gz and patch-4.4.60-rt73.patch.gz $ wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.4.60.tar.gz $ wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/4.4/older/patch-4.4.60-rt73.patch.gz $ tar -xzvf linux-4.4.60.tar.gz $ cd linux-4.4.60 $ gzip -cd ../patch-4.4.60-rt73.patch.gz | patch -p1 --verbose $ sudo apt-get install libncurses-dev libssl-dev # Change .config file $ make menuconfig ##Graphical Menu## # Processor type and features ---> [Enter] # Preemption Model (Voluntary Kernel Preemption (Desktop)) [Enter] # Fully Preemptible Kernel (RT) [Enter] #Select # [Esc][Esc] # <Save> [Enter] /* # Kernel hacking --> [Enter] # Memory Debugging [Enter] # Check for stack overflows #Already deselected - do not select # [Esc][Esc] # [Right Arrow][Right Arrow] # .config # <Okay> [Enter] # <Exit> [Enter] # [Esc][Esc] # [Right Arrow] # <Exit> [Enter] */ make sudo make modules_install -j3 sudo make install -j3

After install the kernel

  • Verify and update. Verify that
    initrd.img-4.4.60-rt73,
    vmlinuz-4.4.60-rt73, and
    config-4.4.60-rt73 exist. They should have been created in the previous step.
$cd /boot
$ ls

Set the default kernel

1. Go to see the menuentry in

vim /boot/grub/grub.cfg

search your menuentry version and copy it.

menuentry 'Ubuntu, with Linux 4.4.60-rt73'

  1. sudo vim /etc/default/grub
$ sudo vim /etc/default/grub GRUB_DEFAULT='Advanced options for Ubuntu>Ubuntu, with Linux 4.4.60-rt73' GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1"

CPU Isolation

sudo vim /etc/default/grub ===> add GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1" sudo update-grub sudo reboot # Loogin Permission sudo vim /etc/ssh/sshd_config ===> modify "PermitRootLogin yes"
  1. sudo update-grub
    • it will show the error message, please change the GRUB_DEFAULT by use the correct one on error message.
  2. In BIOS, Turn off Hyper threading

Lima macOS

1st Start

limactl start --name=default template://ubuntu-lts
limactl shell default

https://github.com/lima-vm/lima

sudo apt-get install sshfs build-essential linux-tools-common linux-tools-generic  automake* linux-headers-`uname -r` net-tools wireless-tools

linux-image-5.4.0-109-generic_5.4.0-109.123_arm64.deb

sudo apt install linux-modules-extra-`uname -r`
  • YAML file on mac:
vim /Users/dutsai/.lima/default

# Ubuntu 20.04 LTS (Focal Fossa)

# This example requires Lima v0.7.0 or later.
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "https://cloud-images.ubuntu.com/releases/20.04/release-20220302/ubuntu-20.04-server-cloudimg-amd64.img"
  arch: "x86_64"
  digest: "sha256:243157ea0390890d6e60ce5e08e0249b16e23b6b313b63aed50f39f92b020afe"
- location: "https://cloud-images.ubuntu.com/releases/20.04/release-20220302/ubuntu-20.04-server-cloudimg-arm64.img"
  arch: "aarch64"
  digest: "sha256:fb2b4efdbf0011bd2a9fd49e9d31efdd252966c889f07b5d246351ec5734a329"
# Fallback to the latest release image.
# Hint: run `limactl prune` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img"
  arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-arm64.img"
  arch: "aarch64"

mounts:
- location: "~"
- location: "~/Workspace_mac/vwifi"
  writable: true
- location: "/tmp/lima"
  writable: true

User mode Linux

https://hackmd.io/@sysprog/user-mode-linux-env

$ sudo apt install build-essential libncurses-dev flex bison
$ sudo apt install xz-utils wget ca-certificates bc fakeroot
$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.12.tar.xz
$ tar xvf linux-5.12.tar.xz
$ make mrproper
$ make defconfig ARCH=um SUBARCH=x86_64
$ make linux ARCH=um SUBARCH=x86_64 -j `nproc`
  • Root file system
$ export REPO=http://dl-cdn.alpinelinux.org/alpine/v3.13/main
$ mkdir -p rootfs
$ curl $REPO/x86_64/APKINDEX.tar.gz | tar -xz -C /tmp/
$ export APK_TOOL=`grep -A1 apk-tools-static /tmp/APKINDEX | cut -c3- | xargs printf "%s-%s.apk"`
$ curl $REPO/x86_64/$APK_TOOL | fakeroot tar -xz -C rootfs
$ fakeroot rootfs/sbin/apk.static \
    --repository $REPO --update-cache \
    --allow-untrusted \
    --root $PWD/rootfs --initdb add alpine-base
$ echo $REPO > rootfs/etc/apk/repositories
$ echo "LABEL=ALPINE_ROOT / auto defaults 1 1" >> rootfs/etc/fstab

howto-usermode-linux

Original Assignment info: F08: smallsys