Alpine Linux on riscv64 BananaPi F3 SBC

2024-12-12

usual disclaimer: no one is responsible for any damage/loss by using this

Also there is IRC channel #alpine-riscv64 on OFTC for discussion about development and help


there is ready made disk images here https://dev.alpinelinux.org/~mps/riscv64/spacemit-mmc.img.xz and tiny-cloud image https://dev.alpinelinux.org/~ncopa/riscv/alpine-bpi-f3-mmc.img.xz

download appropriate image, uncompress with

xz -d spacemit-mmc.img

and

dd if=spacemit-mmc.img of=/dev/sdX

where X is mmc device.

resizing root filesystem (example):
************************************
NOTE: this is not tested deeply, be careful
************************************

localhost:~# lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mmcblk0      179:0    0 29.7G  0 disk
├─mmcblk0p1  179:1    0  124M  0 part /boot
└─mmcblk0p2  179:2    0  464M  0 part /
mmcblk2      179:8    0  7.3G  0 disk
└─mmcblk2p1  179:9    0  7.3G  0 part
mmcblk2boot0 179:16   0    4M  1 disk
mmcblk2boot1 179:24   0    4M  1 disk

and then
parted /dev/mmcblk0 resizepart 2 100%
partx -u /dev/mmcblk0
resize2fs /dev/mmcblk0p2

if the device is not mmcblk0 change it to appropriate one

reboot

script bellow will create same disk image for bananapi f31 but could be tweaked to create different image as needed for particular use cases

script is created with big help of Alpine Linux developer Carlo

size of disk image should be adjusted according needs and parameters for sgdisk to create partitions of the needed sizes

prerequisite on alpine linux:

util-linux or util-linux-misc
e2fsprogs
qemu-riscv64
qemu-openrc
qemu-img
losetup
blkid
sgdisk
wget
tar

start this before running install script
/etc/init.d/qemu-binfmt start
or
rc-service qemu-binfmt start

for other linux distros apk-tool-static could be downloaded from https://dl-cdn.alpinelinux.org/alpine/edge/main/x86_64/ and unpacked with tar

when script finish use dd to write disk inage to mmc card and boot SBC

Script used to create spacemit disk img:

#!/bin/sh

# apk add qemu-img qemu-openrc losetup blkid parted e2fsprogs wget tar
set -eu

: "${DISK:=spacemit-mmc.img}"
: "${DISKSIZE:=600M}"

readonly SCRIPT="${0##*/}"
readonly TMPDIR="$(mktemp -dt "${SCRIPT%.*}".XXXXXX)"
readonly APK_KEY="alpine-devel@lists.alpinelinux.org-60ac2099.rsa.pub"
readonly MIRROR="https://dl-cdn.alpinelinux.org/alpine"
readonly LOOPDEV="$(losetup --find)"
readonly BOOTDEV="$LOOPDEV"p1
readonly ROOTDEV="$LOOPDEV"p2

cleanup() {
	set +e
	mountpoint -q "$TMPDIR"/boot && umount "$TMPDIR"/boot
	mountpoint -q "$TMPDIR" && umount "$TMPDIR"
	losetup --detach-all
	rm -rf "$TMPDIR"
}

trap cleanup EXIT INT

rm -f $DISK
truncate -s $DISKSIZE $DISK

echo "Paritioning disk"
parted -s "$DISK" mktable msdos > /dev/null
parted -s "$DISK" unit s -- mkpart primary ext4 8192 128MiB > /dev/null
parted -s "$DISK" -- mkpart primary ext4 136MiB 100% > /dev/null

echo "Creating dirs and mounting"
losetup -P "$LOOPDEV" "$DISK"
mkfs.ext4 -qL mmc.bfs "$BOOTDEV"
mkfs.ext4 -qL mmc.rfs "$ROOTDEV"
mount -t ext4 "$ROOTDEV" "$TMPDIR"
mkdir -p "$TMPDIR"/boot
mkdir -p "$TMPDIR"/etc/apk/keys
mount -t ext4 "$BOOTDEV" "$TMPDIR"/boot

echo "Setup apk keys and repositories"
wget -qP "$TMPDIR"/etc/apk/keys https://alpinelinux.org/keys/"$APK_KEY"
printf "$MIRROR/edge/%s\n" main community testing > "$TMPDIR"/etc/apk/repositories

echo "installing base packages"
apk --allow-untrusted --root "$TMPDIR" --arch riscv64 --initdb add \
	alpine-base alpine-baselayout alpine-conf kmod openrc \
  dbus util-linux blkid chrony \
	sysfsutils ssl_client ca-certificates-bundle alpine-keys \
	ethtool f2fs-tools e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper \
	iw iwd installkernel linux-firmware-none parted \
	agetty openresolv tar tzdata openssh wget mkinitfs \
	linux-spacemit opensbi-spacemit u-boot-spacemit


echo "flashing boot loader"
dd if="$TMPDIR/"usr/share/u-boot-spacemit/bootinfo_emmc.bin of=${LOOPDEV} bs=512 conv=notrunc
dd if="$TMPDIR/"usr/share/u-boot-spacemit/FSBL.bin of=${LOOPDEV} bs=512 seek=1 conv=notrunc
dd if="$TMPDIR/"usr/share/u-boot-spacemit/FSBL.bin of=${LOOPDEV} bs=512 seek=512 conv=notrunc
dd if="$TMPDIR/"usr/share/opensbi-spacemit/fw_dynamic.itb of=${LOOPDEV} bs=512 seek=1280 conv=notrunc
dd if="$TMPDIR/"usr/share/u-boot-spacemit/u-boot.itb of=${LOOPDEV} bs=512 seek=2048 conv=notrunc

echo "Setting up services"
for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \
	shutdown/mount-ro shutdown/killprocs \
	default/dbus default/chronyd default/local; do
	ln -s /etc/init.d/"${rc##*/}" "$TMPDIR"/etc/runlevels/"$rc"
done

echo "setting basics for libudev-zero/mdev"
echo 'SUBSYSTEM=drm;.*   root:video 660 */usr/libexec/libudev-zero-helper' >>  $TMPDIR/etc/mdev.conf
echo 'SUBSYSTEM=input;.* root:input 660 */usr/libexec/libudev-zero-helper' >>  $TMPDIR/etc/mdev.conf
echo "LABEL=mmc.bfs	/boot	ext4	auto" >> $TMPDIR/etc/fstab

echo "Settting boot loader"
bootuuid=$(blkid -s UUID -o value $BOOTDEV)
rootuuid=$(blkid -s UUID -o value $ROOTDEV)

mkdir -p "$TMPDIR"/boot/extlinux
cat <<EOF > "$TMPDIR"/boot/extlinux/extlinux.conf
menu title Alpine Spacemit
timeout 50
default bpi-f3

label lpi3a
	menu label Alpine lpi3a
	kernel /vmlinuz-spacemit
	initrd /initramfs-spacemit
	fdt /dtbs-spacemit/spacemit/k1-x_lpi3a.dtb
	append earlycon=sbi rw root=UUID=$rootuuid rootfstype=ext4 rootwait console=ttyS0,115200 console=tty0 clk_ignore_unused swiotlb=65536

label bpi-f3
	menu label Alpine bpi-f3
	kernel /vmlinuz-spacemit
	initrd /initramfs-spacemit
	fdt /dtbs-spacemit/spacemit/k1-bananapi-f3.dtb
	append earlycon=sbi rw root=UUID=$rootuuid rootfstype=ext4 rootwait console=ttyS0,115200 console=tty0 clk_ignore_unused swiotlb=65536

EOF

echo "Setting up inittab"
sed -i 's/^tty1.*/tty1::respawn:\/sbin\/agetty -L 115200 tty1 linux --login-pause --autologin root --noclear/' $TMPDIR/etc/inittab
sed -i 's/^#ttyS0/ttyS0/' $TMPDIR/etc/inittab
sed -i 's/^ttyS0.*/ttyS0::respawn:\/sbin\/agetty -L 115200 ttyS0 linux --login-pause --autologin root --noclear/' $TMPDIR/etc/inittab

echo "Finished, cleaning up"