Linux kernel cross compilation
Cross-compiling the Linux kernel has been documented of course, and make.cross exists to help with that. But we wanted to boot the kernel via Qemu later on and that's when things got tricky. On a Fedora x86_64 system:
$ sudo dnf install gcc-sparc64-linux-gnu qemu-system-sparc $ export CCACHE_DIR=/var/tmp/ccache DIR=/var/tmp/linux_sparc $ cd /usr/local/src/linux $ mkdir ${CCACHE_DIR} ${DIR} $ make O=${DIR} ARCH=sparc64 CROSS_COMPILE="ccache sparc64-linux-gnu-" defconfig $ make -j8 O=${DIR} ARCH=sparc64 CROSS_COMPILE="ccache sparc64-linux-gnu-" zImage
Once completed, we should have Sparc64 kernels in ${DIR}/arch/sparc/boot
:
$ ls -hgo ${DIR}/arch/sparc/boot/ total 22M -rwxr-x---. 1 17M Feb 14 18:03 image -rw-r-----. 1 4.5M Feb 14 18:03 zImage
Booting via qemu
makes more sense with a small initrd and we needed a working BusyBox installation as well. But Fedora no longer ships SPARC binaries, and due to missing header files we were unable to cross-compile BusyBox on Fedora. A Debian VM was able to help here:
$ sudo apt-get install gcc-sparc64-linux-gnu libc6-dev-sparc64-cross $ git clone git://busybox.net/busybox.git $ cd busybox $ LDFLAGS="--static" make O=${DIR} ARCH=sparc64 CROSS_COMPILE="sparc64-linux-gnu-" defconfig $ LDFLAGS="--static" make -j8 O=${DIR} ARCH=sparc64 CROSS_COMPILE="sparc64-linux-gnu-" $ file -L ./busybox ./busybox: ELF 64-bit MSB executable, SPARC V9, Sun UltraSPARC1 Extensions Required, relaxed memory ordering [...]
Transfer that busybox
binary to the Fedora machine and we can now construct our initrd
:
$ cat /var/tmp/m.sh #!/bin/bash -e outfile=/var/tmp/initrd.cpio cd $(mktemp -d) echo "Preparing initrd in $(pwd)..." mkdir {bin,dev,mnt,proc,sys} cat > init << EOF #!/bin/sh mount -t devtmpfs none /dev mount -t proc none /proc mount -t sysfs none /sys echo echo Mounting... mount /dev/sda /mnt -t ext4 # Adjust as needed exec /bin/sh EOF chmod +x init cp /var/tmp/busybox.sparc64 bin/busybox $(pwd)/bin/busybox --install bin find . | cpio -o -H newc > ${outfile} echo "Written to ${outfile}."
Create a small root disk and the initrd
:
$ dd if=/dev/zero of=/var/tmp/ext4.img bs=1M count=512 $ mkfs.ext4 /var/tmp/ext4.img $ sh /var/tmp/m.sh Preparing initrd in /run/user/1000/tmp.ZLodtsGu72... 4488 blocks Written to /var/tmp/initrd.cpio.
Now we are finally read to start the new kernel in qemu
:
$ qemu-system-sparc64 -kernel ${DIR}/arch/sparc/boot/image -initrd /var/tmp/initrd.cpio \ -m 512M -drive file=/var/tmp/ext4.img,format=raw -nographic OpenBIOS for Sparc64 Configuration device id QEMU version 1 machine id 0 kernel phys 404000 virt 40004000 size 0x12d5870 initrd phys 16d6000 virt 40c00000 size 0x231000 kernel cmdline CPUs: 1 x SUNW,UltraSPARC-IIi UUID: 00000000-0000-0000-0000-000000000000 Welcome to OpenBIOS v1.1 built on Jul 22 2022 02:10 Type 'help' for detailed information [sparc64] Kernel already loaded [ 0.000878] PROMLIB: Sun IEEE Boot Prom 'OBP 3.10.24 1999/01/01 01:01' [ 0.002626] PROMLIB: Root node compatible: sun4u [ 0.003236] Linux version 6.2.0-rc8 sparc64-linux-gnu-gcc (GCC) 12.2.1 20220819 [ 0.009692] printk: bootconsole [earlyprom0] enabled [ 0.018163] ARCH: SUN4U [...] ~ # uname -a; df -h Linux (none) 6.2.0-rc8 #1 SMP Tue Feb 14 18:02:02 CET 2023 sparc64 GNU/Linux Filesystem Size Used Available Use% Mounted on none 240.1M 0 240.1M 0% /dev /dev/sda 487.2M 24.0K 451.3M 0% /mnt
And with that, we do have a running Sparc machine.