These are the steps to create the dual boot setup, based on Miki Shapiros ansible scripts. Some pieces are borrowed from the Nintendo Switch Fed32 setup. The generic raspi4 notes are here.
Outline:
# Our directory for storing images etc. WORKDIR="/home/chris/Downloads/raspi" # Our microsd-card device OUTDEV="/dev/mmcblk0" mkdir -p $WORKDIR/mnt/fedora32/root $WORKDIR/mnt/raspios \ $WORKDIR/mnt/piroot $WORKDIR/mnt/boot cd $WORKDIR curl http://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2020-05-28/2020-05-27-raspios-buster-lite-armhf.zip unzip 2020-05-27-raspios-buster-lite-armhf.zip dd bs=4M if=2020-05-27-raspios-buster-lite-armhf.img of=$OUTDEV conv=fsync mount ${OUTDEV}p1 $WORKDIR/mnt/boot touch $WORKDIR/mnt/boot/SSH umount $WORKDIR/mnt/boot # Now boot the Raspi4 from the sdcard, and # find out the IP which was assigned via DHCP nmap -sP 192.168.0.0/24 # ssh <ip> / user pi / password raspberry # Become root sudo su - ### Firmware update apt update apt upgrade apt install rpi-eeprom rpi-eeprom-update ### Activate the 64bit kernel echo 'arm_64bit=1' >>/boot/config.txt poweroff
Then poweroff the raspi, and put the sdcard into a different system, here Fedora 32 x86_64, and continue with the following steps.
### Fetch and prepare Fedora cd $WORKDIR curl http://ftp.riken.jp/Linux/fedora/releases/32/Server/aarch64/images/Fedora-Server-32-1.6.aarch64.raw.xz xz -dk Fedora-Server-32-1.6.aarch64.raw.xz kpartx -av Fedora-Server-32-1.6.aarch64.raw # This created /dev/mapper/loopXp1 (vfat part) and /dev/mapper/loopXp2 (ext4 partition) vgchange -ay fedora mount /dev/fedora/root $WORKDIR/mnt/fedora32/root ### Shrink the RaspiOS partition, create one for Fedora e2fsck -f /dev/mmcblk0p2 resize2fs /dev/mmcblk0p2 3G parted /dev/mmcblk0 resizepart 2 4G parted /dev/mmcblk0 mkpart primary ext4 4000MB 100% resize2fs /dev/mmcblk0p2 ### copy over the Fedora root filesystem mkfs.ext4 ${OUTDEV}p3 mount ${OUTDEV}p3 $WORKDIR/mnt/piroot cd $WORKDIR/mnt/fedora32/root tar cfp - . | ( cd $WORKDIR/mnt/piroot; tar xfp - ) ### copy over RaspiOS kernel modules, firmware, modprobe blacklist mount ${OUTDEV}p2 $WORKDIR/mnt/raspios cp -urfp $WORKDIR/mnt/raspios/lib/modules $WORKDIR/mnt/piroot/usr/lib cp -urfp $WORKDIR/mnt/raspios/lib/firmware $WORKDIR/mnt/piroot/root/lib cp -urfp $WORKDIR/mnt/raspios/etc/modprobe.d/. $WORKDIR/mnt/piroot/etc/modprobe.d/ umount $WORKDIR/mnt/raspios ### Prepare new image cd $WORKDIR/mnt/piroot # set your root-password to 'fedora' sed -ie 's,^root.*,root:$6$g1sdJY/CulQKzQmS$heAUJV60eTr1HQtTTR188WlA/vOTj6LPuKA7JB1wKEgPiW1qX2gPJHU8lLhSL8KeKgx.hGgUvQ4uzW6JQ68u40:18388:0:99999:7:::,' etc/shadow # As an alternative, execute 'vi etc/shadow' and manually # change the password hash to something else. echo 'PermitRootLogin yes' >>etc/ssh/sshd_config echo pi4.local >etc/hostname echo '127.0.0.1 pi4.local pi4' >>etc/hosts # We just need these 2 lines echo '/dev/mmcblk0p1 /boot vfat defaults,noatime 0 0' >etc/fstab echo '/dev/mmcblk0p3 / ext4 defaults,noatime 0 0' >>etc/fstab cat >etc/sysconfig/network-scripts/ifcfg-eth0<<EOT TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy IPADDR=192.168.0.4 PREFIX=24 GATEWAY=192.168.0.1 DNS1=8.8.8.8 NAME=eth0 DEVICE=eth0 ONBOOT=yes AUTOCONNECT_PRIORITY=-999 EOT # Disable the initial-setup and other unneeded services rm -f etc/systemd/system/multi-user.target.wants/initial-setup.service rm -f etc/systemd/system/multi-user.target.wants/abrtd.service rm -f etc/systemd/system/multi-user.target.wants/abrt-journal-core.service rm -f etc/systemd/system/multi-user.target.wants/abrt-oops.service rm -f etc/systemd/system/multi-user.target.wants/abrt-vmcore.service rm -f etc/systemd/system/multi-user.target.wants/abrt-xorg.service rm -f etc/systemd/system/multi-user.target.wants/cups.service rm -f etc/systemd/system/multi-user.target.wants/nfs-client.service rm -f etc/systemd/system/multi-user.target.wants/vboxservice.service rm -f etc/systemd/system/multi-user.target.wants/vmtoolsd.service rm -f etc/systemd/system/multi-user.target.wants/ModemManager.service rm -f etc/systemd/system/multi-user.target.wants/rngd.service rm -f etc/systemd/system/multi-user.target.wants/avahi-daemon.service rm -f etc/systemd/system/multi-user.target.wants/auditd.service rm -f etc/systemd/system/multi-user.target.wants/smartd.service rm -f etc/systemd/system/multi-user.target.wants/libvirtd.service rm -f etc/systemd/system/multi-user.target.wants/remote-fs.service rm -f etc/systemd/system/sysinit.target.wants/multipathd.service rm -f etc/systemd/system/sockets.target.wants/multipathd.socket cd .. ### prepare boot partition mount ${OUTDEV}p1 $WORKDIR/mnt/boot vi $WORKDIR/mnt/boot/cmdline.txt # change 'root=PARTUUID=738a4d67-02' # into 'root=PARTUUID=738a4d67-03' (3rd partition to be booted) # and if there are parameters after "rootwait", remove them. # example: # console=serial0,115200 console=tty1 root=PARTUUID=738a4d67-03 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait chmod 0755 $WORKDIR/mnt/piroot umount $WORKDIR/mnt/boot umount $WORKDIR/mnt/piroot umount $WORKDIR/mnt/fedora32/root lvchange -a n fedora kpartx -dv $WORKDIR/Fedora-Server-32-1.6.aarch64.raw
You should now be able to boot the Pi4 with the sdcard into Fedora, and login via ssh.
cat >>~/.bashrc<<EOT # extend prompt to have temperature export PS1='[\u@\h \$(cut -b 1,2 /sys/devices/virtual/thermal/thermal_zone0/temp)°C \W]\$ ' # colored iostat output export S_COLORS=always EOT ### tuning cat >/etc/rc.local<<EOT #!/usr/bin/bash # VM writeback timeout echo '1500' > '/proc/sys/vm/dirty_writeback_centisecs' # power saving for wlan and usb chips echo 'auto' > '/sys/bus/pci/devices/0000:01:00.0/power/control' echo 'auto' > '/sys/bus/pci/devices/0000:00:00.0/power/control' EOT chmod +x /etc/rc.local /etc/rc.local ln -s /etc/rc.local /etc/rc.d/rc.local # To get further ideas about services we do not need systemd-analyze plot >file.svg # For my use cases: systemctl disable lmsensors firewalld # I like gkrellm dnf -y install gkrellm-daemon sysstat htop echo 'allow-host 192.168.0.2' >>/etc/gkrellmd.conf systemctl enable --now gkrellmd # update dnf -y update