Installing Alpine Linux on OrangePi RV2: Difference between revisions
mNo edit summary |
mNo edit summary |
||
| (20 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
{{Draft}} | |||
[[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 | {{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.}} | ||
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. | |||
This guide assumes that the manufacturer provided [https://github.com/riscv-software-src/opensbi OpenSBI] and [https://u-boot.org/ U-Boot] binaries have been applied to the SPI Flash device. This stock bootloader will look for an <code>extlinux/extlinux.conf</code> 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 [https://arvanta.net/alpine/install-alpine-riscv64-qemu-uboot/ install Alpine Linux riscv64 under qemu with u-boot loader] by Milan P. Stanić and posted to [[Riscv64]] by [[User:AnIDFB]]. | |||
== Known issues == | == Known issues == | ||
| Line 7: | Line 16: | ||
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}} | {{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}} | ||
* | * WiFi is not functional | ||
* Manufacturer tools are not included | * Manufacturer tools are not included | ||
* Alpine stock kernels do not work | |||
* Need to explicitly disable the RealTek 8852BS module | |||
== Setting up a workspace == | |||
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]]. You'll need to establish a build environment in this QEMU guest. | |||
<pre>doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev</pre> | |||
{{Note| | |||
<code>ncurses</code> and <code>ncurses-dev</code> aren't a hard requirements but are useful if you want to run <code>make menuconfig</code>}} | |||
== Cloning the source, configuring and building the kernel == | |||
{{Warning| | |||
The kernel build is currently broken}} | |||
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work. There's still a bit of patchwork involved as not all support is up-streamed. Fortunately there is someone who is maintaining repository with patched kernel sources. These sources are current to 6.18.20. | |||
The following command will clone just the current HEAD of the patched repository | |||
<pre>git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git | |||
cd linux-spacemit | |||
make ARCH=riscv k1_defconfig | |||
make -j$(nproc)</pre> | |||
{{Note| | |||
The kernel build may fail. I recommend starting with the k1_defconfig and working through errors as they come up. Only the RealTek 8852BS was an issue at the time of this writing.}} | |||
== Preparing the media == | |||
=== Partition and setup the filesystems === | |||
==== Install parted package ==== | |||
<pre>doas apk add parted</pre> | |||
==== 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 <code>/dev/sdb</code>. The following section requires a root shell. | |||
<pre>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</pre> | |||
The final command should produce output to confirm the result of the executed commands. It should look something like the following. | |||
<pre>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 | |||
</pre> | |||
If all looks good, then we can proceed with formatting the partitions | |||
<pre>mkfs.ext4 /dev/sdb1 && mkfs.ext4 /dev/sdb2</pre> | |||
Mount the filesystems and lay some preliminary groundwork. | |||
<pre># 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 | |||
</pre> | |||
== 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. | |||
<pre>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</pre> | |||
=== Setup openrc services === | |||
<pre>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</pre> | |||
=== Setup fstab === | |||
{{Note| | |||
Found bug, Temporarily removed}} | |||
=== Setup networking === | |||
<pre>[ ! -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</pre> | |||
=== 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. | |||
<pre>passwd -R /mnt root</pre> | |||
=== Enable login on UART === | |||
<pre>sed -i 's/^#ttyS0/ttyS0/' /mnt/etc/inittab</pre> | |||
== Install Alpine from an non-Alpine RISC-V Linux host == | |||
=== Download a minirootfs to run apk within a chroot === | |||
<pre>cd /var/tmp | |||
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz</pre> | |||
Unzip in /mnt | |||
<pre>cd /mnt | |||
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz</pre> | |||
{{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 <code>apk add</code> | |||
<pre>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</pre> | |||
=== Setup openrc services === | |||
<pre>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</pre> | |||
=== Setup fstab === | |||
{{Note| | |||
Found bug, Temporarily removed}} | |||
=== Setup networking === | |||
<pre>[ ! -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</pre> | |||
=== 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. | |||
<pre>passwd</pre> | |||
=== Enable login on UART === | |||
<pre>sed -i 's/^#ttyS0/ttyS0/' /etc/inittab</pre> | |||
== Installing the kernel, configure extlinux == | |||
=== Install the kernel === | |||
=== Configure extlinux === | |||
== Basic usability options == | |||
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 | |||
<pre># Create your account | |||
useradd -G wheel -s /bin/bash -d /home/myuser -m -c "My User" myuser | |||
# Set your password | |||
passwd myuser</pre> | |||
Add a configuration to doas.d for group wheel | |||
<pre>echo permit persist :wheel > /etc/doas.d/00-wheel.conf</pre> | |||
=== 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. | |||
<pre># 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</pre> | |||
[[Category:Riscv64]] | [[Category:Riscv64]] | ||
Latest revision as of 01:04, 3 April 2026
Do not follow instructions here until this notice is removed. |
Main Page > Architectures > Riscv64 > Installing Alpine Linux on OrangePi RV2

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

- WiFi is not functional
- Manufacturer tools are not included
- Alpine stock kernels do not work
- Need to explicitly disable the RealTek 8852BS module
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
ncurses and ncurses-dev aren't a hard requirements but are useful if you want to run make menuconfigCloning the source, configuring and building the kernel

Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work. There's still a bit of patchwork involved as not all support is up-streamed. Fortunately there is someone who is maintaining repository with patched kernel sources. These sources are current to 6.18.20.
The following command will clone just the current HEAD of the patched repository
git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git cd linux-spacemit make ARCH=riscv k1_defconfig make -j$(nproc)
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
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
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
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
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
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
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
Installing the kernel, configure extlinux
Install the kernel
Configure extlinux
Basic usability options
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
