Installing Alpine Linux on OrangePi RV2: Difference between revisions

From Alpine Linux
mNo edit summary
mNo edit summary
 
(9 intermediate revisions by the same user not shown)
Line 2: Line 2:
[[Main Page]] > [[:Category:Architectures|Architectures]] > [[Riscv64]] > Installing Alpine Linux on OrangePi RV2
[[Main Page]] > [[:Category:Architectures|Architectures]] > [[Riscv64]] > Installing Alpine Linux on OrangePi RV2
<br /><br />
<br /><br />
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guide.  This article is provided as a general reference.  It is assumed that the implementer will have the knowledge and ability to close the gap between what is described here and their specific setup.}}
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guide.  This article is provided as a general reference.  It is assumed that the implementer will have the knowledge and ability to close the gap between what is described here and their specific setup.
<br/><br/>Implementers of this guide should consider the result development / alpha quality.}}


The [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-RV2.html OrangePi RV2] is a credit-card sized development board with a Ky X1 8-Core SoC.  The Ky X1 is for all intents and purposes a SpacemiT K1 SoC.  The remainder of this guide is more likely to use the terms SpacemiT or K1 as is prevalent throughout the Linux community.  Please understand that these terms all refer to the same RISC-V ISA implementation.
The [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-RV2.html OrangePi RV2] is a credit-card sized development board with a Ky X1 8-Core SoC.  The Ky X1 is for all intents and purposes a SpacemiT K1 SoC.  The remainder of this guide is more likely to use the terms SpacemiT or K1 as is prevalent throughout the Linux community.  Please understand that these terms all refer to the same RISC-V ISA implementation.
Line 23: Line 24:


== Kernel and Firmware ==
== Kernel and Firmware ==
There are a few different options for kernels.  The extent of coverage documented here is largely due to my initial ignorance.  I have found a few sources for mostly workable kernels.  None of them works 100%.  SpacemiT is still in the process upstreaming functionality.  
There are a few different options for kernels.  The extent of coverage documented here is largely due to my initial ignorance.  I have found a few sources for mostly workable kernels.  None of them works 100%.  SpacemiT is still in the process upstreaming functionality.
 
=== Obtaining the ESOS firmware ===
=== Obtaining the ESOS firmware ===
The processor being used on the RV2 requires a firmware to function properly.  This file is available from the vendor images, in third party distributions and in the [https://github.com/orangepi-xunlong/orangepi-build orangepi-xunlong/orangepi-build] GitHub repository.  The subdirectory containing the required file is [https://github.com/orangepi-xunlong/orangepi-build/tree/next/external/packages/bsp/ky/usr/lib/firmware external/packages/bsp/ky/usr/lib/firmware].  Download the file <code>esos.elf</code>.  Keep the download in a safe place and also <code>/lib/firmware</code>.  The <code>/lib/firmware</code> directory is also where you'll find this file within the vendor's image or an initrd image.
The processor being used on the RV2 requires a firmware to function properly.  This file is available from the vendor images, in third party distributions and in the [https://github.com/orangepi-xunlong/orangepi-build orangepi-xunlong/orangepi-build] GitHub repository.  The subdirectory containing the required file is [https://github.com/orangepi-xunlong/orangepi-build/tree/next/external/packages/bsp/ky/usr/lib/firmware external/packages/bsp/ky/usr/lib/firmware].  Download the file <code>esos.elf</code>.  Keep the download in a safe place and also <code>/lib/firmware</code>.  The <code>/lib/firmware</code> directory is also where you'll find this file within the vendor's image or an initrd image.
{{Note|
{{Note|
Changes to mkinitfs will be needed in order for this firmware to be included.  More information on that will be provided further down the document}}
Changes to mkinitfs will be needed in order for this firmware to be included.  More information on that will be provided further down the document}}
=== Why not the Alpine Kernel? ===
The kernels available from the Alpine Linux Project won't completely boot.  U-Boot is able to load and run the kernel.  The kernel is able to unpack the initramfs image and start the init process.  The kernel panics though because the init process fails to mount a root filesystem.  The init process is unable to mount a root filesystem because the kernel doesn't have the capability to load the esos.elf firmware.  This capability is provided by the remoteproc driver.  My experience with the RV2 so far shown that loading this firmware is required for enabling the full function of the K1/X1 SoC.
=== Obtaining the Vendor kernel ===
=== Obtaining the Vendor kernel ===
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.
Line 57: Line 62:
doas umount /mnt
doas umount /mnt
doas losetup -d /dev/loop0</pre>
doas losetup -d /dev/loop0</pre>
=== Will Alpine's kernel work? (TBD) ===
{{Note|
Need to revisit this}}
=== Building from source ===
=== Building from source ===
There have been 2 main repositories for patched kernel sources.
There have been 2 main repositories for patched kernel sources.
Line 198: Line 200:


== Install Alpine from an non-Alpine RISC-V Linux host ==
== Install Alpine from an non-Alpine RISC-V Linux host ==
This section is mainly intended for those trying to install Alpine from one of the vendor images or another RISCV64 install.  The apk utility does need to be able to run post-build scripts in order for target installation to function properly.


=== Download a minirootfs to run apk within a chroot ===
=== Download a minirootfs to run apk within a chroot ===
Line 253: Line 256:
All of the effort up to this point has come down to this.  This portion of the guide will assume the kernel being installed is version 6.6.63-ky from the vendor.
All of the effort up to this point has come down to this.  This portion of the guide will assume the kernel being installed is version 6.6.63-ky from the vendor.
=== Install the kernel ===
=== Install the kernel ===
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.
<pre>cd /mnt
tar xzf /var/tmp/linux-6.6.63-ky.tgz</pre>
=== Install the esos.elf firmware ===
=== Install the esos.elf firmware ===
Copy esos.elf from your very safe place to /mnt/lib/firmware
<pre>doas cp ~/Downloads/esos.elf /mnt/lib/firmware/</pre>
=== Creating the initrd image ===
=== Creating the initrd image ===
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We'll be using <code>mkinitfs</code> to do this.  There are a few modifications we need to make in order for this process to generate an image with all the required bits.
==== Configuring and fixing mkinitfs ====
==== Configuring and fixing mkinitfs ====
===== Add esos.elf to mkinitfs/features.d/base.files =====
===== Add esos.elf to mkinitfs/features.d/base.files =====
Line 260: Line 269:
===== Add the wireless-regdb database files to base.files =====
===== Add the wireless-regdb database files to base.files =====
{{Note|
{{Note|
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it.  Requires install of wireless-regdb apk package.}}
<pre>echo "/lib/firmware/regulatory.*" >> /etc/mkinitfs/features.d/base.files</pre>
<pre>echo "/lib/firmware/regulatory.*" >> /etc/mkinitfs/features.d/base.files</pre>
===== Add jdb2 to ext4 =====
 
The ext4 module depends on the jdb2 module for filesystem journaling.  The Alpine kernel does not have ext4 or jbd2 as kernel builtins.  If you're using the Alpine provided kernel then you'll need this on the initramfs.
<pre>echo "kernel/fs/jbd2" >> /etc/mkinitfs/features.d/ext4.modules</pre>
===== Prevent mkinitfs from deleting needed firmware =====
===== Prevent mkinitfs from deleting needed firmware =====
The mkinitfs script will delete a directory that shouldn't exist.  The files assembled from the features.d includes will have already been staged prior to mkinitfs assembling firmware needed by included modules.  We need this not to happen and below is the simplest workaround I could pull together.
The mkinitfs script will delete a directory that shouldn't exist.  The files assembled from the features.d includes will have already been staged prior to mkinitfs assembling firmware needed by included modules.  We need this not to happen and below is the simplest workaround I could pull together.
Line 277: Line 284:


==== Using mkinitfs-rv2 to create an initrd image ====
==== Using mkinitfs-rv2 to create an initrd image ====
Installing from an Alpine host
<pre>mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky</pre>
Installing within a chroot
<pre>mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky</pre>
=== Configure extlinux ===
=== Configure extlinux ===
Create an extlinux.conf file with the following
<pre>default l0
menu title Alpine U-Boot menu
prompt 1
timeout 10
label l0
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)
    linux /vmlinuz-6.6.63-ky
    initrd /initramfs-6.6.63-ky
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb
    append mtdparts=d420c000.spi-0:64K@0(bootinfo),64K@64K(private),256K@128K(fsbl),64K@384K(env),192K@448K(opensbi),-@640K(uboot) root=UUID=236a5824-0390-42dc-83e3-f02123188f96 console=ttyS0,115200 console=tty1 rootwait rw rootfstype=ext4 earlycon=sbi</pre>
==== A few notes on extlinux.conf ====
* Most device trees are generated in a dtbs/[kernel-version] directory.
* The vendor vmlinuz is a decompressed kernel image, though it shouldn't matter
* The mtdparts kernel parameter isn't absolutely required
* Only the right-most console statement seems to get attention.  If you're on UART then you'll want <code>console=ttyS0,115200</code> and if you're on the framebuffer you'll want <code>console=tty1</code>.
== Wrapping Up ==
At this point the primary setup is complete.  You may want to add some additional packages or configuration but can also be done after booting the RV2 board.
I may have forgotton something(s) which you'll soon discoven.  I'll do my best to fold in corrections as I find they're needed or as new information becomes available.
=== Unmount the buildroot ===


<pre>umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt</pre>


== Basic usability options ==
== Usability extras ==


The above should get your OrangePi RV2 booting Alpine Linux.  Below are some additional configurations to help make growing your install a little easier.  The following assumes you're still chroot /mnt or have booted the system.
The above should get your OrangePi RV2 booting Alpine Linux.  Below are some additional configurations to help make growing your install a little easier.  The following assumes you're still chroot /mnt or have booted the system.

Latest revision as of 21:33, 15 April 2026

This material is work-in-progress ...

Do not follow instructions here until this notice is removed.
(Last edited by Aarch0x40 on 15 Apr 2026.)

Main Page > Architectures > Riscv64 > Installing Alpine Linux on OrangePi RV2

Warning: The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guide. This article is provided as a general reference. It is assumed that the implementer will have the knowledge and ability to close the gap between what is described here and their specific setup.

Implementers of this guide should consider the result development / alpha quality.


The OrangePi RV2 is a credit-card sized development board with a Ky X1 8-Core SoC. The Ky X1 is for all intents and purposes a SpacemiT K1 SoC. The remainder of this guide is more likely to use the terms SpacemiT or K1 as is prevalent throughout the Linux community. Please understand that these terms all refer to the same RISC-V ISA implementation.

This guide assumes that the manufacturer provided OpenSBI and U-Boot binaries have been applied to the SPI Flash device. This stock bootloader will look for an extlinux/extlinux.conf which will be used to configure the boot process.

Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.

This guide borrows heavily from the article install Alpine Linux riscv64 under qemu with u-boot loader by Milan P. Stanić and posted to Riscv64 by User:AnIDFB.

Known issues


Warning: The following are the issues that are known to exist between the result of this guide and the manufacturer provided image


  • Wireless (Wi-Fi & Bluetooth) is not functional
  • Some kernel sources have an issue with starting the framebuffer
  • Manufacturer tools are not included

This guide was assembled as a dumping of my personal notes. It's being updated as I come across new information. Alpine does run on the RV2 albeit not directly out of the box. Will do my best to reference external materials so that this article may provide some insight to others while still under development. The above may not be the only issues but hopefully there's enough information here to get you going.

Kernel and Firmware

There are a few different options for kernels. The extent of coverage documented here is largely due to my initial ignorance. I have found a few sources for mostly workable kernels. None of them works 100%. SpacemiT is still in the process upstreaming functionality.

Obtaining the ESOS firmware

The processor being used on the RV2 requires a firmware to function properly. This file is available from the vendor images, in third party distributions and in the orangepi-xunlong/orangepi-build GitHub repository. The subdirectory containing the required file is external/packages/bsp/ky/usr/lib/firmware. Download the file esos.elf. Keep the download in a safe place and also /lib/firmware. The /lib/firmware directory is also where you'll find this file within the vendor's image or an initrd image.

Note: Changes to mkinitfs will be needed in order for this firmware to be included. More information on that will be provided further down the document

Why not the Alpine Kernel?

The kernels available from the Alpine Linux Project won't completely boot. U-Boot is able to load and run the kernel. The kernel is able to unpack the initramfs image and start the init process. The kernel panics though because the init process fails to mount a root filesystem. The init process is unable to mount a root filesystem because the kernel doesn't have the capability to load the esos.elf firmware. This capability is provided by the remoteproc driver. My experience with the RV2 so far shown that loading this firmware is required for enabling the full function of the K1/X1 SoC.

Obtaining the Vendor kernel

Open a browser to the OrangePI RV2 Download page.

Click on the "Downloads" button for the Ubuntu Image. This will take you to a Google Drive folder. Download the Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z.

Decompress this file after downloading using your favorite archive utility. It will expand to a directory containing Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img and shasum file.

Attach the image to a loop device and mount the root partition.

# Find the first available loop device
doas losetup --find

# Assuming the first found available device is /dev/loop0
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img

# Mount the root slice
doas mount /dev/loop0p1 /mnt

Archive the vendor kernel

cd /mnt
tar czf /var/tmp/linux-6.6.63-ky.tgz boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky boot/dtb-6.6.63-ky lib/modules/6.6.63-ky
Note: You probably want to put the resulting archive in a safer place than /var/tmp at this point. There's a bit to do before we'll need it.

Unmount and detach the vendor image

cd -
doas umount /mnt
doas losetup -d /dev/loop0

Building from source

There have been 2 main repositories for patched kernel sources.

The linux-spacemit repository is used by RedHat employee Jason Montleon in building out their RISCV64 support. The linux-bredos repository is used by the BredOS project which supports the RV2 and has provides downloadable images for the board. There is cross contribution between these two repositories. A lot of what I've learned to assemble this guide is attributed to these projects.

Setting up a workspace

Begin by setting up a RISC-V workspace by following Running Alpine riscv64 in QEMU. You'll need to establish a build environment in this QEMU guest.

doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev
Note: ncurses and ncurses-dev aren't a hard requirements but are useful if you want to run make menuconfig

Cloning the source, configuring and building the kernel

Note: This is needs a redo.

Preparing the media

Partition and setup the filesystems

Install parted package

doas apk add parted

Insert, partition and format the boot media

The media can be either an SD card or USB drive. An 2280 PCIe NVMe is also possibly if you have the ability to write it from the host setting up the media. For the purposes of this guide we will refer to our boot media as /dev/sdb. The following section requires a root shell.

alias p="parted -sa optimal /dev/sdb"
p mklabel gpt
p mkpart boot ext4 0G 512M
p set 1 boot
p mkpart root ext4 512M 100%
p p

The final command should produce output to confirm the result of the executed commands. It should look something like the following.

Model: Generic STORAGE DEVICE (scsi)
Disk /dev/sdb: 15.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name  Flags
 1      1049kB  512MB   511MB   ext4         boot  boot, esp
 2      512MB   15.5GB  15.0GB               root

If all looks good, then we can proceed with formatting the partitions

mkfs.ext4 /dev/sdb1 && mkfs.ext4 /dev/sdb2

Mount the filesystems and lay some preliminary groundwork.

# Mount the target root slice
mount /dev/sdb2 /mnt

# Create mount point for boot slice
[ ! -d /mnt/boot ] && mkdir -vp /mnt/boot

# Mount boot slice
mount /dev/sdb1 /mnt/boot

# Create directory for extlinux config
[ ! -d /mnt/boot/extlinux ] && mkdir -vp /mnt/boot/extlinux

# Create directory for apk config
[ ! -d /mnt/etc/apk ] && mkdir -vp /mnt/etc/apk

# Create mount point for devfs
[ ! -d /mnt/dev ] && mkdir -vp /mnt/dev

# Create mount point for procfs
[ ! -d /mnt/proc ] && mkdir -vp /mnt/proc

# Create mount point for sysfs
[ ! -d /mnt/sys ] && mkdir -vp /mnt/sys

# Use bind mounts for dev proc and sys within the target device
mount -o bind /dev /mnt/dev && mount -o bind /proc /mnt/proc && mount -o bind /sys /mnt/sys

# Configure apk package manager
cat <<EOF > /mnt/etc/apk/repositories
#/media/vda1/apks
http://dl-cdn.alpinelinux.org/alpine/edge/main
http://dl-cdn.alpinelinux.org/alpine/edge/community
http://dl-cdn.alpinelinux.org/alpine/edge/testing
EOF

Install Alpine from an Alpine host

Install Alpine with apk

Some of what is going to be installed is up to your choosing. This should be enough to get you going and demonstrate how to target an apk installation.

apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \
    mkinitfs

Setup openrc 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/networking default/chronyd default/local; do
	ln -s /etc/init.d/"${rc##*/}" /mnt/etc/runlevels/"$rc"
done

Setup fstab

cp /mnt/etc/fstab /mnt/etc/fstab.orig
echo $(blkid /dev/sdb2 | sed 's/.*: //;s/ .*//;s/"//g') / \ \ \ \ ext4 rw,relatime 0 1 > /mnt/etc/fstab.new
echo $(blkid /dev/sdb1 | sed 's/.*: //;s/ .*//;s/"//g') /boot ext4 rw,relatime 0 2 >> /mnt/etc/fstab.new
cat /mnt/etc/fstab.orig >> /mnt/etc/fstab.new
cp /mnt/etc/fstab.new /mnt/etc/fstab

Setup networking

[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking
cat <<EOF > /mnt/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

EOF

Set the root password

When the system boots it will require a root password. This differs from Alpine install media but that's not the objective of this guide. This guide is installing a ready system.

passwd -R /mnt root

Enable login on UART

sed -i 's/^#ttyS0/ttyS0/' /mnt/etc/inittab

Install Alpine from an non-Alpine RISC-V Linux host

This section is mainly intended for those trying to install Alpine from one of the vendor images or another RISCV64 install. The apk utility does need to be able to run post-build scripts in order for target installation to function properly.

Download a minirootfs to run apk within a chroot

cd /var/tmp
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz

Unzip in /mnt

cd /mnt
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz
Note: If installing from a non-Alpine host, you may want to install the kernel image and modules first. Come back to this part to chroot and run the apk step and finish up with mkinitfs

Chroot into /mnt and run apk add

chroot /mnt /bin/sh
apk --arch riscv64 --allow-untrusted --initdb add \
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \
    mkinitfs

Setup openrc 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/networking default/chronyd default/local; do
	ln -s /etc/init.d/"${rc##*/}" /etc/runlevels/"$rc"
done

Setup fstab within the chroot

cp /etc/fstab /etc/fstab.orig
echo $(blkid /dev/sdb2 | sed 's/.*: //;s/ .*//;s/"//g') / \ \ \ \ ext4 rw,relatime 0 1 > /etc/fstab.new
echo $(blkid /dev/sdb1 | sed 's/.*: //;s/ .*//;s/"//g') /boot ext4 rw,relatime 0 2 >> /etc/fstab.new
cat /etc/fstab.orig >> /etc/fstab.new
cp /etc/fstab.new /etc/fstab

Setup networking

[ ! -d /etc/network ] mkdir -vp /etc/networking
cat <<EOF > /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

EOF

Set the root password

When the system boots it will require a root password. This differs from Alpine install media but that's not the objective of this guide. This guide is installing a ready system.

passwd

Enable login on UART

sed -i 's/^#ttyS0/ttyS0/' /etc/inittab

Setting up the boot environment

All of the effort up to this point has come down to this. This portion of the guide will assume the kernel being installed is version 6.6.63-ky from the vendor.

Install the kernel

We created an archive for each method of obtaining a kernel. Now we need to unpack that archive in our buildroot.

cd /mnt
tar xzf /var/tmp/linux-6.6.63-ky.tgz

Install the esos.elf firmware

Copy esos.elf from your very safe place to /mnt/lib/firmware

doas cp ~/Downloads/esos.elf /mnt/lib/firmware/

Creating the initrd image

The methods to obtain a kernel omitted collecting initrd images. Those images would not have been based on Alpine. We'll be using mkinitfs to do this. There are a few modifications we need to make in order for this process to generate an image with all the required bits.

Configuring and fixing mkinitfs

Add esos.elf to mkinitfs/features.d/base.files
echo "/lib/firmware/esos.elf" >> /etc/mkinitfs/features.d/base.files
Add the wireless-regdb database files to base.files
Note: You may not need this. If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it. Requires install of wireless-regdb apk package.
echo "/lib/firmware/regulatory.*" >> /etc/mkinitfs/features.d/base.files
Prevent mkinitfs from deleting needed firmware

The mkinitfs script will delete a directory that shouldn't exist. The files assembled from the features.d includes will have already been staged prior to mkinitfs assembling firmware needed by included modules. We need this not to happen and below is the simplest workaround I could pull together. Make a copy of mkinitfs

cp /sbin/mkinitfs /sbin/mkinitfs-rv2

In the initfs_firmware function of /sbin/mkinitfs-rv2 you will find the following lines

        rm -rf "$tmpdir"/lib/firmware
        mkdir -p "$tmpdir"/lib/firmware

Change them to be

        #rm -rf "$tmpdir"/lib/firmware
        [ ! -d "$tmpdir"/lib/firmware ] && mkdir -p "$tmpdir"/lib/firmware

Using mkinitfs-rv2 to create an initrd image

Installing from an Alpine host

mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky

Installing within a chroot

mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky

Configure extlinux

Create an extlinux.conf file with the following

default l0
menu title Alpine U-Boot menu
prompt 1
timeout 10

label l0
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)
    linux /vmlinuz-6.6.63-ky
    initrd /initramfs-6.6.63-ky
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb
    append mtdparts=d420c000.spi-0:64K@0(bootinfo),64K@64K(private),256K@128K(fsbl),64K@384K(env),192K@448K(opensbi),-@640K(uboot) root=UUID=236a5824-0390-42dc-83e3-f02123188f96 console=ttyS0,115200 console=tty1 rootwait rw rootfstype=ext4 earlycon=sbi

A few notes on extlinux.conf

  • Most device trees are generated in a dtbs/[kernel-version] directory.
  • The vendor vmlinuz is a decompressed kernel image, though it shouldn't matter
  • The mtdparts kernel parameter isn't absolutely required
  • Only the right-most console statement seems to get attention. If you're on UART then you'll want console=ttyS0,115200 and if you're on the framebuffer you'll want console=tty1.

Wrapping Up

At this point the primary setup is complete. You may want to add some additional packages or configuration but can also be done after booting the RV2 board.

I may have forgotton something(s) which you'll soon discoven. I'll do my best to fold in corrections as I find they're needed or as new information becomes available.

Unmount the buildroot

umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt

Usability extras

The above should get your OrangePi RV2 booting Alpine Linux. Below are some additional configurations to help make growing your install a little easier. The following assumes you're still chroot /mnt or have booted the system.

Add a local user for yourself with escalation privileges

Create a user account for yourself with a secondary group of wheel

# Create your account
useradd -G wheel -s /bin/bash -d /home/myuser -m -c "My User" myuser
# Set your password
passwd myuser

Add a configuration to doas.d for group wheel

echo permit persist :wheel > /etc/doas.d/00-wheel.conf

Install Avahi for mdns broadcasts

Avahi can broadcast names for services provided by your host. The default config in the Alpine package provides a configuration for sshd.

# First setup the hostname
setup-hostname myhost

# Set the hostname
hostname `cat /etc/hostname`

# Install the avahi apk
apk add avahi

# Enable and start the avahi daemon
rc-update add avahi-daemon && rc-service avahi-daemon start