In my post on Debian S390X Emulation [1] I mentioned having problems booting a Debian PPC64EL kernel under QEMU. Giovanni commented that they had PPC64EL working and gave a link to their site with Debian QEMU images for various architectures [2]. I tried their image which worked then tried mine again which also worked – it seemed that a recent update in Debian/Unstable fixed the bug that made QEMU not work with the PPC64EL kernel.
Here are the instructions on how to do it.
First you need to create a filesystem in an an image file with commands like the following:
truncate -s 4g /vmstore/ppc mkfs.ext4 /vmstore/ppc mount -o loop /vmstore/ppc /mnt/tmp
Then visit the Debian Netinst page [3] to download the PPC64EL net install ISO. Then loopback mount it somewhere convenient like /mnt/tmp2.
The package qemu-system-ppc has the program for emulating a PPC64LE system, the qemu-user-static package has the program for emulating PPC64LE for a single program (IE a statically linked program or a chroot environment), you need this to run debootstrap. The following commands should be most of what you need.
apt install qemu-system-ppc qemu-user-static update-binfmts --display # qemu ppc64 needs exec stack to solve "Could not allocate dynamic translator buffer" # so enable that on SE Linux systems setsebool -P allow_execstack 1 debootstrap --foreign --arch=ppc64el --no-check-gpg buster /mnt/tmp file:///mnt/tmp2 chroot /mnt/tmp /debootstrap/debootstrap --second-stage cat << END > /mnt/tmp/etc/apt/sources.list deb http://mirror.internode.on.net/pub/debian/ buster main deb http://security.debian.org/ buster/updates main END echo "APT::Install-Recommends False;" > /mnt/tmp/etc/apt/apt.conf echo ppc64 > /mnt/tmp/etc/hostname # /usr/bin/awk: error while loading shared libraries: cannot restore segment prot after reloc: Permission denied # only needed for chroot setsebool allow_execmod 1 chroot /mnt/tmp apt update # why aren't they in the default install? chroot /mnt/tmp apt install perl dialog chroot /mnt/tmp apt dist-upgrade chroot /mnt/tmp apt install bash-completion locales man-db openssh-server build-essential systemd-sysv ifupdown vim ca-certificates gnupg # install kernel last because systemd install rebuilds initrd chroot /mnt/tmp apt install linux-image-ppc64el chroot /mnt/tmp dpkg-reconfigure locales chroot /mnt/tmp passwd cat << END > /mnt/tmp/etc/fstab /dev/vda / ext4 noatime 0 0 #/dev/vdb none swap defaults 0 0 END mkdir /mnt/tmp/root/.ssh chmod 700 /mnt/tmp/root/.ssh cp ~/.ssh/id_rsa.pub /mnt/tmp/root/.ssh/authorized_keys chmod 600 /mnt/tmp/root/.ssh/authorized_keys rm /mnt/tmp/vmlinux* /mnt/tmp/initrd* mkdir /boot/ppc64 cp /mnt/tmp/boot/[vi]* /boot/ppc64 # clean up umount /mnt/tmp umount /mnt/tmp2 # setcap binary for starting bridged networking setcap cap_net_admin+ep /usr/lib/qemu/qemu-bridge-helper # afterwards set the access on /etc/qemu/bridge.conf so it can only # be read by the user/group permitted to start qemu/kvm echo "allow all" > /etc/qemu/bridge.conf
Here is an example script for starting kvm. It can be run by any user that can read /etc/qemu/bridge.conf.
#!/bin/bash set -e KERN="kernel /boot/ppc64/vmlinux-4.19.0-9-powerpc64le -initrd /boot/ppc64/initrd.img-4.19.0-9-powerpc64le" # single network device, can have multiple NET="-device e1000,netdev=net0,mac=02:02:00:00:01:04 -netdev tap,id=net0,helper=/usr/lib/qemu/qemu-bridge-helper" # random number generator for fast start of sshd etc RNG="-object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0" # I have lockdown because it does no harm now and is good for future kernels # I enable SE Linux everywhere KERNCMD="net.ifnames=0 noresume security=selinux root=/dev/vda ro lockdown=confidentiality" kvm -drive format=raw,file=/vmstore/ppc64,if=virtio $RNG -nographic -m 1024 -smp 2 $KERN -curses -append "$KERNCMD" $NET