Skip to content

Instantly share code, notes, and snippets.

@robertkirkman
Forked from thalamus/ArchLinuxARM-M1
Last active December 7, 2025 12:57
Show Gist options
  • Select an option

  • Save robertkirkman/f79441c79811ad263f2f881f7864e793 to your computer and use it in GitHub Desktop.

Select an option

Save robertkirkman/f79441c79811ad263f2f881f7864e793 to your computer and use it in GitHub Desktop.
How to install Arch Linux ARM or Debian ARM in QEMU full system emulator

How to install a GNU/Linux ARM emulator

Prerequisites:

  • A PC with a Linux distribution - Arch Linux amd64 used here

Dependencies (for Arch Linux amd64 but very easy to get on most distros):

  1. Download the Arch Linux ARM generic tarball and create an image, replacing 60G with your desired maximum size.
wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
qemu-img create -f qcow2 arch-aarch64.qcow2 60G

Tip

Step 1 equivalent for Debian guest:

wget https://cdimage.debian.org/cdimage/release/current/arm64/iso-dvd/debian-12.7.0-arm64-DVD-1.iso
wget https://cdimage.debian.org/cdimage/release/current/arm64/iso-dvd/SHA256SUMS
shasum -a 256 --ignore-missing -c SHA256SUMS
qemu-img create -f qcow2 debian-aarch64.qcow2 60G

Users of Debian guest should now skip to step 7.

  1. Become root, connect the image to nbd and partition it with fdisk.
sudo modprobe nbd
sudo qemu-nbd --connect=/dev/nbd0 arch-aarch64.qcow2
sudo fdisk /dev/nbd0
  • then g (to create a new GPT partition table)
  • then n (to create a new partition), then Enter twice, then +400M and Enter
  • then t (to change the type), then 1 for EFI System Partition
  • then n and Enter three times, then w to write changes and exit
  1. Format the partitions of the image, mount them, and extract the Arch Linux ARM tarball to them.
sudo mkfs.vfat /dev/nbd0p1
sudo mkfs.ext4 /dev/nbd0p2
sudo mkdir rootfs
sudo mount /dev/nbd0p2 rootfs
sudo mkdir rootfs/boot
sudo mount /dev/nbd0p1 rootfs/boot 
sudo bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C rootfs
  1. Edit fstab.
  • You will need both partitions' UUIDs - the UUID of the vfat partition in /dev/nbd0p1 looks like UUID="XXXX-XXXX" and the UUID of the ext4 partition in /dev/nbd0p2 looks like UUID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX":
sudo blkid
  • Then, edit rootfs/etc/fstab:
sudo vim rootfs/etc/fstab
  • Paste the following, replacing each instance of X with the corresponding digit of the UUID of the corresponding partition, /dev/nbd0p1 and /dev/nbd0p2 respectively, then save the file:
/dev/disk/by-uuid/XXXX-XXXX                            /boot vfat defaults 0 0
/dev/disk/by-uuid/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /     ext4 defaults 0 0
  1. Create startup.nsh, which is read by the UEFI firmware to initially boot.
  • Edit rootfs/boot/startup.nsh:
sudo vim rootfs/boot/startup.nsh
  • Paste the following, replacing each instance of X with the corresponding digit of the UUID of the /dev/nbd0p2 partition, then save the file:
Image root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=\initramfs-linux.img
  1. Unmount the partitions, sync, disconnect the image from nbd, and exit the root shell.
sudo umount -R rootfs
sudo sync
sudo qemu-nbd --disconnect /dev/nbd0
sudo rmmod nbd
  1. Create flash images for the UEFI firmware and variables

Note

if you downloaded the RELEASEAARCH64_QEMU_EFI.fd instead of using the one from your distro's package, use that here in place of the QEMU_CODE.fd. AARCH64_QEMU_EFI.fds (which are installed into "flash0.img" here) can very slowly become slightly outdated over time. After using one with an Arch Linux ARM emulator for several years, then installing a new emulator from scratch and comparing its behavior with the old one, I've noticed very slight, subtle differences in behavior between them in the pre-boot stage before guest OS code runs. I would say the newer one's behavior seems slightly more polished and desirable.

truncate -s 64M flash0.img
truncate -s 64M flash1.img
dd if=/usr/share/edk2-armvirt/aarch64/QEMU_CODE.fd of=flash0.img conv=notrunc
  1. Launch QEMU, removing or adding anything you see fit.
qemu-system-aarch64 -M virt -m 8192 -cpu cortex-a72 -smp 8 \
      -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash0.img \
      -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash1.img \
      -drive if=none,file=arch-aarch64.qcow2,format=qcow2,id=hd0 \
      -device virtio-scsi-pci,id=scsi0 \
      -device scsi-hd,bus=scsi0.0,drive=hd0,bootindex=1 \
      -nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
      -monitor none -display none -vga none

Tip

Step 8 equivalent for Debian guest:

qemu-system-aarch64 -M virt -m 8192 -cpu cortex-a72 -smp 8 \
     -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash0.img \
     -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash1.img \
     -drive if=none,file=debian-aarch64.qcow2,format=qcow2,id=hd0 \
     -cdrom debian-12.7.0-arm64-DVD-1.iso \
     -device virtio-scsi-pci,id=scsi0 \
     -device scsi-hd,bus=scsi0.0,drive=hd0,bootindex=2 \
     -nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
     -nographic
  1. Upon successful first boot, initialize Arch Linux ARM and install a new bootloader.
  • Log in as alarm, password alarm:
ssh -p 2222 alarm@localhost
  • Become root, password root:
su
  • Initialize the pacman keyring, update the system and install efibootmgr, replacing each instance of X with the corresponding digit of the UUID of the /dev/nbd0p2 partition from earlier (which is now /dev/sda2), then shut down:
pacman-key --init
pacman-key --populate archlinuxarm
pacman -Syu
pacman -S efibootmgr
efibootmgr --disk /dev/sda --part 1 --create --label "Arch Linux ARM" --loader /Image --verbose \
           --unicode 'root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=\initramfs-linux.img'
poweroff

Tip

Step 9 equivalent for Debian guest:

  • At the EDK II Shell, type this command
FS1:\efi\boot\grubaa64.efi

Users of Debian guest can choose "Install" and use the guided installer.

  1. Launch QEMU again, exactly as in step 8.
qemu-system-aarch64 -M virt -m 8192 -cpu cortex-a72 -smp 8 \
      -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash0.img \
      -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash1.img \
      -drive if=none,file=arch-aarch64.qcow2,format=qcow2,id=hd0 \
      -device virtio-scsi-pci,id=scsi0 \
      -device scsi-hd,bus=scsi0.0,drive=hd0,bootindex=1 \
      -nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
      -monitor none -display none -vga none

Tip

Step 10 equivalent for Debian guest:

qemu-system-aarch64 -M virt -m 8192 -cpu cortex-a72 -smp 8 \
     -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash0.img \
     -drive if=pflash,media=disk,format=raw,cache=writethrough,file=flash1.img \
     -drive if=none,file=debian-aarch64.qcow2,format=qcow2,id=hd0 \
     -device virtio-scsi-pci,id=scsi0 \
     -device scsi-hd,bus=scsi0.0,drive=hd0,bootindex=2 \
     -nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
     -nographic
  1. Proceed with configuring Arch Linux ARM as normal (time, locales, users, software, configuration), using the Arch Linux Wiki as a guide.

Note

If your host has a simple network configuration, you can replace the slower -nic user argument with an efficient -netdev tap argument if you want using my minimal tap0 guide.

#!/bin/bash
# qemu-system gives the power of fine-grained control over guest:
# - firmware
# - bootloader
# - kernel
# - init system
# - docker engine
# that proot, chroot, qemu-user, docker and other containers usually do not
set -e
# guest firmware architecture
EDK2_ARCHITECTURE=AARCH64
# guest bootloader architecture
GRUB2_ARCHITECTURE=aa64
# guest kernel architecture
KERNEL_ARCHITECTURE=aarch64
# guest userspace architecture
USERSPACE_ARCHITECTURE=arm64
# guest termux-docker architecture
TERMUX_ARCH=arm
GUEST_RELEASE=trixie
QEMU_VERSION=10.0.3
OPENSSH_VERSION=10.0p2
# manifestation of https://github.com/tianocore/edk2/issues/10663
# last known PXE-compatible QEMU_EFI.fd builds from a tianocore/edk2 commit around early 2024
# QEMU_EFI.fd files require a GCC cross toolchain to build, and the retrage repository is not official,
# but it builds them entirely in CI.
EDK2_NIGHTLY_RELEASE=cdffebde798a04e793b8b7e4ad857c8d06e80af9
GUEST_SRCURL=https://deb.debian.org/debian/dists/${GUEST_RELEASE}/main/installer-${USERSPACE_ARCHITECTURE}/current/images/netboot/netboot.tar.gz
QEMU_SRCURL=https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
OPENSSH_SRCURL=https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${OPENSSH_VERSION}.tar.gz
EDK2_NIGHTLY_SRCURL=https://github.com/retrage/edk2-nightly/raw/${EDK2_NIGHTLY_RELEASE}/bin/RELEASE${EDK2_ARCHITECTURE}_QEMU_EFI.fd
EMULATOR_INSTALL_DIR=$(pwd)/emulator
__install_qemu-system() {
rm -rf "${EMULATOR_INSTALL_DIR}"
mkdir -p "${EMULATOR_INSTALL_DIR}"
pushd "${EMULATOR_INSTALL_DIR}"
mkdir -p qemu-src/
pushd qemu-src/
wget -O qemu-src.tar.xz "${QEMU_SRCURL}"
tar xvJf qemu-src.tar.xz --strip-components=1
./configure \
--disable-docs \
--disable-fuzzing \
--disable-gettext \
--disable-modules \
--disable-sparse \
--disable-guest-agent \
--disable-qga-vss \
--disable-kvm \
--disable-xen \
--disable-stack-protector \
--disable-dbus-display \
--disable-tpm \
--disable-keyring \
--disable-libkeyutils \
--disable-af-xdp \
--disable-attr \
--disable-auth-pam \
--disable-brlapi \
--disable-bzip2 \
--disable-cap-ng \
--disable-blkio \
--disable-bpf \
--disable-curl \
--disable-gio \
--disable-glusterfs \
--disable-hv-balloon \
--disable-libdw \
--disable-libnfs \
--disable-mpath \
--disable-iconv \
--disable-curses \
--disable-libcbor \
--disable-gnutls \
--disable-nettle \
--disable-gcrypt \
--disable-libdaxctl \
--disable-libpmem \
--disable-libssh \
--disable-libudev \
--disable-libusb \
--disable-lzfse \
--disable-lzo \
--disable-rbd \
--disable-opengl \
--disable-rdma \
--disable-gtk \
--disable-sdl \
--disable-sdl-image \
--disable-seccomp \
--disable-smartcard \
--disable-snappy \
--disable-spice \
--disable-spice-protocol \
--disable-u2f \
--disable-canokey \
--disable-usb-redir \
--disable-l2tpv3 \
--disable-netmap \
--disable-pixman \
--disable-vde \
--disable-vmnet \
--disable-virglrenderer \
--disable-rutabaga-gfx \
--disable-png \
--disable-vnc \
--disable-vte \
--disable-xkbcommon \
--disable-zstd \
--disable-qpl \
--disable-uadk \
--disable-qatzip \
--disable-fuse \
--disable-alsa \
--disable-jack \
--disable-oss \
--disable-pa \
--disable-pipewire \
--disable-sndio \
--disable-vhost-kernel \
--disable-vhost-net \
--disable-vhost-user \
--disable-vhost-crypto \
--disable-vhost-vdpa \
--disable-libvduse \
--disable-capstone \
--disable-selinux \
--disable-replication \
--disable-colo-proxy \
--disable-bochs \
--disable-cloop \
--disable-dmg \
--disable-qcow1 \
--disable-vdi \
--disable-vhdx \
--disable-vmdk \
--disable-vpc \
--disable-vvfat \
--disable-qed \
--disable-parallels \
--disable-qom-cast-debug \
--disable-linux-aio \
--disable-linux-io-uring \
--disable-virtfs \
--enable-lto \
--prefix="${EMULATOR_INSTALL_DIR}" \
--target-list="${KERNEL_ARCHITECTURE}-softmmu"
make -j$(nproc) install
popd # qemu-src
mkdir -p openssh-src/
pushd openssh-src/
wget -O openssh-src.tar.gz "${OPENSSH_SRCURL}"
tar xzvf openssh-src.tar.gz --strip-components=1
# prevent from touching real ~/.ssh folder
find . -type f | xargs -n 1 sed -i \
-e "s|~/\.ssh|$EMULATOR_INSTALL_DIR/tftp|g" \
-e "s|\"~/\"|\"$EMULATOR_INSTALL_DIR/\"|g" \
-e "s|user_pw->pw_dir|\"$EMULATOR_INSTALL_DIR/\"|g" \
-e "s|s->pw->pw_dir|\"$EMULATOR_INSTALL_DIR/\"|g" \
-e "s|pw->pw_dir|\"$EMULATOR_INSTALL_DIR/\"|g" \
-e "s|\"\.ssh\"|\"tftp\"|g"
export CFLAGS="-Wno-incompatible-pointer-types"
touch configure
./configure \
--disable-largefile \
--disable-pkcs11 \
--disable-security-key \
--disable-strip \
--disable-etc-default-login \
--disable-fd-passing \
--disable-lastlog \
--without-shadow \
--with-default-path="" \
--with-privsep-path="${EMULATOR_INSTALL_DIR}"/var/empty \
--with-pid-dir="${EMULATOR_INSTALL_DIR}"/var/run \
--prefix="${EMULATOR_INSTALL_DIR}"
make -j$(nproc)
make install
popd # openssh-src
export PATH="${EMULATOR_INSTALL_DIR}/bin:${PATH}"
truncate -s 64M firmware.img
truncate -s 64M efivars.img
wget -O QEMU_EFI.fd "${EDK2_NIGHTLY_SRCURL}"
dd if=QEMU_EFI.fd of=firmware.img conv=notrunc
qemu-img create -f qcow2 debian-"${USERSPACE_ARCHITECTURE}".qcow2 16G
mkdir -p tftp/
pushd tftp/
ssh-keygen -b 2048 -t ed25519 -f ./id_ed25519 -q -N ""
wget -O netboot.tar.gz "${GUEST_SRCURL}"
tar xzvf netboot.tar.gz
patch -p1 << EOF
--- a/debian-installer/$USERSPACE_ARCHITECTURE/grub/grub.cfg
+++ b/debian-installer/$USERSPACE_ARCHITECTURE/grub/grub.cfg
@@ -3,9 +3,11 @@ set menu_color_highlight=white/blue
insmod gzio
-menuentry 'Install' {
+set timeout=1
+
+menuentry 'Custom Automated Install' {
set background_color=black
- linux /debian-installer/$USERSPACE_ARCHITECTURE/linux --- quiet
+ linux /debian-installer/$USERSPACE_ARCHITECTURE/linux auto=true priority=critical url=tftp://192.168.130.2/preseed.cfg ---
initrd /debian-installer/$USERSPACE_ARCHITECTURE/initrd.gz
}
menuentry 'Graphical install' {
EOF
cat > preseed.cfg << EOF
#_preseed_V1
# this configuration is based on https://www.debian.org/releases/bookworm/example-preseed.txt
d-i debian-installer/locale string en_US
d-i keyboard-configuration/xkb-keymap select us
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string debian-$USERSPACE_ARCHITECTURE
d-i netcfg/get_domain string localdomain
d-i mirror/country string manual
d-i mirror/http/hostname string http.us.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i mirror/suite string $GUEST_RELEASE
d-i passwd/make-user boolean false
d-i passwd/root-password password password
d-i passwd/root-password-again password password
d-i clock-setup/utc boolean true
d-i time/zone string America/Chicago
d-i clock-setup/ntp boolean true
d-i partman-auto/disk string /dev/sda
d-i partman-auto/method string regular
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman-md/confirm boolean true
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i apt-setup/non-free boolean false
d-i apt-setup/contrib boolean false
d-i pkgsel/include string curl binutils zip jq devscripts
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev string /dev/sda
d-i finish-install/reboot_in_progress note
d-i debian-installer/exit/poweroff boolean true
grub-pc grub2/linux_cmdline_default string
grub-pc grub-pc/timeout string 1
# uncomment this and remove 'passwd -l root' from preseed_postscript.sh
# to enable ssh password login as root for debugging or development
# (false means enable here, yes really)
#openssh-server openssh-server/permit-root-login boolean false
d-i preseed/late_command string \
in-target curl -O tftp://192.168.130.2/preseed_postscript.sh; \
in-target chmod +x preseed_postscript.sh; \
in-target ./preseed_postscript.sh;
EOF
cat > preseed_postscript.sh << EOF
#!/bin/bash
passwd -l root
mkdir /root/.ssh
chmod 0700 /root/.ssh
curl tftp://192.168.130.2/id_ed25519.pub > /root/.ssh/authorized_keys
echo 'debian-$USERSPACE_ARCHITECTURE' > /etc/hostname
echo 'kernel.pid_max=65535' >> /etc/sysctl.d/local.conf
EOF
popd # tftp
# autoinstallation session
qemu-system-"${KERNEL_ARCHITECTURE}" -M virt -m 12288 -cpu cortex-a72 -smp 4 \
-drive if=pflash,media=disk,format=raw,cache=writethrough,file=firmware.img \
-drive if=pflash,media=disk,format=raw,cache=writethrough,file=efivars.img \
-drive if=none,file="${EMULATOR_INSTALL_DIR}"/debian-"${USERSPACE_ARCHITECTURE}".qcow2,format=qcow2,id=hd0 \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-hd,bus=scsi0.0,drive=hd0 \
-netdev user,id=net0,net=192.168.130.0/24,tftp=tftp,bootfile=debian-installer/"${USERSPACE_ARCHITECTURE}"/bootnet"${GRUB2_ARCHITECTURE}".efi \
-device virtio-net-pci,netdev=net0,mac=52:55:00:d1:55:05 \
-nographic
popd # $EMULATOR_INSTALL_DIR
}
__start_qemu-system() {
# daemonization session
qemu-system-"${KERNEL_ARCHITECTURE}" -M virt -m 12288 -cpu cortex-a72 -smp 4 \
-drive if=pflash,media=disk,format=raw,cache=writethrough,file="${EMULATOR_INSTALL_DIR}"/firmware.img \
-drive if=pflash,media=disk,format=raw,cache=writethrough,file="${EMULATOR_INSTALL_DIR}"/efivars.img \
-drive if=none,file="${EMULATOR_INSTALL_DIR}"/debian-"${USERSPACE_ARCHITECTURE}".qcow2,format=qcow2,id=hd0 \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-hd,bus=scsi0.0,drive=hd0,bootindex=1 \
-netdev user,id=net0,net=192.168.130.0/24,hostfwd=tcp::2222-:22 \
-device virtio-net-pci,netdev=net0,mac=52:55:00:d1:55:05 \
-daemonize
}
__run_in_qemu-system() {
ssh -tt -p 2222 -o StrictHostKeyChecking=no -o LogLevel=QUIET root@localhost "$@"
}
__run_in_termux-docker() {
# based on twaik code seen here https://github.com/termux/termux-docker/issues/69
__run_in_qemu-system docker start termux-docker \>/dev/null 2\>\&1 || \
__run_in_qemu-system docker run --detach --init --name termux-docker \
-it termux/termux-docker:"${TERMUX_ARCH}"
__run_in_qemu-system docker exec -itu system termux-docker "$@"
}
__stop_qemu-system() {
__run_in_qemu-system shutdown now
}
# fixes a lot of bugs in termux-docker, preventing annoying things like "Error: None of the mirrors are accessible"
__install_termux-docker_development_branch() {
__run_in_qemu-system git clone -b deblobbify https://github.com/robertkirkman/termux-docker.git
__run_in_qemu-system apt build-dep -y docker.io
__run_in_qemu-system apt source docker.io
__run_in_qemu-system cp termux-docker/custom-docker-with-unrestricted-personality.patch docker.io-\*/debian/patches/
__run_in_qemu-system bash -c \"echo\ 'custom-docker-with-unrestricted-personality.patch'\ \>\>\ docker.io-\*/debian/patches/series\"
__run_in_qemu-system bash -c \"cd\ docker.io-\*/\ \&\&\ DEB_BUILD_OPTIONS=nocheck\ debuild\ -b\ -uc\ -us\"
__run_in_qemu-system rm golang\*
__run_in_qemu-system apt install -y ./\*.deb
__run_in_qemu-system apt-mark hold docker.io
__run_in_qemu-system systemctl enable --now docker
__run_in_qemu-system bash -c \"cd\ termux-docker\ \&\&\ TERMUX_ARCH=$TERMUX_ARCH\ ./generate.sh\"
}
__install_qemu-system
__start_qemu-system
__install_termux-docker_development_branch
__run_in_termux-docker uname -a
__run_in_termux-docker login
__stop_qemu-system
@robertkirkman
Copy link
Author

robertkirkman commented Apr 6, 2025

@horvathcsabalaszlo interesting, i'm not able to reproduce that. The Arch Linux ARM directions are still booting for me when clean installed with a working AARCH64_QEMU_EFI.fd.

The behavior of the EDK2 Shell could be influenced by what specific QEMU_CODE.fd, AKA QEMU_EFI.fd, AKA AARCH64_QEMU_EFI.fd you used in step 7. Each copy of one you can get from different places is very subtly different, and some of them have bugs that others do not.

Could you try this one, like this? This one is working for me.

https://raw.githubusercontent.com/retrage/edk2-nightly/b5e504a31ea2469306a20876e19bbb058afeacb5/bin/RELEASEAARCH64_QEMU_EFI.fd

wget https://raw.githubusercontent.com/retrage/edk2-nightly/b5e504a31ea2469306a20876e19bbb058afeacb5/bin/RELEASEAARCH64_QEMU_EFI.fd
dd if=RELEASEAARCH64_QEMU_EFI.fd of=flash0.img conv=notrunc

Then try running step 8 and step 9 again.

@horvathcsabalaszlo
Copy link

Thanks!
I followed a different guide, but basically the same of your, and the startup.nsh is the same in both. I'll give a try to the .fd you linked, and come back :)

@horvathcsabalaszlo
Copy link

I get this with your .fd file also :)

UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):HD0a0b:;BLK1:
          PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)/HD(1,GPT,2D4D7735-2D4F-4D64-9B36-7DDE99A411D3,0x800,0x64000)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)
     BLK2: Alias(s):
          PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)/HD(2,GPT,95B5CA11-34A9-44F8-95CC-50489FF853E3,0x64800,0x99B000)


Press ESC in 1 seconds to skip startup.nsh or any other key to continue.
Shell> Image root=UUID=02298819-b38e-4a2f-91c8-13a2e1022ea1 rw initrd=\initramfs-linux.img
'Image' is not recognized as an internal or external command, operable program, or script file.


Shell> 


@robertkirkman
Copy link
Author

Are you sure that you are writing this into rootfs/boot/startup.nsh and saving the file at the appropriate part?

image

This line Image root=UUID=02298819-b38e-4a2f-91c8-13a2e1022ea1 rw initrd=\initramfs-linux.img is for startup.nsh, it is not for the Interactive Shell.

@robertkirkman
Copy link
Author

In this case, the file rootfs/boot/Image is the file that is represented by the Image command here, so I believe rootfs/boot/Image must be correctly present and stored in /dev/nbd0p1 in the previous steps, for this to work.

If the Arch Linux steps are too tedious, you can also try the Debian steps (in green paragraphs) which are shorter and have an automated installer, so are easier to do without making mistakes.

@robertkirkman
Copy link
Author

For example, it is important that these two commands in Step 3 were done in this order, and not the other way around, and that they did not have errors:

sudo mount /dev/nbd0p1 rootfs/boot 
sudo bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C rootfs

@horvathcsabalaszlo
Copy link

This was in /rootfs/boot

root@a8host:/naspool/virtualstore/arch_arm# ls /mnt/boot/
bcm2708-rpi-b-plus.dtb	  bcm2710-rpi-zero-2-w.dtb  bcm2835-rpi-cm1-io1.dtb   fixup.dat		   start4.elf
bcm2708-rpi-b-rev1.dtb	  bcm2710-rpi-zero-2.dtb    bcm2835-rpi-zero-w.dtb    fixup4.dat	   start4cd.elf
bcm2708-rpi-b.dtb	  bcm2711-rpi-4-b.dtb	    bcm2835-rpi-zero.dtb      fixup4cd.dat	   start4db.elf
bcm2708-rpi-cm.dtb	  bcm2711-rpi-400.dtb	    bcm2836-rpi-2-b.dtb       fixup4db.dat	   start4x.elf
bcm2708-rpi-zero-w.dtb	  bcm2711-rpi-cm4-io.dtb    bcm2837-rpi-3-a-plus.dtb  fixup4x.dat	   start_cd.elf
bcm2708-rpi-zero.dtb	  bcm2711-rpi-cm4.dtb	    bcm2837-rpi-3-b-plus.dtb  fixup_cd.dat	   start_db.elf
bcm2709-rpi-2-b.dtb	  bcm2711-rpi-cm4s.dtb	    bcm2837-rpi-3-b.dtb       fixup_db.dat	   start_x.elf
bcm2709-rpi-cm2.dtb	  bcm2835-rpi-a-plus.dtb    bcm2837-rpi-cm3-io3.dtb   fixup_x.dat	   startup.nsh
bcm2710-rpi-2-b.dtb	  bcm2835-rpi-a.dtb	    bcm2837-rpi-zero-2-w.dtb  initramfs-linux.img
bcm2710-rpi-3-b-plus.dtb  bcm2835-rpi-b-plus.dtb    bootcode.bin	      kernel7.img
bcm2710-rpi-3-b.dtb	  bcm2835-rpi-b-rev2.dtb    cmdline.txt		      overlays
bcm2710-rpi-cm3.dtb	  bcm2835-rpi-b.dtb	    config.txt		      start.elf
root@a8host:/naspool/virtualstore/arch_arm# 

I copied kernel7.img to Image , because seemed that the Arch didn't used the Image name.

But still drops this :
`UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
FS0: Alias(s):HD0a0b:;BLK1:
PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)/HD(1,GPT,2D4D7735-2D4F-4D64-9B36-7DDE99A411D3,0x800,0x64000)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)
BLK2: Alias(s):
PciRoot(0x0)/Pci(0x2,0x0)/Scsi(0x0,0x0)/HD(2,GPT,95B5CA11-34A9-44F8-95CC-50489FF853E3,0x64800,0x99B000)

Press ESC in 1 seconds to skip startup.nsh or any other key to continue.
Shell> Image root=UUID=02298819-b38e-4a2f-91c8-13a2e1022ea1 rw initrd=\initramfs-linux.img
Script Error Status: Unsupported (line number 1)

Shell>
`

So something really strange is going on here. Luckily it's not urgent to me to have this VM, so i can let this go if you have no time :)

@robertkirkman
Copy link
Author

I copied kernel7.img to Image , because seemed that the Arch didn't used the Image name.

That doesn't look right,
are you sure you used this Arch Linux ARM installer image?

http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz

This is what I see in /boot of my installation, it should look like this:

[tacokoneko@archarm ~]$ ls /boot
dtbs  Image  Image.gz  initramfs-linux-fallback.img  initramfs-linux.img  startup.nsh

If you extract that archive http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz, do you see the same thing as me, or are you trying to use a different version of Arch Linux ARM?

A different version of Arch Linux ARM might have a kernel that is not compatible with this mode of QEMU.

@horvathcsabalaszlo
Copy link

You were right, at first i followed the Qemu Raspberry guide, and it referred a different rootfs package. With your suggestion, it booted (in emergency, but this is another problem).

Thanks for your time :)

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