
[{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/arch-linux/","section":"Tags","summary":"","title":"Arch-Linux","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/arm64/","section":"Tags","summary":"","title":"Arm64","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/llm-free/","section":"Tags","summary":"","title":"Llm-Free","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/qemu/","section":"Tags","summary":"","title":"Qemu","type":"tags"},{"content":"Getting x86_64 guests in QEMU is quite easy (with the PITA of setting up cmdline flags), but doing so for ARM(64) based guests does tend to get more involved with additional setup, and often times it\u0026rsquo;s not straightforward and confusing. Most tutorials involving setting up ARM64 guests is either non existent, or outdated\u0026hellip; While we\u0026rsquo;ve seen tutorials for doing it on tools like UTM for Apple Silicon for running ARM guests, I do want to set it up myself via writing my own QEMU launch scripts.\nI\u0026rsquo;ve learned, that despite most of the time you need to grab the kernel and initramfs images from guest to host and use -kernel and -initrd flags, you can just easily use efistub and EDK2 to facilitate the boot process as normal, without having to carry seperate kernel and init files.\nSetting up however does involve offline bootstrapping which means we would need to directly mount and partition disk images within a running Linux installation, without using Arch ISOs (because its non existent for ARM64), and one time dealing with running EFI shell commands.\nWarnings # This blog post is not meant for beginners and assumes prior experience installing Arch Linux and familiarity with advanced Linux commands. This is a reference guide documenting my setup process, not a step-by-step tutorial. Commands may need adaptation for your environment. Follow at your own risk! Preparation and bootstrapping. # This section explains how I prepared the disk image and bootstrap alarm\nAssuming we\u0026rsquo;re running on a Linux host, we need:\nQEMU NBD Package (This is what I\u0026rsquo;m using) You also need a kernel with nbd support. This can be checked and loaded by running modprobe nbd max_part=8 (max_part means here is maximum partitions, in this case it\u0026rsquo;s 8 but we only need 3 partitions) Alternatively, if you want to use a fixed disk setup, you can simply use qemu-img to create a raw image, losetup, cfdisk, and mount it directly. No need for qemu-nbd for this case. Partitioning tool of your choice, such as: cfdisk. Root privileges (FOR x86_64 hosts) qemu-user-static package and systemd-binfmt or binfmt-support package to make it easier to handle different binary formats and register QEMU binaries if the package has binfmt rule on it using services, on Arch, you also need qemu-user-static-binfmt. Preparing the disk image # We first create an image using the command:\nqemu-img create -f qcow2 arch.qcow2 40g # You can change the size but we recommend the minimum of 10GB in size This creates a dynamically allocated disk (tiny file size and growing). Never choose any formats but qcow2 or raw, as any other formats would render the vdisk unmountable without using special tools which is rare.\nAfter the disk is created, we mount it using qemu-nbd as root\nsudo modprobe nbd max_part=8 # if you haven\u0026#39;t already sudo qemu-nbd -c /dev/nbd0 -f qcow2 arch.qcow2 Partitioning and formatting # After running qemu-nbd command, the /dev/nbd0 is now acting as a block device node which is similar to sda or nvme0n1, which can be manipulated using partitioning tools.\nPick your poison, in this case I\u0026rsquo;m using cfdisk. It will ask you what type of disk, choose gpt.\nThen create the following partitions with types sequentially:\nEFI System Partition (for booting) - 512MB - EFI system NOTE: Use EFI system type, not Linux Filesystem as mistaken in the screenshot.\nSwap (optional but recommended) - 1GB - Linux swap Root Partition - 38GB (or the rest of the disk space) - Linux Filesystem. Write and quit.\nPartitions now appear as:\n/dev/nbd0p1 - EFI system partition /dev/nbd0p2 - Swap /dev/nbd0p3 - Root Filesystem Then format the partitions using the following commands:\nEFI system partition - sudo mkfs.fat -F 32 /dev/nbd0p1 Swap - sudo mkswap /dev/nbd0p2 Root filesystem - sudo mkfs.ext4 /dev/nbd0p3 Bootstrapping # After configuring partitions, we then provision ALarm rootfs to the root partition.\nInstead of using pacstrap, you need to download and decompress a tarball. Download the latest generic Arch Linux ARM64 image here\nThen before we extract the rootfs, we need to mount the root partition somewhere. In this case, /mnt/archroot. Then we can extract the rootfs there.\nsudo mkdir -p /mnt/archroot sudo mount /dev/nbd0p3 /mnt/archroot sudo tar -xpvf ArchLinuxARM-aarch64-latest.tar.gz -C /mnt/archroot After extraction, we might also need to setup ESP mountpoint, in accordance to archwiki you can mount the ESP partition of your liking, however in my case, it\u0026rsquo;s very simple and I don\u0026rsquo;t want to get into efistub-capable kernel updates sync just yet\u0026hellip; which we mount the ESP to /esp and simply copy the kernel and initramfs.\nWe then mount the ESP\nsudo mkdir /mnt/archroot/esp sudo mount /dev/nbd0p1 /mnt/archroot/esp Chrooting and system preparation # While QEMU user + binfmt + chroot works for configuring Arch, as of configuring it through WSL2 with Arch Linux host on 11/29/2025, many binaries complain about not being in terminal or missing pty or stdin despite having devpts mounted when chrooting. I don\u0026rsquo;t know if this is WSL-specific or QEMU-user-specific\nI\u0026rsquo;m not sure if this is an isolated case for me only, as doing this step worked when using actual running arm64 system instead of user-mode emulation without complaining terminal related errors\u0026hellip; I\u0026rsquo;d strongly recommend doing this on actual ARM64 running Linux hosts or QEMU system instance running Alpine virt arm64 live ISO system with EDK2 with the bootstrapped qcow2 being attached.\nThis part is where we chroot into a newly bootstrapped system. Rather than using arch-chroot, we simply mount and chroot as normal.\n# Assuming you mounted an ESP partition before as following this *guide* ROOTFS=/mnt/archroot sudo -s systemctl restart systemd-binfmt.service mount -t proc proc $ROOTFS/proc mount -t sysfs sys $ROOTFS/sys mount --rbind /dev $ROOTFS/dev chroot $ROOTFS /bin/su -l chroot here.\nUpdating the system # Once you\u0026rsquo;re in arch chroot\u0026hellip; update and install the essential packages\npacman-key --init pacman-key --populate pacman -Syu sudo nano networkmanager efibootmgr This is, in most cases it will also update the linux package and rebuild initramfs which will take time especially using qemu-user.\nAfter it\u0026rsquo;s done updating, you do need to copy the files from /boot with Image, initramfs-linux.img and initramfs-linux-fallback.img to esp directory, in my case.. These files will be placed at /esp/EFI/arch\nSystem configuration # The same thing as configuring and personalizing your Arch Linux system, you can prepare the system as usual like locales, timezones, and packages.\nThere are things that you do need to configure.\nFstab # You do atleast need to configure fstab more importantly making sure that root partition / is mounted properly, and swap.\nOptionally you can also set your ESP mountpoint within fstab, I prefer mounting /esp at boot so I can easily update the kernel with efistub used for efi matching the one installed from system (you can refer to guide here for more information). If you\u0026rsquo;re not planning to automatically mount ESP at boot, you can always manually mount partition 1 later.\nBefore you begin, you need to check the UUID of the partitions to make sure it\u0026rsquo;s always properly mounted, as long it can identify and load these partitions within the disk.\n# Assuming you\u0026#39;re in chroot, as a root user blkid /dev/nbd0p1 # ESP (Optional, depending on how you set it up) blkid /dev/nbd0p2 # Swap (Only if you setup swap) blkid /dev/nbd0p3 # Root Partition # Output /dev/nbd0p1: UUID=\u0026#34;DA4E-01DF\u0026#34; BLOCK_SIZE=\u0026#34;512\u0026#34; TYPE=\u0026#34;vfat\u0026#34; PARTUUID=\u0026#34;d137ea7d-73a0-4136-8286-cf9e0241c520\u0026#34; /dev/nbd0p2: UUID=\u0026#34;46f66a8a-47e9-4106-af13-b286a7d2f91d\u0026#34; TYPE=\u0026#34;swap\u0026#34; PARTUUID=\u0026#34;1ed8c07a-0a75-4105-81e8-32d650132f69\u0026#34; /dev/nbd0p3: UUID=\u0026#34;9c61b6b2-0076-47cb-ade2-9d25e6f17820\u0026#34; BLOCK_SIZE=\u0026#34;4096\u0026#34; TYPE=\u0026#34;ext4\u0026#34; PARTUUID=\u0026#34;9ac65e83-4a15-42f1-8452-6bd8465749f2\u0026#34; Once you obtained the UUIDs, you can configure fstab as:\nUUID=DA4E-01DF /esp vfat defaults 0 2 UUID=46f66a8a-47e9-4106-af13-b286a7d2f91d none swap defaults 0 0 UUID=9c61b6b2-0076-47cb-ade2-9d25e6f17820 / ext4 defaults 0 1 You can always customize options\nNetworking # Always enable NetworkManager to automatically setup network at boot. Natively recognizes virtio-net-pci\nsystemctl enable NetworkManager Serial Console Access # In some cases, ARM64 guests may not be able to properly use a display like virtio-gpu-pci, ramfb, as it may not work in all cases due to missing drivers shipped. As we are required to use -nographic, we do need systemd to be bought up to the terminal during boot, in this case we must utilize ttyS0 or ttyAMA0 serial devices which is connected to the primary QEMU serial0 interface (or nographic), so we need to make sure we can login to Arch properly.\nEnable serial-getty for ttyS0 and ttyAMA0\nsystemctl enable serial-getty@ttyS0.service systemctl enable serial-getty@ttyAMA0.service Not done yet, this is only to make sure systemd can be bought to the serial0 interface, but the kernel must have cmdline option console=ttyS0,115200n8 console=ttyAMA0,115200n8 which I\u0026rsquo;ll explain later.\nThe reason we need to enable both is despite ttyAMA0 is primarily for ARM hardware, in most cases within a virt machine type the serial0 is exposed as ttyS0. To make things confusing, some distributions like Debian would typically use ttyAMA0 interface, we can\u0026rsquo;t be sure about everything.\nSSH # If serial console access may not work out, you can also configure SSH\u0026hellip; and you can login to as alarm user\nsystemctl enable sshd.service Note that root password authentication is disabled, it\u0026rsquo;s recommended to allow wheel group in sudoers using EDITOR=nano visudo. You\u0026rsquo;ll be able to login as n:alarm/p:alarm with sudo access through SSH.\nThis works only if you do port forwarding exposing port 22 mapping to higher port number for user networking or bridge/TAP interface that lets you access the port directly through interface.\nYOU DO NOT # Configure GRUB bootloader, instead\u0026hellip; we use efistub which is simply placing the kernel and initramfs to the ESP. First boot setup # Once you configured your arch system with the prerequistes above. We then\nBoot # Download EDK2 images, I recommend extracting the package qemu-efi-aarch64 deb file using ar or file-roller\nYou only need to grab files from /usr/share/AAVMF/ the following:\nAAVMF_CODE.no-secboot.fd AAVMF_VARS.fd Both files must have 64M-67M file size, you do not need to perform dd commands. The latter file is important as this is where we persist the boot settings, consider the variable file as nvram and unique to this installation. Never reuse the EFI variables file.\nFirst boot quirks # One thing to realize is\u0026hellip; we haven\u0026rsquo;t setup EFI boot entry using efibootmgr during chroot step (which is important to prevent tampering your existing EFI settings).\nBy default, we won\u0026rsquo;t be able to get past through Arch boot process\u0026hellip; However:\nThis means, we need to interact with EFI shell for once to manually boot (If you came back here then congrats, efibootmgr failed for some reason)\nWe need to use -display gtk so we can access serial0 through` View \u0026gt; serial0 radio toggle.\nHere is my launch command line:\n# Replace files like firmware and qcow2 with actual ones # Access SSH via ssh -p 8022 alarm@localhost ..\\QEMU\\qemu-system-aarch64.exe ` -M virt ` -m 2048 ` -cpu cortex-a72 ` -accel tcg ` -netdev user,hostfwd=tcp::8022-:22,id=eth0 ` -device virtio-net-pci,netdev=eth0 ` -display gtk ` -device virtio-gpu-pci ` -drive if=pflash,format=raw,readonly=on,file=Firmware\\AAVMF_CODE.no-secboot.fd ` -drive if=pflash,format=raw,file=Firmware\\AAVMF_VARS.fd ` -device virtio-scsi-pci,id=scsi0 ` -drive file=arch.qcow2,format=qcow2,if=none,media=disk,id=scsi0 ` -device scsi-hd,drive=scsi0,bus=scsi0.0,bootindex=1 ` -device nec-usb-xhci,id=xhci ` -device usb-kbd,bus=xhci.0 Navigating the calm before the storm # Once you ran QEMU with GTK window\u0026hellip; you will see Tianocore logo, and it\u0026rsquo;s very normal to not boot into anything.. BUT don\u0026rsquo;t panic, you need to enter the EFI shell by pressing any key and selecting EFI shell from the boot menu\nWithin the EFI shell, you will need to manually execute commands. You need to navigate the Image or kernel to be executed. The fs0: drive points to the found first ESP on the disk.\nDepending on how you setup ESP, in my case, it\u0026rsquo;s \\efi\\arch\\ where the Image EFI executable is located, you will need to adjust paths.\nOnce you\u0026rsquo;re in EFI shell, you typically navigate using DOS-like syntax to your ESP where the kernal is located.\nfs0: cd efi cd arch This is where Image and initramfs-linux.img is located\u0026hellip; once you\u0026rsquo;re in CWD with both files. You run the Linux kernel as\n:: Replace root=UUID=9c61b6b2-0076-47cb-ade2-9d25e6f17820 with your own partition UUID :: Replace initrd=\\efi\\arch\\initramfs-linux.img to the actual ESP structure where your initramfs is located Image root=UUID=9c61b6b2-0076-47cb-ade2-9d25e6f17820 rw initrd=\\efi\\arch\\initramfs-linux.img console=ttyS0,115200n8 console=ttyAMA0,115200n8 systemd.tty.term.ttyS0=xterm-256color systemd.tty.term.ttyAMA0=xterm-256color :: We use xterm-256color so later we can use serial directly to our favorite terminal emulators like Ghostty or Alacritty. And once you execute it, switch to serial0 interface using View \u0026gt; serial0 to see the actual boot process. There should be no kernel panics, it only happens for misconfigured initramfs and potentially misconfigured fstab/root partition.\nYou should see a systemd boot sequence.\nYou can alternatively use EFI shell to directly add boot entries to EFI variables, but I haven\u0026rsquo;t tested yet. See: https://blog.stigok.com/2018/06/04/set-efi-boot-entries-uefi-shell.html and skip the efibootmgr part. Then proceed to here\nAfter it asks me to login # Congrats! You can either login directly to serial0 or use ssh -p 8022 alarm@localhost\nWe\u0026rsquo;re not done yet # One last thing is we configure the boot entry for Arch Linux ARM using efibootmgr, so that we don\u0026rsquo;t have to manually deal with entering EFI shell ever again and typing everything.\nNote that EFI vars file is needed as explained above.\nAs alarm user, assuming with sudo access granted.. run:\nsudo efibootmgr -c \\ -d /dev/sda \\ -p 1 \\ -l \u0026#39;\\EFI\\ARCH\\Image\u0026#39; \\ -u \u0026#39;root=UUID=9c61b6b2-0076-47cb-ade2-9d25e6f17820 rw initrd=\\EFI\\ARCH\\initramfs-linux.img console=ttyS0,115200n8 console=ttyAMA0,115200n8 systemd.tty.term.ttyS0=xterm-256color systemd.tty.term.ttyAMA0=xterm-256color\u0026#39; If you\u0026rsquo;re using virtio-blk-pci, replace sda with vda Again replace \\EFI\\ARCH path to actual ESP structure you setup\nReboot and see if it can automatically boot # Do not do system_reset, shutdown the guest first then run the launch script again unchanged, and check if EFI doesn\u0026rsquo;t complain missing boot / you able to access serial0 and automatically see systemd logs.\nIf you see the system boots, congrats! You now have ready to boot Arch ARM64 Image.\nIf however you still had to enter EFI shell again, check here\nWhen everything goes well # If you\u0026rsquo;re able to boot automatically and have your Arch system set up. You can now directly use the emulated system through terminal.\nWith the launch script using nographic, supports multiplexer, and passes signals like CTRL-C to guest rather than qemu process.\n#!/bin/bash qemu-system-aarch64 \\ -M virt \\ -m 2048 \\ -cpu cortex-a72 \\ -accel tcg \\ -netdev user,hostfwd=tcp::8022-:22,id=eth0 \\ -device virtio-net-pci,netdev=eth0 \\ -device virtio-gpu-pci \\ -object rng-random,filename=/dev/urandom,id=rng0 \\ -device virtio-rng-pci,rng=rng0 \\ -nographic \\ -chardev stdio,mux=on,id=char0,signal=off \\ -serial chardev:char0 \\ -mon chardev=char0,mode=readline \\ -drive if=pflash,format=raw,readonly=on,file=Firmware/AAVMF_CODE.no-secboot.fd \\ -drive if=pflash,format=raw,file=Firmware/AAVMF_VARS.fd \\ -device virtio-scsi-pci,id=scsi0 \\ -drive file=arch.qcow2,format=qcow2,if=none,media=disk,id=scsi0 \\ -device scsi-hd,drive=scsi0,bus=scsi0.0,bootindex=1 \\ -device nec-usb-xhci,id=xhci \\ -device usb-kbd,bus=xhci.0 #-drive file=alpine-virt-3.22.2-aarch64.iso,if=none,media=cdrom,id=cdrom0 ` #-device scsi-cd,drive=cdrom0,bus=scsi0.0,bootindex=2 ` Here\u0026rsquo;s the boot process and successful login: Some tips # When the terminal output looks garbled, you need resize command which you can do by installing xorg-xterm package and running resize; reset which this command ensures it aligns with the serial terminal state such as height and width. As much as possible, use SSH.\nIf you have M-series Mac, you can use QEMU with hvf accelerator or kvm for Linux.\nFor graphical applications, we recommend simply using tigervnc (with port forwarding thru QEMU or SSH)\nIn summary # Installation and bootstrapping is typically done in any online Linux installation with root access.\nEDK2 firmware is used to be able to boot into systems with EFI boot structure which often involves setting up ESP and placing boot files there, it\u0026rsquo;s not possible to use MBR/BIOS as the concept lives in x86 systems. Since Grub is uncommon we instead use a kernel with EFIstub which is enabled in linux package and using the kernel as efi bootlader binary. First time boot is not straightforward.\nDirect graphical display through SDL is not possible, since using display drivers like ramfb or virtio-gpu-pci are often a hit or miss depending how OSes ships display drivers, ARM boards typically doesn\u0026rsquo;t have VGA, in this case, serial is necessary to login to system or SSH.\n","date":"30 November 2025","externalUrl":null,"permalink":"/blogs/setting-up-alarm-qemu/","section":"Blogs","summary":"","title":"Setting up Arch Linux ARM64 for QEMU guide.","type":"blogs"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/tags/virtualization/","section":"Tags","summary":"","title":"Virtualization","type":"tags"},{"content":"","date":"30 November 2025","externalUrl":null,"permalink":"/","section":"WMCB Tech (marcusz's site)","summary":"","title":"WMCB Tech (marcusz's site)","type":"page"},{"content":"I will post some interesting stuffs here soon\u0026hellip;\n","date":"13 October 2025","externalUrl":null,"permalink":"/blogs/","section":"Blogs","summary":"","title":"Blogs","type":"blogs"},{"content":" Who am I? # I am Wyatt Marcus, you can also call me also known as: marcusz\nI am also referred to the following places using different names: Internet handle: @zavocc or @zavocc306 (due to marcusz handle being taken) YouTube: WMCB Tech Steam: BULKHEAD666 (@zavocc306 as URL slug handle) Twitch: geraldobtd Anyway you read it you recognize me. I\u0026rsquo;m a passionate tech enthusiast since childhood, I was in a very different field of interest compared to people around me, tinkering with almost all fields of technology such as programming, cloud, AI, virtualization, security, and other fun stuff like exploring different operating systems and exploring software and applications.\nI\u0026rsquo;m an avid computer person, except for apple products, because I didn\u0026rsquo;t had and don\u0026rsquo;t have apple devices touch my entire life, not because I\u0026rsquo;m poor but I don\u0026rsquo;t like Apple.\nInterests # part time ocassional YouTuber - currently hit 1K subs!!! though not active for now Tower defense, platformer, simulation, and sandbox games like Minecraft, BTD6, Hacknet, and Crash 4. Cloud computing - Azure and AWS Mediocre programming - building Discord bots in python for years, while still getting the hang of next.js, while I learned C#, Java, C\u0026hellip; I don\u0026rsquo;t think I can build practical apps just yet AI - Heavily invested with AI since 2023, and exploring the best and affordable AI tools and models, as well as building AI applications and agentic capabilities, I also have very strong interest with generative media capabilities. Virtualization and containerization Niche music And other niche stuff like running Alpine using QEMU on a phone GitHub What\u0026rsquo;s this website for? # Not much, really, aside from getting to know me, In fact I don\u0026rsquo;t know what to write, just content and commentaries with stuff under me\u0026hellip;\nHowever I may post interesting stuff blogs. Note that if I ever pust even posts that is generated by AI even the slightest, I will always put AI generated or AI assisted taxonomies\nAnyway\u0026hellip; not much to write here though nor nothing interesting to read, I\u0026rsquo;m just a person with passion of tech, uhhh no major achievements so far, if ever, I will update this page for any significant milestones I had, you can visit my social links in h ome\n","date":"13 October 2025","externalUrl":null,"permalink":"/about/","section":"WMCB Tech (marcusz's site)","summary":"","title":"About Me","type":"page"},{"content":"","date":"13 October 2025","externalUrl":null,"permalink":"/tags/personal/","section":"Tags","summary":"","title":"Personal","type":"tags"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]