<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Aarch0x40</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Aarch0x40"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Aarch0x40"/>
	<updated>2026-05-01T23:13:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32332</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32332"/>
		<updated>2026-04-15T21:33:59Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Implementers of this guide should consider the result development / alpha quality.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
&lt;br /&gt;
=== Why not the Alpine Kernel? ===&lt;br /&gt;
The kernels available from the Alpine Linux Project won&#039;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&#039;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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32331</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32331"/>
		<updated>2026-04-15T21:31:41Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.&lt;br /&gt;
&lt;br /&gt;
Implementers of this guide should consider the result development / alpha quality.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
&lt;br /&gt;
=== Why not the Alpine Kernel? ===&lt;br /&gt;
The kernels available from the Alpine Linux Project won&#039;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&#039;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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32297</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32297"/>
		<updated>2026-04-11T06:47:21Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
&lt;br /&gt;
=== Why not the Alpine Kernel? ===&lt;br /&gt;
The kernels available from the Alpine Linux Project won&#039;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&#039;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.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32296</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32296"/>
		<updated>2026-04-11T05:37:51Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32295</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32295"/>
		<updated>2026-04-11T05:33:56Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Add jdb2 to ext4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
{{Note|&lt;br /&gt;
This may not be necessary.  Need to double check it.&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* If using a kernel without ext4 and jbd2 modules as builtins, you&#039;ll need to append modules=ext4&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Riscv64_Redo&amp;diff=32294</id>
		<title>Talk:Riscv64 Redo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Riscv64_Redo&amp;diff=32294"/>
		<updated>2026-04-11T02:47:31Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=32293</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=32293"/>
		<updated>2026-04-10T05:45:57Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Other Architectures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:package_edutainment.svg|right|link=]]&lt;br /&gt;
{{TOC left}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; explaining how to perform a particular task with Alpine Linux, that expects a minimal knowledge from reader to perform actions. Howto&#039;s have been organized in the below page based on the topics.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The [[#Tutorials|tutorials]] are hands-on&#039;&#039;&#039; and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good example. The output in one step is the starting point for the following step.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
* Contributors are requested to refer to [[Help:Editing]] first and make use of resources like [[How to write a HOWTO]].&lt;br /&gt;
* Contributions must be complete articles. &lt;br /&gt;
* Don&#039;t override already made contributions, unless there is a mistake. &lt;br /&gt;
* If you want to request a topic, please add your request in this page&#039;s [[Talk:Tutorials_and_Howtos|Discussion]].}}&lt;br /&gt;
&lt;br /&gt;
== Desktop ==&lt;br /&gt;
&lt;br /&gt;
* {{:Daily driver guide}}&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
* [[Bluetooth]] - Instructions for installing and configuring Bluetooth&lt;br /&gt;
* [[Bonding]] - Bond (or aggregate) multiple ethernet interfaces&lt;br /&gt;
* [[Bridge]] - Configuring a network bridge&lt;br /&gt;
** [[Bridge wlan0 to eth0]]&lt;br /&gt;
* [[Configure Networking]]&lt;br /&gt;
* [[How to configure static routes]]&lt;br /&gt;
* Modem&lt;br /&gt;
** [[Using HSDPA modem]]&lt;br /&gt;
** [[Using serial modem]]&lt;br /&gt;
* [[mDNS]] - Howto implement multicast DNS resolution in Alpine. &lt;br /&gt;
* [[Multi ISP]] &#039;&#039;(Dual-ISP setup with load-balancing and automatic failover)&#039;&#039;&lt;br /&gt;
* [[PXE boot]]&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
** [[Wi-Fi|Connecting to a wireless access point]]&lt;br /&gt;
** [[How to setup a wireless access point]] &#039;&#039;(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)&#039;&#039;&lt;br /&gt;
* Use [https://github.com/ifupdown-ng/ifupdown-ng/blob/main/doc/interfaces-vxlan.scd vxlan], if using  [[Ifupdown-ng]] instead of [[VLAN]]&lt;br /&gt;
* [[Setting up a Home Router]]&lt;br /&gt;
&lt;br /&gt;
=== Backup and data migration ===&lt;br /&gt;
&lt;br /&gt;
* [[Migrating data]]&lt;br /&gt;
* [[Rsnapshot]] - setting up periodic backups&lt;br /&gt;
&lt;br /&gt;
=== Other topics ===&lt;br /&gt;
&lt;br /&gt;
* [[Gaming on Alpine]]&lt;br /&gt;
* [[Remote Desktop Server]]&lt;br /&gt;
* [[Default applications|How to change default application]]&lt;br /&gt;
* [[CPU frequency scaling]]&lt;br /&gt;
* [[Mimalloc]]&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[How to build the Alpine Linux kernel]]&lt;br /&gt;
* [[Nextcloud]] &#039;&#039;(Self hostable cloud suite - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[Fingerprint Authentication with swaylock]]&lt;br /&gt;
* [[Mounting a LUKS Encrypted Data Partition at Boot]]&lt;br /&gt;
* [[Desktop environments and Window managers|List of supported Desktop environments and Window managers]]&lt;br /&gt;
&lt;br /&gt;
== Diskless ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]]&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
&lt;br /&gt;
== Other Architectures ==&lt;br /&gt;
&lt;br /&gt;
=== APU (PCEngines) ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Install: from a disc to PC Engines APU|Alpine on PC Engines APU]]&lt;br /&gt;
* [https://github.com/huubsch/Installation-of-Alpine-Linux-on-PC-Engines-APU3/tree/main?tab=readme-ov-file Installation of Alpine Linux on PCEngines APU, legacy BIOS]&lt;br /&gt;
&lt;br /&gt;
=== ARM ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine on ARM]]&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
* [[Raspberry Pi|Raspberry Pi main page]]&lt;br /&gt;
* [[Raspberry Pi Bluetooth Speaker|Raspberry Pi - Bluetooth Speaker]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi|Raspberry Pi - Router with VPN]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi (IPv6)|Raspberry Pi - Router with VPN (IPv6)]]&lt;br /&gt;
* [[Classic install or sys mode on Raspberry Pi|Raspberry Pi - Sys mode install]]&lt;br /&gt;
* [[Raspberry Pi LVM on LUKS|Raspberry Pi - Sys mode install - LVM on LUKS]]&lt;br /&gt;
* [[RPI Video Receiver|Raspberry Pi - Video Receiver]] &#039;&#039;(network video decoder using Rasperry Pi and omxplayer)&#039;&#039;&lt;br /&gt;
* [[Raspberry Pi 3 - Browser Client]] - kiosk or digital sign&lt;br /&gt;
* [[Raspberry Pi 3 - Configuring it as wireless access point -AP Mode]]&lt;br /&gt;
* [[Raspberry Pi 3 - Setting Up Bluetooth]]&lt;br /&gt;
* [[Raspberry Pi 4 - Persistent system acting as a NAS and Time Machine]]&lt;br /&gt;
* [[Raspberry_Pi_Zero_W_-_Installation|Raspberry Pi Zero W - Installation]]&lt;br /&gt;
* [[How to set up Alpine as a wireless router|Raspberry Pi Zero W - Wireless router]] &#039;&#039;(Setting up a firewalled, Wireless AP with wired network on a Pi Zero W)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IBM Z (IBM z Systems) ===&lt;br /&gt;
&lt;br /&gt;
* [[s390x|s390x - Installation]]&lt;br /&gt;
&lt;br /&gt;
=== PowerPC ===&lt;br /&gt;
&lt;br /&gt;
* [[Ppc64le|Powerpc64le - Installation]]&lt;br /&gt;
&lt;br /&gt;
=== RISC-V ===&lt;br /&gt;
&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
* [[#Desktop security|Desktop security]] lists steps for securing Alpine Linux desktops&lt;br /&gt;
* [[Setting up a laptop]] page has detailed guidelines to configure a secured laptop&lt;br /&gt;
* [[Securing Alpine Linux|Secure Alpine Linux]] using Security Technical Implementation Guides (STIGs)&lt;br /&gt;
* [[Sshguard|SSHGuard]] - Protects hosts against brute-force attacks:  monitoring logs, attack detection, blocking using firewall.&lt;br /&gt;
&lt;br /&gt;
== Services == &lt;br /&gt;
&lt;br /&gt;
{{Note| Services are arranged in alphabetical order.}}&lt;br /&gt;
&lt;br /&gt;
=== Content management systems ===&lt;br /&gt;
&lt;br /&gt;
* [[DokuWiki]] &#039;&#039;(Simple and easy to use wiki, no database required)&#039;&#039;&lt;br /&gt;
* [[Drupal]] &#039;&#039;(Content Management System (CMS) written in PHP)&#039;&#039;&lt;br /&gt;
* [[Kopano]] &#039;&#039;(Microsoft Outlook compatible Groupware)&#039;&#039;&lt;br /&gt;
* [[Mahara]] &#039;&#039;(E-portfolio and social networking system)&#039;&#039;&lt;br /&gt;
* [[MediaWiki]] &#039;&#039;(Free web-based wiki software application)&#039;&#039;&lt;br /&gt;
* [[Pastebin]] &#039;&#039;(Pastebin software application)&#039;&#039;&lt;br /&gt;
* [[WordPress]] &#039;&#039;(Web software to create website or blog)&#039;&#039;&lt;br /&gt;
* [[Moodle]] &#039;&#039;(Online Learning Management system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Database === &lt;br /&gt;
&lt;br /&gt;
* [[MariaDB]] or [[MySQL|MySQL]]&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
&lt;br /&gt;
* [[DNSCrypt-Proxy]] &#039;&#039;Encrypt and authenticate DNS calls from your system&#039;&#039;&lt;br /&gt;
* [[Setting up nsd DNS server]]&lt;br /&gt;
* [[Small-Time DNS with BIND9]] &#039;&#039;(A simple configuration with ad blocking for your home network)&#039;&#039;&lt;br /&gt;
* Unbound&lt;br /&gt;
** [[Setting up unbound DNS server]]&lt;br /&gt;
** [[Using Unbound as an Ad-blocker]] &#039;&#039;(Setup ad blocking for your network)&#039;&#039;&lt;br /&gt;
* [[TinyDNS Format]]&lt;br /&gt;
&lt;br /&gt;
=== File server ===&lt;br /&gt;
&lt;br /&gt;
* [[Setting up an NFS server|nfs-server]]&lt;br /&gt;
* [[Setting up a Samba server|samba-server]] &#039;&#039;(standard file sharing)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-ad-dc|samba-ad-dc]] &#039;&#039;(Active Directory compatible domain controller)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Firewall ===&lt;br /&gt;
&lt;br /&gt;
* [https://git.alpinelinux.org/awall/about/ Alpine Wall User&#039;s Guide]&lt;br /&gt;
** [[Zero-To-Awall]] -&#039;&#039;AWall for dummies&#039;&#039;&lt;br /&gt;
** [[How-To Alpine Wall]] - &#039;&#039;AWall for Shorewall users&#039;&#039;&lt;br /&gt;
** [[Alpine Wall]] - &#039;&#039;AWall - Firewall management framework - Design Document&#039;&#039;&lt;br /&gt;
* [[Iptables]]&lt;br /&gt;
* [[nftables]]&lt;br /&gt;
* [[Uncomplicated Firewall|Uncomplicated Firewall or UFW]]&lt;br /&gt;
&lt;br /&gt;
=== HTTP and web services ===&lt;br /&gt;
&lt;br /&gt;
* [[Althttpd]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
** [[Apache with php-fpm]]&lt;br /&gt;
** [[Setting Up Apache with PHP]]&lt;br /&gt;
** [[Apache authentication: NTLM Single Signon]]&lt;br /&gt;
* [[Darkhttpd]]&lt;br /&gt;
* [[Lighttpd]]&lt;br /&gt;
** [[Lighttpd Advanced security]]&lt;br /&gt;
** [[Setting Up Lighttpd With FastCGI]]&lt;br /&gt;
** [[Production Web server: Lighttpd|Production web server: Lighttpd‎‎]]&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
** [[Nginx as reverse proxy with acme (letsencrypt)]]&lt;br /&gt;
** [[Nginx with PHP]]&lt;br /&gt;
* Squid Proxy&lt;br /&gt;
** [[Setting up Explicit Squid Proxy]]&lt;br /&gt;
** [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Tomcat]]&lt;br /&gt;
** [[Production LAMP system: Lighttpd + PHP + MySQL‎‎|Production LAMP system: Lighttpd + PHP + MariaDB/MySQL‎‎]]&lt;br /&gt;
&lt;br /&gt;
=== IRC ===&lt;br /&gt;
&lt;br /&gt;
* [[NgIRCd]] &#039;&#039;(Server for Internet Relay Chat/IRC)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(Hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
* [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* Exim/Dovecot&lt;br /&gt;
** [[Small-Time Email with Exim and Dovecot]] &#039;&#039;(A simple configuration for your home network.)&lt;br /&gt;
** [[Setting up dovecot with imap and tls]]&lt;br /&gt;
* [[relay email to gmail (msmtp, mailx, sendmail]]&lt;br /&gt;
* [[relay email (nullmailer)]]&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Setting up postfix with virtual domains]]&lt;br /&gt;
* Server protection&lt;br /&gt;
** [[Setting up clamsmtp]]&lt;br /&gt;
&lt;br /&gt;
=== Monitoring ===&lt;br /&gt;
&lt;br /&gt;
* [[Awstats]] &#039;&#039;(Free log file analyzer)&#039;&#039;&lt;br /&gt;
* [[Cacti: traffic analysis and monitoring network]] &#039;&#039;(Front-end for rrdtool networking monitor)&#039;&#039;&lt;br /&gt;
* [[Cvechecker]] &#039;&#039;(Compare installed packages for Common Vulnerabilities Exposure)&#039;&#039; &amp;lt;!-- Monitoring and Security --&amp;gt;&lt;br /&gt;
* [[Linfo]]&lt;br /&gt;
* [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[PhpSysInfo]] &#039;&#039;(A simple application that displays information about the host it&#039;s running on)&#039;&#039;&lt;br /&gt;
* [[Logcheck]] &#039;&#039;(log file monitoring tool)&#039;&#039;&lt;br /&gt;
* [[Matomo]] &#039;&#039;(A real time web analytics software program)&#039;&#039;&lt;br /&gt;
* [[Rasdaemon]] &#039;&#039;(Platform Reliability, Availability and Serviceability monitoring tool)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft, solution, Networking and Monitoring and Server --&amp;gt;&lt;br /&gt;
** [[Setting up NRPE daemon]] &#039;&#039;(Performs remote Nagios checks)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting Up Fprobe And Ntop|Ntop]] &#039;&#039;(NetFlow collection and analysis using a remote fprobe instance; for alpine 3.10-3.12 only)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Traffic monitoring]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
** [[Setting up monitoring using rrdtool (and rrdcollect)]]&lt;br /&gt;
** [[Setting up traffic monitoring using rrdtool (and snmp)]] &amp;lt;!-- Monitoring --&amp;gt;&lt;br /&gt;
* [[Zabbix|Zabbix - the professional complete manager]] &#039;&#039;(Monitor and track the status of network services and hardware)&#039;&#039;&lt;br /&gt;
* [[ZoneMinder video camera security and surveillance]]&lt;br /&gt;
&lt;br /&gt;
=== Remote Administration ===&lt;br /&gt;
&lt;br /&gt;
* ACF&lt;br /&gt;
** [[Changing passwords for ACF|ACF - changing passwords]]&lt;br /&gt;
** [[Generating SSL certs with ACF]] &amp;lt;!-- Generating SSL certs with ACF 1.9 --&amp;gt;&lt;br /&gt;
** [[setup-acf| ACF - setup]] &#039;&#039;(Configures ACF (webconfiguration/webmin) so you can manage your box through https)&#039;&#039;&lt;br /&gt;
* [[Setting up a SSH server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
** [[HOWTO OpenSSH 2FA with password and Google Authenticator |OpenSSH 2FA]] &#039;&#039;(A simple two factor setup for OpenSSH)&#039;&#039;&lt;br /&gt;
* [[OpenVCP]] &#039;&#039;(VServer Control Panel)&#039;&#039;&lt;br /&gt;
* [[PhpMyAdmin]] &#039;&#039;(Web-based administration tool for MYSQL)&#039;&#039;&lt;br /&gt;
* [[PhpPgAdmin]] &#039;&#039;(Web-based administration tool for PostgreSQL)&#039;&#039;&lt;br /&gt;
* [[Webmin]] &#039;&#039;(A web-based interface for Linux system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Telephony ===&lt;br /&gt;
&lt;br /&gt;
* [[FreePBX|FreePBX on Alpine Linux]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Kamailio]] &#039;&#039;(SIP Server, formerly OpenSER)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== VPN ===&lt;br /&gt;
* [[Freeradius Active Directory Integration]]&lt;br /&gt;
* [[GNUnet]]&lt;br /&gt;
* [[IGMPproxy]]&lt;br /&gt;
* [[Setting up a OpenVPN server|OpenVPN server]] &#039;&#039;(Allowing single users or devices to remotely connect to your network)&#039;&#039;&lt;br /&gt;
* [[OpenVSwitch]]&lt;br /&gt;
* [[Openconnect-SSO in Docker]]&lt;br /&gt;
* [[Tor]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Configure a Wireguard interface (wg)|Wireguard]]&lt;br /&gt;
* [[Vpnc]]&lt;br /&gt;
&lt;br /&gt;
=== Other Servers ===&lt;br /&gt;
&lt;br /&gt;
* [[apcupsd]] &#039;&#039;(UPS Monitoring with apcupsd)&#039;&#039;&lt;br /&gt;
* [[Chrony and GPSD | Chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]&lt;br /&gt;
* [[Glpi]] &#039;&#039;(Manage inventory of technical resources)&#039;&#039;&lt;br /&gt;
* [[How to setup a Alpine Linux mirror]]&lt;br /&gt;
* [[nut-ups|NUT UPS]] &#039;&#039;(UPS Monitoring with Network UPS Tools)&#039;&#039;&lt;br /&gt;
* [[Odoo]]&lt;br /&gt;
* [[Configure OpenLDAP | OpenLDAP]] &#039;&#039;(Installing and configuring the Alpine package for OpenLDAP)&#039;&#039;&lt;br /&gt;
* [[Setting up a LLDAP server|lldap-server]] &#039;&#039;(Directory Server)&#039;&#039;&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software development ==&lt;br /&gt;
&lt;br /&gt;
* [[Cgit]]&lt;br /&gt;
* [[OsTicket]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Patchwork]] &#039;&#039;(Patch review management system)&#039;&#039;&lt;br /&gt;
* [[Redmine]] &#039;&#039;(Project management system) [Deprecated]&#039;&#039;&lt;br /&gt;
* [[Request Tracker]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Setting up trac wiki|Trac]] &#039;&#039;(Enhanced wiki and issue tracking system for software development projects)&#039;&#039;&lt;br /&gt;
* [[Ansible]] &#039;&#039;(Configuration management)&#039;&#039;&lt;br /&gt;
* [[Installing Oracle Java|Oracle Java (installation)]]&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up disks manually|Manual partitioning]]&lt;br /&gt;
* [[Disk Replication with DRBD|DRBD: Disk Replication]]&lt;br /&gt;
* [[Filesystems]]&lt;br /&gt;
** [[Burning ISOs]]&lt;br /&gt;
* [[Setting up iSCSI|iSCSI Setup]]&lt;br /&gt;
** [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
** [[Linux iSCSI Target (TCM)|iSCSI Target (TCM)/LinuxIO (LIO)]]&lt;br /&gt;
** [[Linux iSCSI Target (tgt)|User space iSCSI Target (tgt)]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM|LVM Setup]]&lt;br /&gt;
** [[Setting up LVM on GPT-labeled disks|LVM on GPT-labeled disks]]&lt;br /&gt;
** [[Installing on GPT LVM|LVM on GPT-labeled disks (updated)]]&lt;br /&gt;
** [[LVM on LUKS]]&lt;br /&gt;
* RAID&lt;br /&gt;
** [[Raid Administration]]&lt;br /&gt;
** [[Setting up a software RAID array]]&lt;br /&gt;
* [[ZFS]]&lt;br /&gt;
** [[Root on ZFS with native encryption]]&lt;br /&gt;
** [[Setting up ZFS on LUKS]]&lt;br /&gt;
* [[CEPH|CEPH]]&lt;br /&gt;
&lt;br /&gt;
== Virtualization ==&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
* [[Installing Alpine in a virtual machine]]&lt;br /&gt;
** [[Install Alpine on VMware ESXi]]&lt;br /&gt;
* [[KVM]] &#039;&#039;(Setting up Alpine as a KVM hypervisor)&#039;&#039;&lt;br /&gt;
* [[LXC]] &#039;&#039;(Setting up a Linux container in Alpine Linux)&#039;&#039;&lt;br /&gt;
* [[QEMU]]&lt;br /&gt;
* Xen&lt;br /&gt;
** [[Xen Dom0]] &#039;&#039;(Setting up Alpine as a dom0 for Xen hypervisor)&#039;&#039;&lt;br /&gt;
** [[Xen Dom0 on USB or SD]]&lt;br /&gt;
** [[Create Alpine Linux PV DomU|Xen DomU (paravirtualized)]]&lt;br /&gt;
** [[Xen LiveCD]]&lt;br /&gt;
** [[Xen PCI Passthrough]]&lt;br /&gt;
** [[K8s]] Building a K8s Kubernetes Cluster on Alpine Linux&lt;br /&gt;
* [[Runc]]&lt;br /&gt;
&lt;br /&gt;
== [[Simple_Walkthrough]] ==&lt;br /&gt;
* [[About-virtualization-simple]]&lt;br /&gt;
* [[LXC_Alpinelinux_Simple]]&lt;br /&gt;
* [[Qemu-simple]]&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[TTY_Autologin|TTY Autologin]]&lt;br /&gt;
* [[Kexec|Faster rebooting with kexec]]&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small Office Services]]&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039;&lt;br /&gt;
* [[Linux iSCSI Target (TCM)]]&lt;br /&gt;
* [[ISP Mail Server 3.x HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-service ISP mail server)&#039;&#039;&lt;br /&gt;
* [[Grommunio Mail Server]] &#039;&#039;(Mariadb+Postfix+Rspamd+Grommunio - Full-service mail server as MS exchange replacement)&#039;&#039;&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Streaming Security Camera Video with VLC]]&lt;br /&gt;
* [[Install Alpine on a btrfs filesystem with refind as boot manager]]&lt;br /&gt;
* [[Compile software from source|How to Compile a software from source in Alpine Linux]]&lt;br /&gt;
* [https://ww2.coastal.edu/mmurphy2/oer/alpine/ Alpine Linux tutorials - Dr Murphy, Computing Science Associate Professor]&lt;br /&gt;
* [[Michael&#039;s base installation procedure|Michael&#039;s base installation procedure]]&lt;br /&gt;
* [[Michael&#039;s cwm  desktop (minimal)|Michael&#039;s cwm desktop (minimal)]]&lt;br /&gt;
* [[Michael&#039;s sway desktop (minimal)|Michael&#039;s Sway desktop (minimal)]]&lt;br /&gt;
* [[Sway_customization_guide|Sway customization guide]] &#039;&#039;(Tutorial re Sway config file basics)&#039;&#039;&lt;br /&gt;
* [[Using Distrobox For VR Gaming|Using Distrobox For VR Gaming]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=32292</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=32292"/>
		<updated>2026-04-10T05:45:17Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Other Architectures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:package_edutainment.svg|right|link=]]&lt;br /&gt;
{{TOC left}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; explaining how to perform a particular task with Alpine Linux, that expects a minimal knowledge from reader to perform actions. Howto&#039;s have been organized in the below page based on the topics.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The [[#Tutorials|tutorials]] are hands-on&#039;&#039;&#039; and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good example. The output in one step is the starting point for the following step.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
* Contributors are requested to refer to [[Help:Editing]] first and make use of resources like [[How to write a HOWTO]].&lt;br /&gt;
* Contributions must be complete articles. &lt;br /&gt;
* Don&#039;t override already made contributions, unless there is a mistake. &lt;br /&gt;
* If you want to request a topic, please add your request in this page&#039;s [[Talk:Tutorials_and_Howtos|Discussion]].}}&lt;br /&gt;
&lt;br /&gt;
== Desktop ==&lt;br /&gt;
&lt;br /&gt;
* {{:Daily driver guide}}&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
* [[Bluetooth]] - Instructions for installing and configuring Bluetooth&lt;br /&gt;
* [[Bonding]] - Bond (or aggregate) multiple ethernet interfaces&lt;br /&gt;
* [[Bridge]] - Configuring a network bridge&lt;br /&gt;
** [[Bridge wlan0 to eth0]]&lt;br /&gt;
* [[Configure Networking]]&lt;br /&gt;
* [[How to configure static routes]]&lt;br /&gt;
* Modem&lt;br /&gt;
** [[Using HSDPA modem]]&lt;br /&gt;
** [[Using serial modem]]&lt;br /&gt;
* [[mDNS]] - Howto implement multicast DNS resolution in Alpine. &lt;br /&gt;
* [[Multi ISP]] &#039;&#039;(Dual-ISP setup with load-balancing and automatic failover)&#039;&#039;&lt;br /&gt;
* [[PXE boot]]&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
** [[Wi-Fi|Connecting to a wireless access point]]&lt;br /&gt;
** [[How to setup a wireless access point]] &#039;&#039;(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)&#039;&#039;&lt;br /&gt;
* Use [https://github.com/ifupdown-ng/ifupdown-ng/blob/main/doc/interfaces-vxlan.scd vxlan], if using  [[Ifupdown-ng]] instead of [[VLAN]]&lt;br /&gt;
* [[Setting up a Home Router]]&lt;br /&gt;
&lt;br /&gt;
=== Backup and data migration ===&lt;br /&gt;
&lt;br /&gt;
* [[Migrating data]]&lt;br /&gt;
* [[Rsnapshot]] - setting up periodic backups&lt;br /&gt;
&lt;br /&gt;
=== Other topics ===&lt;br /&gt;
&lt;br /&gt;
* [[Gaming on Alpine]]&lt;br /&gt;
* [[Remote Desktop Server]]&lt;br /&gt;
* [[Default applications|How to change default application]]&lt;br /&gt;
* [[CPU frequency scaling]]&lt;br /&gt;
* [[Mimalloc]]&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[How to build the Alpine Linux kernel]]&lt;br /&gt;
* [[Nextcloud]] &#039;&#039;(Self hostable cloud suite - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[Fingerprint Authentication with swaylock]]&lt;br /&gt;
* [[Mounting a LUKS Encrypted Data Partition at Boot]]&lt;br /&gt;
* [[Desktop environments and Window managers|List of supported Desktop environments and Window managers]]&lt;br /&gt;
&lt;br /&gt;
== Diskless ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]]&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
&lt;br /&gt;
== Other Architectures ==&lt;br /&gt;
&lt;br /&gt;
=== APU (PCEngines) ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Install: from a disc to PC Engines APU|Alpine on PC Engines APU]]&lt;br /&gt;
* [https://github.com/huubsch/Installation-of-Alpine-Linux-on-PC-Engines-APU3/tree/main?tab=readme-ov-file Installation of Alpine Linux on PCEngines APU, legacy BIOS]&lt;br /&gt;
&lt;br /&gt;
=== ARM ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine on ARM]]&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
* [[Raspberry Pi|Raspberry Pi main page]]&lt;br /&gt;
* [[Raspberry Pi Bluetooth Speaker|Raspberry Pi - Bluetooth Speaker]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi|Raspberry Pi - Router with VPN]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi (IPv6)|Raspberry Pi - Router with VPN (IPv6)]]&lt;br /&gt;
* [[Classic install or sys mode on Raspberry Pi|Raspberry Pi - Sys mode install]]&lt;br /&gt;
* [[Raspberry Pi LVM on LUKS|Raspberry Pi - Sys mode install - LVM on LUKS]]&lt;br /&gt;
* [[RPI Video Receiver|Raspberry Pi - Video Receiver]] &#039;&#039;(network video decoder using Rasperry Pi and omxplayer)&#039;&#039;&lt;br /&gt;
* [[Raspberry Pi 3 - Browser Client]] - kiosk or digital sign&lt;br /&gt;
* [[Raspberry Pi 3 - Configuring it as wireless access point -AP Mode]]&lt;br /&gt;
* [[Raspberry Pi 3 - Setting Up Bluetooth]]&lt;br /&gt;
* [[Raspberry Pi 4 - Persistent system acting as a NAS and Time Machine]]&lt;br /&gt;
* [[Raspberry_Pi_Zero_W_-_Installation|Raspberry Pi Zero W - Installation]]&lt;br /&gt;
* [[How to set up Alpine as a wireless router|Raspberry Pi Zero W - Wireless router]] &#039;&#039;(Setting up a firewalled, Wireless AP with wired network on a Pi Zero W)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IBM Z (IBM z Systems) ===&lt;br /&gt;
&lt;br /&gt;
* [[s390x|s390x - Installation]]&lt;br /&gt;
&lt;br /&gt;
=== RISC-V ===&lt;br /&gt;
&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
=== PowerPC ===&lt;br /&gt;
&lt;br /&gt;
* [[Ppc64le|Powerpc64le - Installation]]&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
* [[#Desktop security|Desktop security]] lists steps for securing Alpine Linux desktops&lt;br /&gt;
* [[Setting up a laptop]] page has detailed guidelines to configure a secured laptop&lt;br /&gt;
* [[Securing Alpine Linux|Secure Alpine Linux]] using Security Technical Implementation Guides (STIGs)&lt;br /&gt;
* [[Sshguard|SSHGuard]] - Protects hosts against brute-force attacks:  monitoring logs, attack detection, blocking using firewall.&lt;br /&gt;
&lt;br /&gt;
== Services == &lt;br /&gt;
&lt;br /&gt;
{{Note| Services are arranged in alphabetical order.}}&lt;br /&gt;
&lt;br /&gt;
=== Content management systems ===&lt;br /&gt;
&lt;br /&gt;
* [[DokuWiki]] &#039;&#039;(Simple and easy to use wiki, no database required)&#039;&#039;&lt;br /&gt;
* [[Drupal]] &#039;&#039;(Content Management System (CMS) written in PHP)&#039;&#039;&lt;br /&gt;
* [[Kopano]] &#039;&#039;(Microsoft Outlook compatible Groupware)&#039;&#039;&lt;br /&gt;
* [[Mahara]] &#039;&#039;(E-portfolio and social networking system)&#039;&#039;&lt;br /&gt;
* [[MediaWiki]] &#039;&#039;(Free web-based wiki software application)&#039;&#039;&lt;br /&gt;
* [[Pastebin]] &#039;&#039;(Pastebin software application)&#039;&#039;&lt;br /&gt;
* [[WordPress]] &#039;&#039;(Web software to create website or blog)&#039;&#039;&lt;br /&gt;
* [[Moodle]] &#039;&#039;(Online Learning Management system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Database === &lt;br /&gt;
&lt;br /&gt;
* [[MariaDB]] or [[MySQL|MySQL]]&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
&lt;br /&gt;
* [[DNSCrypt-Proxy]] &#039;&#039;Encrypt and authenticate DNS calls from your system&#039;&#039;&lt;br /&gt;
* [[Setting up nsd DNS server]]&lt;br /&gt;
* [[Small-Time DNS with BIND9]] &#039;&#039;(A simple configuration with ad blocking for your home network)&#039;&#039;&lt;br /&gt;
* Unbound&lt;br /&gt;
** [[Setting up unbound DNS server]]&lt;br /&gt;
** [[Using Unbound as an Ad-blocker]] &#039;&#039;(Setup ad blocking for your network)&#039;&#039;&lt;br /&gt;
* [[TinyDNS Format]]&lt;br /&gt;
&lt;br /&gt;
=== File server ===&lt;br /&gt;
&lt;br /&gt;
* [[Setting up an NFS server|nfs-server]]&lt;br /&gt;
* [[Setting up a Samba server|samba-server]] &#039;&#039;(standard file sharing)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-ad-dc|samba-ad-dc]] &#039;&#039;(Active Directory compatible domain controller)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Firewall ===&lt;br /&gt;
&lt;br /&gt;
* [https://git.alpinelinux.org/awall/about/ Alpine Wall User&#039;s Guide]&lt;br /&gt;
** [[Zero-To-Awall]] -&#039;&#039;AWall for dummies&#039;&#039;&lt;br /&gt;
** [[How-To Alpine Wall]] - &#039;&#039;AWall for Shorewall users&#039;&#039;&lt;br /&gt;
** [[Alpine Wall]] - &#039;&#039;AWall - Firewall management framework - Design Document&#039;&#039;&lt;br /&gt;
* [[Iptables]]&lt;br /&gt;
* [[nftables]]&lt;br /&gt;
* [[Uncomplicated Firewall|Uncomplicated Firewall or UFW]]&lt;br /&gt;
&lt;br /&gt;
=== HTTP and web services ===&lt;br /&gt;
&lt;br /&gt;
* [[Althttpd]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
** [[Apache with php-fpm]]&lt;br /&gt;
** [[Setting Up Apache with PHP]]&lt;br /&gt;
** [[Apache authentication: NTLM Single Signon]]&lt;br /&gt;
* [[Darkhttpd]]&lt;br /&gt;
* [[Lighttpd]]&lt;br /&gt;
** [[Lighttpd Advanced security]]&lt;br /&gt;
** [[Setting Up Lighttpd With FastCGI]]&lt;br /&gt;
** [[Production Web server: Lighttpd|Production web server: Lighttpd‎‎]]&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
** [[Nginx as reverse proxy with acme (letsencrypt)]]&lt;br /&gt;
** [[Nginx with PHP]]&lt;br /&gt;
* Squid Proxy&lt;br /&gt;
** [[Setting up Explicit Squid Proxy]]&lt;br /&gt;
** [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Tomcat]]&lt;br /&gt;
** [[Production LAMP system: Lighttpd + PHP + MySQL‎‎|Production LAMP system: Lighttpd + PHP + MariaDB/MySQL‎‎]]&lt;br /&gt;
&lt;br /&gt;
=== IRC ===&lt;br /&gt;
&lt;br /&gt;
* [[NgIRCd]] &#039;&#039;(Server for Internet Relay Chat/IRC)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(Hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
* [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* Exim/Dovecot&lt;br /&gt;
** [[Small-Time Email with Exim and Dovecot]] &#039;&#039;(A simple configuration for your home network.)&lt;br /&gt;
** [[Setting up dovecot with imap and tls]]&lt;br /&gt;
* [[relay email to gmail (msmtp, mailx, sendmail]]&lt;br /&gt;
* [[relay email (nullmailer)]]&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Setting up postfix with virtual domains]]&lt;br /&gt;
* Server protection&lt;br /&gt;
** [[Setting up clamsmtp]]&lt;br /&gt;
&lt;br /&gt;
=== Monitoring ===&lt;br /&gt;
&lt;br /&gt;
* [[Awstats]] &#039;&#039;(Free log file analyzer)&#039;&#039;&lt;br /&gt;
* [[Cacti: traffic analysis and monitoring network]] &#039;&#039;(Front-end for rrdtool networking monitor)&#039;&#039;&lt;br /&gt;
* [[Cvechecker]] &#039;&#039;(Compare installed packages for Common Vulnerabilities Exposure)&#039;&#039; &amp;lt;!-- Monitoring and Security --&amp;gt;&lt;br /&gt;
* [[Linfo]]&lt;br /&gt;
* [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[PhpSysInfo]] &#039;&#039;(A simple application that displays information about the host it&#039;s running on)&#039;&#039;&lt;br /&gt;
* [[Logcheck]] &#039;&#039;(log file monitoring tool)&#039;&#039;&lt;br /&gt;
* [[Matomo]] &#039;&#039;(A real time web analytics software program)&#039;&#039;&lt;br /&gt;
* [[Rasdaemon]] &#039;&#039;(Platform Reliability, Availability and Serviceability monitoring tool)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft, solution, Networking and Monitoring and Server --&amp;gt;&lt;br /&gt;
** [[Setting up NRPE daemon]] &#039;&#039;(Performs remote Nagios checks)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting Up Fprobe And Ntop|Ntop]] &#039;&#039;(NetFlow collection and analysis using a remote fprobe instance; for alpine 3.10-3.12 only)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Traffic monitoring]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
** [[Setting up monitoring using rrdtool (and rrdcollect)]]&lt;br /&gt;
** [[Setting up traffic monitoring using rrdtool (and snmp)]] &amp;lt;!-- Monitoring --&amp;gt;&lt;br /&gt;
* [[Zabbix|Zabbix - the professional complete manager]] &#039;&#039;(Monitor and track the status of network services and hardware)&#039;&#039;&lt;br /&gt;
* [[ZoneMinder video camera security and surveillance]]&lt;br /&gt;
&lt;br /&gt;
=== Remote Administration ===&lt;br /&gt;
&lt;br /&gt;
* ACF&lt;br /&gt;
** [[Changing passwords for ACF|ACF - changing passwords]]&lt;br /&gt;
** [[Generating SSL certs with ACF]] &amp;lt;!-- Generating SSL certs with ACF 1.9 --&amp;gt;&lt;br /&gt;
** [[setup-acf| ACF - setup]] &#039;&#039;(Configures ACF (webconfiguration/webmin) so you can manage your box through https)&#039;&#039;&lt;br /&gt;
* [[Setting up a SSH server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
** [[HOWTO OpenSSH 2FA with password and Google Authenticator |OpenSSH 2FA]] &#039;&#039;(A simple two factor setup for OpenSSH)&#039;&#039;&lt;br /&gt;
* [[OpenVCP]] &#039;&#039;(VServer Control Panel)&#039;&#039;&lt;br /&gt;
* [[PhpMyAdmin]] &#039;&#039;(Web-based administration tool for MYSQL)&#039;&#039;&lt;br /&gt;
* [[PhpPgAdmin]] &#039;&#039;(Web-based administration tool for PostgreSQL)&#039;&#039;&lt;br /&gt;
* [[Webmin]] &#039;&#039;(A web-based interface for Linux system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Telephony ===&lt;br /&gt;
&lt;br /&gt;
* [[FreePBX|FreePBX on Alpine Linux]]&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Kamailio]] &#039;&#039;(SIP Server, formerly OpenSER)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== VPN ===&lt;br /&gt;
* [[Freeradius Active Directory Integration]]&lt;br /&gt;
* [[GNUnet]]&lt;br /&gt;
* [[IGMPproxy]]&lt;br /&gt;
* [[Setting up a OpenVPN server|OpenVPN server]] &#039;&#039;(Allowing single users or devices to remotely connect to your network)&#039;&#039;&lt;br /&gt;
* [[OpenVSwitch]]&lt;br /&gt;
* [[Openconnect-SSO in Docker]]&lt;br /&gt;
* [[Tor]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Configure a Wireguard interface (wg)|Wireguard]]&lt;br /&gt;
* [[Vpnc]]&lt;br /&gt;
&lt;br /&gt;
=== Other Servers ===&lt;br /&gt;
&lt;br /&gt;
* [[apcupsd]] &#039;&#039;(UPS Monitoring with apcupsd)&#039;&#039;&lt;br /&gt;
* [[Chrony and GPSD | Chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]&lt;br /&gt;
* [[Glpi]] &#039;&#039;(Manage inventory of technical resources)&#039;&#039;&lt;br /&gt;
* [[How to setup a Alpine Linux mirror]]&lt;br /&gt;
* [[nut-ups|NUT UPS]] &#039;&#039;(UPS Monitoring with Network UPS Tools)&#039;&#039;&lt;br /&gt;
* [[Odoo]]&lt;br /&gt;
* [[Configure OpenLDAP | OpenLDAP]] &#039;&#039;(Installing and configuring the Alpine package for OpenLDAP)&#039;&#039;&lt;br /&gt;
* [[Setting up a LLDAP server|lldap-server]] &#039;&#039;(Directory Server)&#039;&#039;&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software development ==&lt;br /&gt;
&lt;br /&gt;
* [[Cgit]]&lt;br /&gt;
* [[OsTicket]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Patchwork]] &#039;&#039;(Patch review management system)&#039;&#039;&lt;br /&gt;
* [[Redmine]] &#039;&#039;(Project management system) [Deprecated]&#039;&#039;&lt;br /&gt;
* [[Request Tracker]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Setting up trac wiki|Trac]] &#039;&#039;(Enhanced wiki and issue tracking system for software development projects)&#039;&#039;&lt;br /&gt;
* [[Ansible]] &#039;&#039;(Configuration management)&#039;&#039;&lt;br /&gt;
* [[Installing Oracle Java|Oracle Java (installation)]]&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up disks manually|Manual partitioning]]&lt;br /&gt;
* [[Disk Replication with DRBD|DRBD: Disk Replication]]&lt;br /&gt;
* [[Filesystems]]&lt;br /&gt;
** [[Burning ISOs]]&lt;br /&gt;
* [[Setting up iSCSI|iSCSI Setup]]&lt;br /&gt;
** [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
** [[Linux iSCSI Target (TCM)|iSCSI Target (TCM)/LinuxIO (LIO)]]&lt;br /&gt;
** [[Linux iSCSI Target (tgt)|User space iSCSI Target (tgt)]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM|LVM Setup]]&lt;br /&gt;
** [[Setting up LVM on GPT-labeled disks|LVM on GPT-labeled disks]]&lt;br /&gt;
** [[Installing on GPT LVM|LVM on GPT-labeled disks (updated)]]&lt;br /&gt;
** [[LVM on LUKS]]&lt;br /&gt;
* RAID&lt;br /&gt;
** [[Raid Administration]]&lt;br /&gt;
** [[Setting up a software RAID array]]&lt;br /&gt;
* [[ZFS]]&lt;br /&gt;
** [[Root on ZFS with native encryption]]&lt;br /&gt;
** [[Setting up ZFS on LUKS]]&lt;br /&gt;
* [[CEPH|CEPH]]&lt;br /&gt;
&lt;br /&gt;
== Virtualization ==&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
* [[Installing Alpine in a virtual machine]]&lt;br /&gt;
** [[Install Alpine on VMware ESXi]]&lt;br /&gt;
* [[KVM]] &#039;&#039;(Setting up Alpine as a KVM hypervisor)&#039;&#039;&lt;br /&gt;
* [[LXC]] &#039;&#039;(Setting up a Linux container in Alpine Linux)&#039;&#039;&lt;br /&gt;
* [[QEMU]]&lt;br /&gt;
* Xen&lt;br /&gt;
** [[Xen Dom0]] &#039;&#039;(Setting up Alpine as a dom0 for Xen hypervisor)&#039;&#039;&lt;br /&gt;
** [[Xen Dom0 on USB or SD]]&lt;br /&gt;
** [[Create Alpine Linux PV DomU|Xen DomU (paravirtualized)]]&lt;br /&gt;
** [[Xen LiveCD]]&lt;br /&gt;
** [[Xen PCI Passthrough]]&lt;br /&gt;
** [[K8s]] Building a K8s Kubernetes Cluster on Alpine Linux&lt;br /&gt;
* [[Runc]]&lt;br /&gt;
&lt;br /&gt;
== [[Simple_Walkthrough]] ==&lt;br /&gt;
* [[About-virtualization-simple]]&lt;br /&gt;
* [[LXC_Alpinelinux_Simple]]&lt;br /&gt;
* [[Qemu-simple]]&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[TTY_Autologin|TTY Autologin]]&lt;br /&gt;
* [[Kexec|Faster rebooting with kexec]]&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small Office Services]]&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039;&lt;br /&gt;
* [[Linux iSCSI Target (TCM)]]&lt;br /&gt;
* [[ISP Mail Server 3.x HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-service ISP mail server)&#039;&#039;&lt;br /&gt;
* [[Grommunio Mail Server]] &#039;&#039;(Mariadb+Postfix+Rspamd+Grommunio - Full-service mail server as MS exchange replacement)&#039;&#039;&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Streaming Security Camera Video with VLC]]&lt;br /&gt;
* [[Install Alpine on a btrfs filesystem with refind as boot manager]]&lt;br /&gt;
* [[Compile software from source|How to Compile a software from source in Alpine Linux]]&lt;br /&gt;
* [https://ww2.coastal.edu/mmurphy2/oer/alpine/ Alpine Linux tutorials - Dr Murphy, Computing Science Associate Professor]&lt;br /&gt;
* [[Michael&#039;s base installation procedure|Michael&#039;s base installation procedure]]&lt;br /&gt;
* [[Michael&#039;s cwm  desktop (minimal)|Michael&#039;s cwm desktop (minimal)]]&lt;br /&gt;
* [[Michael&#039;s sway desktop (minimal)|Michael&#039;s Sway desktop (minimal)]]&lt;br /&gt;
* [[Sway_customization_guide|Sway customization guide]] &#039;&#039;(Tutorial re Sway config file basics)&#039;&#039;&lt;br /&gt;
* [[Using Distrobox For VR Gaming|Using Distrobox For VR Gaming]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32291</id>
		<title>Talk:Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32291"/>
		<updated>2026-04-10T05:39:35Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32290</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32290"/>
		<updated>2026-04-10T05:39:20Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.6.63-ky)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* If using a kernel without ext4 and jbd2 modules as builtins, you&#039;ll need to append modules=ext4&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32289</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32289"/>
		<updated>2026-04-10T04:41:21Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
We created an archive for each method of obtaining a kernel.  Now we need to unpack that archive in our buildroot.&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xzf /var/tmp/linux-6.6.63-ky.tgz&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
Copy esos.elf from your very safe place to /mnt/lib/firmware&lt;br /&gt;
&amp;lt;pre&amp;gt;doas cp ~/Downloads/esos.elf /mnt/lib/firmware/&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
The methods to obtain a kernel omitted collecting initrd images.  Those images would not have been based on Alpine.  We&#039;ll be using &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
Installing from an Alpine host&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -b /mnt -c /mnt/etc/mkinitfs/mkinitfs.conf -o /mnt/boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing within a chroot&lt;br /&gt;
&amp;lt;pre&amp;gt;mkinitfs-rv2 -c /etc/mkinitfs/mkinitfs.conf -o /boot/initramfs-6.6.63-ky 6.6.63-ky&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
Create an extlinux.conf file with the following&lt;br /&gt;
&amp;lt;pre&amp;gt;default l0&lt;br /&gt;
menu title Alpine U-Boot menu&lt;br /&gt;
prompt 1&lt;br /&gt;
timeout 10&lt;br /&gt;
&lt;br /&gt;
label l0&lt;br /&gt;
    menu label Alpine Linux 3.24.0_alpha20260127 (Kernel 6.17.0-spacemit-k1)&lt;br /&gt;
    linux /vmlinuz-6.6.63-ky&lt;br /&gt;
    initrd /initramfs-6.6.63-ky&lt;br /&gt;
    fdt /dtb-6.6.63-ky/ky/x1_orangepi-rv2.dtb&lt;br /&gt;
    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&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A few notes on extlinux.conf ====&lt;br /&gt;
* Most device trees are generated in a dtbs/[kernel-version] directory.&lt;br /&gt;
* The vendor vmlinuz is a decompressed kernel image, though it shouldn&#039;t matter&lt;br /&gt;
* The mtdparts kernel parameter isn&#039;t absolutely required&lt;br /&gt;
* If using a kernel without ext4 and jbd2 modules as builtins, you&#039;ll need to append modules=ext4&lt;br /&gt;
* Only the right-most console statement seems to get attention.  If you&#039;re on UART then you&#039;ll want &amp;lt;code&amp;gt;console=ttyS0,115200&amp;lt;/code&amp;gt; and if you&#039;re on the framebuffer you&#039;ll want &amp;lt;code&amp;gt;console=tty1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Wrapping Up ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I may have forgotton something(s) which you&#039;ll soon discoven.  I&#039;ll do my best to fold in corrections as I find they&#039;re needed or as new information becomes available.&lt;br /&gt;
&lt;br /&gt;
=== Unmount the buildroot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;umount /mnt/proc /mnt/sys /mnt/dev /mnt/boot /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usability extras ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32288</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32288"/>
		<updated>2026-04-10T04:02:29Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32287</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32287"/>
		<updated>2026-04-10T04:00:17Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC left}}&lt;br /&gt;
{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32286</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32286"/>
		<updated>2026-04-10T03:57:38Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32285</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32285"/>
		<updated>2026-04-10T03:52:59Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
This is needs a redo.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32284</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32284"/>
		<updated>2026-04-10T03:48:54Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;Downloads&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Attach the image to a loop device and mount the root partition.&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find the first available loop device&lt;br /&gt;
doas losetup --find&lt;br /&gt;
&lt;br /&gt;
# Assuming the first found available device is /dev/loop0&lt;br /&gt;
doas losetup -P /dev/loop0 Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# Mount the root slice&lt;br /&gt;
doas mount /dev/loop0p1 /mnt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Archive the vendor kernel&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
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&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
You probably want to put the resulting archive in a safer place than /var/tmp at this point.  There&#039;s a bit to do before we&#039;ll need it.}}&lt;br /&gt;
&lt;br /&gt;
Unmount and detach the vendor image&lt;br /&gt;
&amp;lt;pre&amp;gt;cd -&lt;br /&gt;
doas umount /mnt&lt;br /&gt;
doas losetup -d /dev/loop0&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32283</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32283"/>
		<updated>2026-04-10T03:24:17Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
This guide was assembled as a dumping of my personal notes.  It&#039;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&#039;s enough information here to get you going.&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32282</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32282"/>
		<updated>2026-04-10T03:16:24Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Some kernel sources have an issue with starting the framebuffer&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
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. &lt;br /&gt;
 &lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
There have been 2 main repositories for patched kernel sources.&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/jasonmontleon/linux-spacemit jasonmontleon/linux-spacemit]&lt;br /&gt;
* [https://github.com/BredOS/linux-bredos BredOS/linux-bredos]&lt;br /&gt;
&lt;br /&gt;
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&#039;ve learned to assemble this guide is attributed to these projects.&lt;br /&gt;
&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32281</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32281"/>
		<updated>2026-04-10T02:57:52Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaining the Vendor kernel ===&lt;br /&gt;
Open a browser to the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePI RV2 Download] page.&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
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.&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
===== Add esos.elf to mkinitfs/features.d/base.files =====&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/esos.elf&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add the wireless-regdb database files to base.files =====&lt;br /&gt;
{{Note|&lt;br /&gt;
You may not need this.  If you see a kernel message regarding failure to load regulatory.db with error -2, this will resolve it}}&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/lib/firmware/regulatory.*&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/base.files&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Add jdb2 to ext4 =====&lt;br /&gt;
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&#039;re using the Alpine provided kernel then you&#039;ll need this on the initramfs.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;kernel/fs/jbd2&amp;quot; &amp;gt;&amp;gt; /etc/mkinitfs/features.d/ext4.modules&amp;lt;/pre&amp;gt;&lt;br /&gt;
===== Prevent mkinitfs from deleting needed firmware =====&lt;br /&gt;
The mkinitfs script will delete a directory that shouldn&#039;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.&lt;br /&gt;
Make a copy of mkinitfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /sbin/mkinitfs /sbin/mkinitfs-rv2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the initfs_firmware function of &amp;lt;code&amp;gt;/sbin/mkinitfs-rv2&amp;lt;/code&amp;gt; you will find the following lines&lt;br /&gt;
&amp;lt;pre&amp;gt;        rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change them to be&lt;br /&gt;
&amp;lt;pre&amp;gt;        #rm -rf &amp;quot;$tmpdir&amp;quot;/lib/firmware&lt;br /&gt;
        [ ! -d &amp;quot;$tmpdir&amp;quot;/lib/firmware ] &amp;amp;&amp;amp; mkdir -p &amp;quot;$tmpdir&amp;quot;/lib/firmware&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using mkinitfs-rv2 to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32280</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32280"/>
		<updated>2026-04-10T02:11:24Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
== Kernel and Firmware ==&lt;br /&gt;
=== Obtaining the ESOS firmware ===&lt;br /&gt;
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 &amp;lt;code&amp;gt;esos.elf&amp;lt;/code&amp;gt;.  Keep the download in a safe place and also &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;/lib/firmware&amp;lt;/code&amp;gt; directory is also where you&#039;ll find this file within the vendor&#039;s image or an initrd image.&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
=== Obtaning the Vendor kernel ===&lt;br /&gt;
=== Will Alpine&#039;s kernel work? (TBD) ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Need to revisit this}}&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cat /mnt/etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils \&lt;br /&gt;
    mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab within the chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting up the boot environment ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Install the esos.elf firmware ===&lt;br /&gt;
=== Creating the initrd image ===&lt;br /&gt;
==== Configuring and fixing mkinitfs ====&lt;br /&gt;
==== Using mkinitfs to create an initrd image ====&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32279</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32279"/>
		<updated>2026-04-10T01:23:44Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* Wireless (Wi-Fi &amp;amp; Bluetooth) is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
== Obtaining a Kernel ==&lt;br /&gt;
=== Extracting the Vendor&#039;s kernel ===&lt;br /&gt;
=== Building from source ===&lt;br /&gt;
I may split this into a seperate article&lt;br /&gt;
==== Setting up a workspace ====&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
==== Cloning the source, configuring and building the kernel ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Riscv64&amp;diff=32278</id>
		<title>Riscv64</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Riscv64&amp;diff=32278"/>
		<updated>2026-04-10T01:16:15Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
{{Move|Running Alpine riscv64 in QEMU|Relocate this current page to one specific to QEMU.  This page would then become a list of articles related to installing Alpine Linux on specific RISCV66 hardware implementations.  The new location of this article would be listed on the new page.  A preview of the new page can be found [[Riscv64 Redo|here]]}}&lt;br /&gt;
riscv64 (RISC-V 64-bit) is one of the [[architecture|architectures]] that Alpine Linux supports. The first stable release was Alpine Linux 3.20. Standard ISO images are available since Alpine Linux 3.23. You can download it from the [https://alpinelinux.org/downloads/ Alpine Linux downloads] page.&lt;br /&gt;
&lt;br /&gt;
== Running Alpine riscv64 in QEMU ==&lt;br /&gt;
&lt;br /&gt;
=== Installing QEMU on Alpine ===&lt;br /&gt;
&lt;br /&gt;
Installing QEMU for RISC-V on Alpine is very straightforward:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# apk add qemu-system-riscv64 qemu-img}}&lt;br /&gt;
&lt;br /&gt;
You will need {{Pkg|qemu-img|arch=riscv64}} if you want to create QCOW2 disk images; if you only want to create raw images, it’s not needed.&lt;br /&gt;
&lt;br /&gt;
For example, to create a new 2&amp;amp;nbsp;GB QCOW2 disk image:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ qemu-img create -f qcow2 alpine-riscv64.qcow2 2G}}&lt;br /&gt;
&lt;br /&gt;
Adjust the &#039;&#039;size&#039;&#039; parameter as you see fit.&lt;br /&gt;
&lt;br /&gt;
=== Getting U-Boot ===&lt;br /&gt;
&lt;br /&gt;
[https://u-boot.org/ U-Boot], aka &#039;&#039;Das U-Boot: The Universal Boot Loader&#039;&#039;, is one of the easiest, most flexible ways to boot Alpine on RISC-V. It can be used with GRUB for EFI booting, or with &amp;lt;code&amp;gt;extlinux.conf&amp;lt;/code&amp;gt; for non-EFI booting.&lt;br /&gt;
&lt;br /&gt;
You need the file &#039;&#039;&#039;&amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt;&#039;&#039;&#039; to boot using U-Boot. Alpine provides a compiled &amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt; in two places:&lt;br /&gt;
&lt;br /&gt;
# The &#039;&#039;&#039;Generic U-Boot tarball&#039;&#039;&#039; on the [https://alpinelinux.org/downloads/ Alpine downloads page]. Currently that is:&lt;br /&gt;
#:https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/riscv64/alpine-uboot-3.23.3-riscv64.tar.gz&lt;br /&gt;
# The &#039;&#039;&#039;[https://pkgs.alpinelinux.org/package/edge/main/riscv64/u-boot-qemu &amp;lt;code&amp;gt;u-boot-qemu&amp;lt;/code&amp;gt; package for &amp;lt;code&amp;gt;riscv64&amp;lt;/code&amp;gt;]&#039;&#039;&#039;. Note that if you are not already on an Alpine riscv64 system, you won’t be able to just &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; this package, as it will be for a different architecture. In practical terms this means downloading the &amp;lt;code&amp;gt;.apk&amp;lt;/code&amp;gt; file directly from an APK mirror, e.g.:&lt;br /&gt;
#:https://dl-cdn.alpinelinux.org/edge/main/riscv64/u-boot-qemu-2026.01-r0.apk&lt;br /&gt;
&lt;br /&gt;
If you downloaded the &amp;lt;code&amp;gt;.tgz&amp;lt;/code&amp;gt; file, this command will extract the &amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt; file to the current directory:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ tar --strip-components 3 -xf alpine-uboot-3.23.3-riscv64.tar.gz \&lt;br /&gt;
    ./u-boot/qemu-riscv64_smode/u-boot.bin}}&lt;br /&gt;
&lt;br /&gt;
If you downloaded the &amp;lt;code&amp;gt;.apk&amp;lt;/code&amp;gt; file, this command will extract the &amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt; file to the current directory:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ tar --strip-components 4 -xf u-boot-qemu-2026.01-r0.apk \&lt;br /&gt;
    usr/share/u-boot/qemu-riscv64_smode/u-boot.bin}}&lt;br /&gt;
&lt;br /&gt;
{{Note|There are two &amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt; files, but you need the one in the &amp;lt;code&amp;gt;qemu-riscv64_smode&amp;lt;/code&amp;gt; directory. That is because OpenSBI (the first thing QEMU executes) will run in &#039;&#039;M-mode&#039;&#039; (the highest privilege), which expects to execute U-Boot in &#039;&#039;S-mode&#039;&#039; (one privilege level lower).}}&lt;br /&gt;
&lt;br /&gt;
=== U-Boot + GRUB EFI ===&lt;br /&gt;
&lt;br /&gt;
The easiest way to run Alpine riscv64 in EFI mode is to boot from the ISO. You can download it from the [https://alpinelinux.org/downloads/ Alpine downloads page]. Here is an example of launching QEMU using U-Boot to boot this ISO:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ qemu-system-riscv64 -machine virt -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -kernel u-boot.bin \&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -drive file{{=}}alpine-standard-3.23.3-riscv64.iso,media{{=}}cdrom,if{{=}}none,id{{=}}cd0,readonly{{=}}on \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}cd0}}&lt;br /&gt;
&lt;br /&gt;
The boot path is therefore:&lt;br /&gt;
&lt;br /&gt;
    QEMU =&amp;gt; OpenSBI =&amp;gt; U-Boot =&amp;gt; GRUB EFI =&amp;gt; Linux&lt;br /&gt;
&lt;br /&gt;
Some explanatory notes about the command:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-nographic&amp;lt;/code&amp;gt; will select a serial console (rather than a graphical one).&lt;br /&gt;
* &amp;lt;code&amp;gt;-kernel u-boot.bin&amp;lt;/code&amp;gt; is what causes OpenSBI to load U-Boot.&lt;br /&gt;
* The &amp;lt;code&amp;gt;-netdev&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-device virtio-net-device&amp;lt;/code&amp;gt; lines set up &#039;&#039;user-mode networking&#039;&#039; with SSH port forwarding from the host:2222 to the guest:22.&lt;br /&gt;
* The ISO is being treated as a &amp;lt;code&amp;gt;virtio-blk-device&amp;lt;/code&amp;gt; rather than a real CD-ROM drive.&lt;br /&gt;
* After you’ve run &amp;lt;code&amp;gt;setup-alpine&amp;lt;/code&amp;gt;, you can remove the last two lines on subsequent launches so the ISO is no longer attached.&lt;br /&gt;
&lt;br /&gt;
It’s equally possible to boot using just the Generic U-Boot tarball. First, it needs to be fully extracted, &#039;&#039;except&#039;&#039; &amp;lt;code&amp;gt;extlinux.conf&amp;lt;/code&amp;gt;, which U-Boot will try to use first if present:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ mkdir alpine-uboot-3.23.3-riscv64&lt;br /&gt;
$ tar -C alpine-uboot-3.23.3-riscv64 --exclude ./extlinux/extlinux.conf \&lt;br /&gt;
    -xf alpine-uboot-3.23.3-riscv64.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
Then you can launch QEMU and have it emulate the &amp;lt;code&amp;gt;alpine-uboot-3.23.3-riscv64&amp;lt;/code&amp;gt; as a [https://www.qemu.org/docs/master/system/images.html#virtual-fat-disk-images Virtual FAT disk image]:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ qemu-system-riscv64 -machine virt -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -kernel u-boot.bin \&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -drive file{{=}}alpine-standard-3.23.3-riscv64.iso,media{{=}}cdrom,if{{=}}none,id{{=}}cd0,readonly{{=}}on \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd1}}&lt;br /&gt;
&lt;br /&gt;
This is nearly identical to the previous command, except the change from the ISO to the extracted tarball directory (&amp;lt;code&amp;gt;alpine-uboot-3.23.3-riscv64&amp;lt;/code&amp;gt;). Note the &amp;lt;code&amp;gt;fat:ro:&amp;lt;/code&amp;gt; syntax to emulate a virtual hard drive from a directory on the host.&lt;br /&gt;
&lt;br /&gt;
=== U-Boot + extlinux.conf ===&lt;br /&gt;
&lt;br /&gt;
U-Boot can use &amp;lt;code&amp;gt;extlinux.conf&amp;lt;/code&amp;gt; to boot, which does not require EFI (and therefore does not use GRUB).&lt;br /&gt;
&lt;br /&gt;
The simplest way to boot without EFI is to use the Generic U-Boot tarball. In this case, it’s extracted without modification and booted as a [https://www.qemu.org/docs/master/system/images.html#virtual-fat-disk-images Virtual FAT disk image].&lt;br /&gt;
&lt;br /&gt;
First, extract the Generic U-Boot tarball:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ mkdir alpine-uboot-3.23.3-riscv64&lt;br /&gt;
$ tar -C alpine-uboot-3.23.3-riscv64 -xf alpine-uboot-3.23.3-riscv64.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
Then, launch QEMU:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ qemu-system-riscv64 -machine virt -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -kernel u-boot.bin \&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -drive file{{=}}fat:ro:alpine-uboot-3.23.3-riscv64,if{{=}}none,id{{=}}hd1,readonly{{=}}on \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd1}}&lt;br /&gt;
&lt;br /&gt;
{{Warning|A [https://lists.denx.de/pipermail/u-boot/2025-August/596500.html regression exists in U-Boot 2025.10], which is included with the Alpine 3.23 release, that may prevent booting via &amp;lt;code&amp;gt;extlinux.conf&amp;lt;/code&amp;gt;. The error will be similar to:&lt;br /&gt;
&lt;br /&gt;
    Failed to reserve memory for fdt at 0xbee9e220&lt;br /&gt;
    FDT creation failed! hanging...### ERROR ### Please RESET the board ###&lt;br /&gt;
&lt;br /&gt;
This has been [https://github.com/u-boot/u-boot/commit/62f1afbe7a8ae8f8b9e85c5ea4eb446b97892a7c resolved in U-Boot 2026.01].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; use the &amp;lt;code&amp;gt;u-boot.bin&amp;lt;/code&amp;gt; file from the Alpine Edge build of the {{Pkg|u-boot-qemu|arch=riscv64}} package, which will be U-Boot 2026.01 or later. See the &#039;&#039;[[#Getting_U-Boot|Getting U-Boot]]&#039;&#039; section for the URL and APK extraction instructions.}}&lt;br /&gt;
&lt;br /&gt;
The boot path is therefore:&lt;br /&gt;
&lt;br /&gt;
    QEMU =&amp;gt; OpenSBI =&amp;gt; U-Boot + extlinux.conf =&amp;gt; Linux&lt;br /&gt;
&lt;br /&gt;
Some explanatory notes about the command:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-nographic&amp;lt;/code&amp;gt; will select a serial console (rather than a graphical one).&lt;br /&gt;
* &amp;lt;code&amp;gt;-kernel u-boot.bin&amp;lt;/code&amp;gt; is what causes OpenSBI to load U-Boot.&lt;br /&gt;
* The &amp;lt;code&amp;gt;-netdev&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-device virtio-net-device&amp;lt;/code&amp;gt; lines set up &#039;&#039;user-mode networking&#039;&#039; with SSH port forwarding from the host:2222 to the guest:22.&lt;br /&gt;
* After you’ve run &amp;lt;code&amp;gt;setup-alpine&amp;lt;/code&amp;gt;, you can remove the last two lines on subsequent launches, so the virtual FAT disk image is no longer attached.&lt;br /&gt;
&lt;br /&gt;
{{Tip|You may see a usage message that begins like:&lt;br /&gt;
&lt;br /&gt;
    usage: /usr/sbin/update-u-boot [-b{{!}}--board &amp;lt;board-type&amp;gt;] [-d{{!}}--device &amp;lt;device&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
This is harmless. If it concerns you, it can be suppressed during the install by using the &amp;lt;code&amp;gt;BOOTLOADER&amp;lt;/code&amp;gt; environment variable:&lt;br /&gt;
&lt;br /&gt;
    {{Cmd|# BOOTLOADER{{=}}none setup-alpine}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
(While it is technically possible to install from the ISO using &amp;lt;code&amp;gt;extlinux.conf&amp;lt;/code&amp;gt;, doing so is more trouble than it’s worth, as you have to create a separate boot volume containing &amp;lt;code&amp;gt;/boot/vmlinuz-lts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/boot/initramfs-lts&amp;lt;/code&amp;gt; from the ISO, and &amp;lt;code&amp;gt;/extlinux/extlinux.conf&amp;lt;/code&amp;gt; from the Generic U-Boot tarball.)&lt;br /&gt;
&lt;br /&gt;
=== EDK2 + GRUB EFI ===&lt;br /&gt;
&lt;br /&gt;
Using EDK2 is convenient in that it comes bundled with {{Pkg|qemu-system-riscv64|arch=riscv64}}. However, it does require a few more QEMU options than U-Boot to work successfully.&lt;br /&gt;
&lt;br /&gt;
Here is an example using EDK2 to boot the Alpine riscv64 standard ISO:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ cp /usr/share/qemu/edk2-riscv-vars.fd .&lt;br /&gt;
$ qemu-system-riscv64 -machine virt,acpi{{=}}off -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -drive if{{=}}pflash,format{{=}}raw,unit{{=}}0,file{{=}}/usr/share/qemu/edk2-riscv-code.fd,readonly{{=}}on \&lt;br /&gt;
    -drive if{{=}}pflash,format{{=}}raw,unit{{=}}1,file{{=}}edk2-riscv-vars.fd \&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -drive file{{=}}alpine-standard-3.23.3-riscv64.iso,media{{=}}cdrom,if{{=}}none,id{{=}}cd0,readonly{{=}}on \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}cd0}}&lt;br /&gt;
&lt;br /&gt;
{{Warning|EDK2 will not boot the kernel without &amp;lt;code&amp;gt;acpi{{=}}off&amp;lt;/code&amp;gt;. It could be that the ACPI data QEMU is providing EDK2 is not compatible or accurate, somehow.}}&lt;br /&gt;
&lt;br /&gt;
The boot path is:&lt;br /&gt;
&lt;br /&gt;
    QEMU =&amp;gt; OpenSBI =&amp;gt; EDK2 =&amp;gt; GRUB EFI =&amp;gt; Linux&lt;br /&gt;
&lt;br /&gt;
Some explanatory notes about the command:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-nographic&amp;lt;/code&amp;gt; will select a serial console (rather than a graphical one).&lt;br /&gt;
* The two &amp;lt;code&amp;gt;pflash&amp;lt;/code&amp;gt; lines load two files:&lt;br /&gt;
** the EDK2 &#039;&#039;code&#039;&#039; in &amp;lt;code&amp;gt;readonly&amp;lt;/code&amp;gt; mode.&lt;br /&gt;
** the EDK2 &#039;&#039;vars&#039;&#039; (EDK2’s nvram, essentially) in a writable way.&lt;br /&gt;
**:(EDK2 doesn’t load via &amp;lt;code&amp;gt;-kernel&amp;lt;/code&amp;gt;, unlike U-Boot.)&lt;br /&gt;
* The &amp;lt;code&amp;gt;-netdev&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-device virtio-net-device&amp;lt;/code&amp;gt; lines set up &#039;&#039;user-mode networking&#039;&#039; with SSH port forwarding from the host:2222 to the guest:22.&lt;br /&gt;
* After you’ve run &amp;lt;code&amp;gt;setup-alpine&amp;lt;/code&amp;gt;, you can remove the last two lines on subsequent launches, so the virtual FAT disk image is no longer attached.&lt;br /&gt;
&lt;br /&gt;
{{Tip|EDK2 produces &#039;&#039;voluminous&#039;&#039; output before the Linux kernel starts. This is expected, even if seemingly abnormal.}}&lt;br /&gt;
&lt;br /&gt;
=== Direct booting ===&lt;br /&gt;
&lt;br /&gt;
“Direct” booting means using QEMU to load the kernel and initramfs files into memory and having OpenSBI boot them directly, bypassing any other bootloader such as U-Boot, EDK2, GRUB, etc. This is a very fast method of booting, but there are some points to consider:&lt;br /&gt;
&lt;br /&gt;
* You will have to somehow get the kernel and initramfs onto the host system. During installation, this is straightforward enough: you can extract them out of the installation media. But for subsequent boots (ie, after &amp;lt;code&amp;gt;apk upgrade&amp;lt;/code&amp;gt; has changed the kernel or initramfs in the guest), this becomes more challenging.&lt;br /&gt;
* Reboots will not use a new kernel from within the guest (ie, one downloaded via &amp;lt;code&amp;gt;apk upgrade&amp;lt;/code&amp;gt;), but the one that was present on the host when QEMU was first launched. For this reason, it’s suggested that you use the &amp;lt;code&amp;gt;-noreboot&amp;lt;/code&amp;gt; QEMU option to prevent reboots.&lt;br /&gt;
* Because there is no bootloader to pass kernel options, you must specify &amp;lt;code&amp;gt;-append&amp;lt;/code&amp;gt; QEMU options instead. Fortunately these are rather standardized.&lt;br /&gt;
&lt;br /&gt;
The boot path for this method is simply:&lt;br /&gt;
&lt;br /&gt;
    QEMU =&amp;gt; OpenSBI =&amp;gt; Linux&lt;br /&gt;
&lt;br /&gt;
==== Extracting the images ====&lt;br /&gt;
&lt;br /&gt;
To make extracting the images easier, here is a shell function you can use. It uses 7-Zip, which you can install on Alpine with &amp;lt;code&amp;gt;apk add {{Pkg|7zip|arch=riscv64}}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Cat|extract.sh|extract_boot_images() {&lt;br /&gt;
    case &amp;quot;$1&amp;quot; in&lt;br /&gt;
        iso{{!}}tar)&lt;br /&gt;
            7z x -aoa &amp;quot;$2&amp;quot; boot/vmlinuz-lts boot/initramfs-lts&lt;br /&gt;
            ;;&lt;br /&gt;
        hdimg)&lt;br /&gt;
            7z x -aoa &amp;quot;$2&amp;quot; 0.img&lt;br /&gt;
            7z x -aoa 0.img -oboot vmlinuz-lts initramfs-lts&lt;br /&gt;
            rm -f 0.img&lt;br /&gt;
            ;;&lt;br /&gt;
    esac&lt;br /&gt;
    [ -f boot/vmlinuz-lts ] &amp;amp;&amp;amp; gunzip &amp;lt; boot/vmlinuz-lts &amp;gt; boot/vmlinux-lts&lt;br /&gt;
&amp;amp;#125;}}&lt;br /&gt;
&lt;br /&gt;
This function takes two arguments: the file type, &amp;lt;code&amp;gt;iso&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tar&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;hdimg&amp;lt;/code&amp;gt;, and the filename itself.&lt;br /&gt;
&lt;br /&gt;
For the Alpine ISO or Generic U-Boot tarball, the extraction is fairly straightforward. For hard drive images (either QCOW2 or raw), it will extract the first partition (which ought to be &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt;, ie, &amp;lt;code&amp;gt;/dev/vda1&amp;lt;/code&amp;gt;), and then extract the images from that. In both cases, it decompresses &amp;lt;code&amp;gt;vmlinuz-lts&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;vmlinux-lts&amp;lt;/code&amp;gt;, since it seems that OpenSBI wants an uncompressed kernel image.&lt;br /&gt;
&lt;br /&gt;
{{Note|If you extract the kernel and initramfs from the ISO, you should use the ISO to install; and similarly, if you extract them from the Generic U-Boot tarball, you should use the tarball to install.}}&lt;br /&gt;
&lt;br /&gt;
==== Install booting ====&lt;br /&gt;
&lt;br /&gt;
Here is an example QEMU command line for installation booting (first using the shell script above to extract the images):&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ . extract.sh&lt;br /&gt;
$ extract_boot_images iso alpine-standard-3.23.3-riscv64.iso&lt;br /&gt;
$ qemu-system-riscv64 -machine virt -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -kernel boot/vmlinux-lts \&lt;br /&gt;
    -initrd boot/initramfs-lts \&lt;br /&gt;
    -append &amp;quot;modules{{=}}loop,squashfs,sd-mod,usb-storage quiet&amp;quot; \&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -drive file{{=}}alpine-standard-3.23.3-riscv64.iso,media{{=}}cdrom,if{{=}}none,id{{=}}cd0,readonly{{=}}on \&lt;br /&gt;
    -device virtio-scsi-device,id{{=}}scsi0 \&lt;br /&gt;
    -device scsi-cd,drive{{=}}cd0,bus{{=}}scsi0.0 \&lt;br /&gt;
    -noreboot}}&lt;br /&gt;
&lt;br /&gt;
Some explanatory notes about the command:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-nographic&amp;lt;/code&amp;gt; will select a serial console (rather than a graphical one).&lt;br /&gt;
* The &amp;lt;code&amp;gt;-kernel&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-initrd&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;-append&amp;lt;/code&amp;gt; lines set up the kernel boot from files on the host. The &amp;lt;code&amp;gt;-append&amp;lt;/code&amp;gt; string is set up for booting from install media (the ISO or tarball).&lt;br /&gt;
* The &amp;lt;code&amp;gt;-netdev&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-device virtio-net-device&amp;lt;/code&amp;gt; lines set up &#039;&#039;user-mode networking&#039;&#039; with SSH port forwarding from the host:2222 to the guest:22.&lt;br /&gt;
* &amp;lt;code&amp;gt;-noreboot&amp;lt;/code&amp;gt; prevents the system from rebooting back into the installer. (You should change the command post installation so that subsequent launches boot from your hard drive image.)&lt;br /&gt;
&lt;br /&gt;
Run &amp;lt;code&amp;gt;setup-alpine&amp;lt;/code&amp;gt; as normal. It may attempt to install a bootloader, but it won’t be used.&lt;br /&gt;
&lt;br /&gt;
==== Normal booting ====&lt;br /&gt;
&lt;br /&gt;
After the installation, you can run a normal boot by extracting the kernel and initramfs out of the hard drive image you just created:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ . extract.sh&lt;br /&gt;
$ extract_boot_images hdimg alpine-riscv64.qcow2&lt;br /&gt;
$ qemu-system-riscv64 -machine virt -smp cores{{=}}2 -m 2G \&lt;br /&gt;
    -nographic \&lt;br /&gt;
    -kernel boot/vmlinux-lts \&lt;br /&gt;
    -initrd boot/initramfs-lts \&lt;br /&gt;
    -append &amp;quot;root{{=}}/dev/vda3 modules{{=}}sd-mod,usb-storage,ext4 quiet rootfstype{{=}}ext4&amp;quot;&lt;br /&gt;
    -device virtio-rng-device \&lt;br /&gt;
    -netdev user,hostfwd{{=}}tcp:127.0.0.1:2222-:22,id{{=}}n0 \&lt;br /&gt;
    -device virtio-net-device,netdev{{=}}n0 \&lt;br /&gt;
    -drive file{{=}}alpine-riscv64.qcow2,if{{=}}none,id{{=}}hd0 \&lt;br /&gt;
    -device virtio-blk-device,drive{{=}}hd0 \&lt;br /&gt;
    -noreboot}}&lt;br /&gt;
&lt;br /&gt;
The main difference here is in the image extraction (done using the hard drive image rather than the installation media) and in the &amp;lt;code&amp;gt;-append&amp;lt;/code&amp;gt; line, which specifies the virtio disk &amp;lt;code&amp;gt;/dev/vda3&amp;lt;/code&amp;gt; as the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Normally the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; parameter would be a UUID. If you prefer to use a UUID, you can grab it using a command like:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# blkid /dev/vda3}}&lt;br /&gt;
&lt;br /&gt;
And update your &amp;lt;code&amp;gt;-append&amp;lt;/code&amp;gt; parameter accordingly, e.g.:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|    -append &amp;quot;root{{=}}UUID{{=}}2341d7cd-e050-427e-afff-94fa0db4c8c5 modules{{=}}sd-mod,usb-storage,ext4 quiet rootfstype{{=}}ext4&amp;quot; \}}&lt;br /&gt;
&lt;br /&gt;
=== Using apk to create an image ===&lt;br /&gt;
&lt;br /&gt;
Yet another way to create a hard drive image for Alpine riscv64 would be with the help of an existing Alpine system (using any architecture, not just riscv64). Here are two articles that discuss this method:&lt;br /&gt;
&lt;br /&gt;
* [https://arvanta.net/alpine/install-alpine-riscv64-qemu/ install Alpine Linux riscv64 under qemu]&lt;br /&gt;
* [https://arvanta.net/alpine/install-alpine-riscv64-qemu-uboot/ install Alpine Linux riscv64 under qemu with u-boot loader]&lt;br /&gt;
&lt;br /&gt;
{{Note|These articles were created for a previous version of Alpine, and there may be differences in the way that a current &amp;lt;code&amp;gt;setup-alpine&amp;lt;/code&amp;gt; deploys a new system &#039;&#039;vs&#039;&#039; the result from these scripts. However, the techniques used are still sound and may be of interest.}}&lt;br /&gt;
&lt;br /&gt;
== Contribute ==&lt;br /&gt;
* Test out the port and [https://gitlab.alpinelinux.org/alpine/aports/-/issues/?label_name%5B%5D=arch%3Ariscv64 report] the bugs you find.&lt;br /&gt;
* Write and improve guides about the port.&lt;br /&gt;
* Fix [https://gitlab.alpinelinux.org/alpine/aports packages] that are buggy or don&#039;t work on RISC-V.&lt;br /&gt;
&#039;&#039;This section is based on [https://irclogs.alpinelinux.org/%23alpine-riscv64-2025-10.log this] [[Alpine Linux:IRC|IRC]] conversation from 2025-10-01.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32277</id>
		<title>Riscv64 Redo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32277"/>
		<updated>2026-04-10T01:10:32Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Move|Riscv64|A new main page for RISCV64 that links to articles regarding specific hardware implementations.  The current RISCV64 page would move to a QEMU specific one.}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[architecture|Architectures]] &amp;gt; Riscv64&lt;br /&gt;
&lt;br /&gt;
riscv64 (RISC-V 64-bit) is one of the [[architecture|architectures]] that Alpine Linux supports. The first stable release was Alpine Linux 3.20. Standard ISO images are available since Alpine Linux 3.23. You can download it from the [https://alpinelinux.org/downloads/ Alpine Linux downloads] page.&lt;br /&gt;
&lt;br /&gt;
RISC-V is an open source instruction set architecture (ISA) that was originally developed at UC Berkeley.  It&#039;s currently maintained by [https://riscv.org/ RISC-V International].  Organizations are allowed to implement the RISC-V ISA with their own custom extensions.  This results in their being some specificity to each implementation that makes it to market.  Below you&#039;ll find links to articles which detail how to get Alpine Linux running on your board or VM.&lt;br /&gt;
&lt;br /&gt;
== Alpine Linux on Specific RISC-V Implementations ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guides.  The following articles are 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.}}&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
== Contribute ==&lt;br /&gt;
* Test out the port and [https://gitlab.alpinelinux.org/alpine/aports/-/issues/?label_name%5B%5D=arch%3Ariscv64 report] the bugs you find.&lt;br /&gt;
* Write and improve guides about the port.&lt;br /&gt;
* Fix [https://gitlab.alpinelinux.org/alpine/aports packages] that are buggy or don&#039;t work on RISC-V.&lt;br /&gt;
&#039;&#039;This section is based on [https://irclogs.alpinelinux.org/%23alpine-riscv64-2025-10.log this] [[Alpine Linux:IRC|IRC]] conversation from 2025-10-01.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32268</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32268"/>
		<updated>2026-04-03T01:04:26Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nproc)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32255</id>
		<title>Riscv64 Redo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32255"/>
		<updated>2026-03-29T21:42:14Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[architecture|Architectures]] &amp;gt; Riscv64&lt;br /&gt;
&lt;br /&gt;
riscv64 (RISC-V 64-bit) is one of the [[architecture|architectures]] that Alpine Linux supports. The first stable release was Alpine Linux 3.20. Standard ISO images are available since Alpine Linux 3.23. You can download it from the [https://alpinelinux.org/downloads/ Alpine Linux downloads] page.&lt;br /&gt;
&lt;br /&gt;
RISC-V is an open source instruction set architecture (ISA) that was originally developed at UC Berkeley.  It&#039;s currently maintained by [https://riscv.org/ RISC-V International].  Organizations are allowed to implement the RISC-V ISA with their own custom extensions.  This results in their being some specificity to each implementation that makes it to market.  Below you&#039;ll find links to articles which detail how to get Alpine Linux running on your board or VM.&lt;br /&gt;
&lt;br /&gt;
== Alpine Linux on Specific RISC-V Implementations ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guides.  The following articles are 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.}}&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
== Contribute ==&lt;br /&gt;
* Test out the port and [https://gitlab.alpinelinux.org/alpine/aports/-/issues/?label_name%5B%5D=arch%3Ariscv64 report] the bugs you find.&lt;br /&gt;
* Write and improve guides about the port.&lt;br /&gt;
* Fix [https://gitlab.alpinelinux.org/alpine/aports packages] that are buggy or don&#039;t work on RISC-V.&lt;br /&gt;
&#039;&#039;This section is based on [https://irclogs.alpinelinux.org/%23alpine-riscv64-2025-10.log this] [[Alpine Linux:IRC|IRC]] conversation from 2025-10-01.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32254</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32254"/>
		<updated>2026-03-29T21:41:49Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
We&#039;re not gathering the vendor initrd image because it will try to launch systemd.  We will instead use mkinitfs to generate an Alpine based initrd.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32253</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32253"/>
		<updated>2026-03-29T21:30:29Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
We&#039;re not gathering the vendor initrd image because it will try to launch systemd.  We will instead use mkinitfs to generate an Alpine based initrd.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
&amp;lt;pre&amp;gt;sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32252</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32252"/>
		<updated>2026-03-29T21:29:49Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
We&#039;re not gathering the vendor initrd image because it will try to launch systemd.  We will instead use mkinitfs to generate an Alpine based initrd.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
sed -i &#039;s/^#ttyS0/ttyS0/&#039; /mnt/etc/inittab&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable login on UART ===&lt;br /&gt;
sed -i &#039;s/^#ttyS0/ttyS0/&#039; /etc/inittab&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32251</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32251"/>
		<updated>2026-03-29T21:23:36Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Cloning the source, configuring and building the kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
We&#039;re not gathering the vendor initrd image because it will try to launch systemd.  We will instead use mkinitfs to generate an Alpine based initrd.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32250</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32250"/>
		<updated>2026-03-29T21:21:34Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Extracting the vendor kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
We&#039;re not gathering the vendor initrd image because it will try to launch systemd.  We will instead use mkinitfs to generate an Alpine based initrd.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32249</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32249"/>
		<updated>2026-03-29T21:20:16Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Downloading and extracting the vendor kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32248</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32248"/>
		<updated>2026-03-29T21:19:34Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Alpine stock kernels do not work&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Downloading and extracting the vendor kernel ==&lt;br /&gt;
{{Note|&lt;br /&gt;
You may need to install losetup for this process to work}}&lt;br /&gt;
Follow the &#039;&#039;&#039;Ubuntu Image&#039;&#039;&#039; link on the [http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-RV2.html OrangePi RV2 Downloads] page.  Download Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.7z then extract the contents to /var/tmp. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Find a loop device&lt;br /&gt;
LOOPDEV=`losetup -f` &amp;amp;&amp;amp; echo $LOOPDEV&lt;br /&gt;
&lt;br /&gt;
# Attach the image file to the loop device&lt;br /&gt;
losetup -P ${LOOPDEV} /var/tmp/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63/Orangepirv2_1.0.0_ubuntu_noble_server_linux6.6.63.img&lt;br /&gt;
&lt;br /&gt;
# If this worked correctly, you should have only one partition on the loop device&lt;br /&gt;
ls ${LOOPDEV}*&lt;br /&gt;
/dev/loop0  /dev/loop0p1&lt;br /&gt;
&lt;br /&gt;
# Mount it and cd to the mount point&lt;br /&gt;
mount ${LOOPDEV}p1 /mnt &amp;amp;&amp;amp; cd /mnt&lt;br /&gt;
&lt;br /&gt;
# Create an archive of the required bits&lt;br /&gt;
tar cpzf /var/tmp/linux-6.6.63-ky.tgz lib/modules boot/dtb-6.6.63-ky boot/vmlinuz-6.6.63-ky boot/System.map-6.6.63-ky boot/config-6.6.63-ky&lt;br /&gt;
&lt;br /&gt;
# Unmount the loop device&lt;br /&gt;
umount /mnt&lt;br /&gt;
&lt;br /&gt;
# Detach the vendor image&lt;br /&gt;
losetup -d ${LOOPDEV}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32247</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32247"/>
		<updated>2026-03-29T20:48:57Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Cloning the source, configuring and building the kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warning|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32246</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32246"/>
		<updated>2026-03-29T20:48:44Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Cloning the source, configuring and building the kernel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
{{Warningg|&lt;br /&gt;
The kernel build is currently broken}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32245</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32245"/>
		<updated>2026-03-29T18:48:31Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Install Alpine from an non-Alpine host */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine RISC-V Linux host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32244</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32244"/>
		<updated>2026-03-29T17:59:03Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Setup fstab */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32243</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32243"/>
		<updated>2026-03-29T17:58:47Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Setup fstab */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
{{Note|&lt;br /&gt;
Found bug, Temporarily removed}}&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;# Backup the fstab even though only contains stock entries&lt;br /&gt;
cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
&lt;br /&gt;
# Create a working fstab file with an entry for the root device by UUID &lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the working fstab file with an entry for the boot device by UUID&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the stock entries from the original fstab to the working fstab&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Install the new fstab&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32242</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32242"/>
		<updated>2026-03-29T17:55:36Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Install Alpine with apk ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /mnt/etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;# Backup the fstab even though only contains stock entries&lt;br /&gt;
cp /mnt/etc/fstab /mnt/etc/fstab.orig&lt;br /&gt;
&lt;br /&gt;
# Create a working fstab file with an entry for the root device by UUID &lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the working fstab file with an entry for the boot device by UUID&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the stock entries from the original fstab to the working fstab&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /mnt/etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Install the new fstab&lt;br /&gt;
cp /mnt/etc/fstab.new /mnt/etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /mnt/etc/network ] mkdir -vp /mnt/etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd -R /mnt root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine host ==&lt;br /&gt;
&lt;br /&gt;
=== Download a minirootfs to run apk within a chroot ===&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup openrc services ===&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup fstab ===&lt;br /&gt;
&amp;lt;pre&amp;gt;# Backup the fstab even though only contains stock entries&lt;br /&gt;
cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
&lt;br /&gt;
# Create a working fstab file with an entry for the root device by UUID &lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the working fstab file with an entry for the boot device by UUID&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the stock entries from the original fstab to the working fstab&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Install the new fstab&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup networking ===&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set the root password ===&lt;br /&gt;
When the system boots it will require a root password.  This differs from Alpine install media but that&#039;s not the objective of this guide.  This guide is installing a ready system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;passwd&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel, configure extlinux ==&lt;br /&gt;
=== Install the kernel ===&lt;br /&gt;
=== Configure extlinux ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32235</id>
		<title>Riscv64 Redo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32235"/>
		<updated>2026-03-29T06:41:07Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[architecture|Architectures]] &amp;gt; Riscv64&lt;br /&gt;
&lt;br /&gt;
riscv64 (RISC-V 64-bit) is one of the [[architecture|architectures]] that Alpine Linux supports. The first stable release was Alpine Linux 3.20. Standard ISO images are available since Alpine Linux 3.23. You can download it from the [https://alpinelinux.org/downloads/ Alpine Linux downloads] page.&lt;br /&gt;
&lt;br /&gt;
RISC-V is an open source instruction set architecture (ISA) that was originally developed at UC Berkeley.  It&#039;s currently maintained by [https://riscv.org/ RISC-V International].  Organizations are allowed to implement the RISC-V ISA with their own custom extensions.  This results in their being some specificity to each implementation that makes it to market.  Below you&#039;ll find links to articles which detail how to get Alpine Linux running on your board or VM.&lt;br /&gt;
&lt;br /&gt;
== Alpine Linux on Specific RISC-V Implementations ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guides.  The following articles are provided as a general reference to be adapted to your specific setup.  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.}}&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
== Contribute ==&lt;br /&gt;
* Test out the port and [https://gitlab.alpinelinux.org/alpine/aports/-/issues/?label_name%5B%5D=arch%3Ariscv64 report] the bugs you find.&lt;br /&gt;
* Write and improve guides about the port.&lt;br /&gt;
* Fix [https://gitlab.alpinelinux.org/alpine/aports packages] that are buggy or don&#039;t work on RISC-V.&lt;br /&gt;
&#039;&#039;This section is based on [https://irclogs.alpinelinux.org/%23alpine-riscv64-2025-10.log this] [[Alpine Linux:IRC|IRC]] conversation from 2025-10-01.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User:Aarch0x40&amp;diff=32234</id>
		<title>User:Aarch0x40</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User:Aarch0x40&amp;diff=32234"/>
		<updated>2026-03-29T06:39:17Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Some things I&#039;m helping out with ==&lt;br /&gt;
* [[Riscv64]]&lt;br /&gt;
* [[Riscv64 Redo]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32233</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32233"/>
		<updated>2026-03-29T06:36:28Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine host ==&lt;br /&gt;
&lt;br /&gt;
Download a minirootfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup openrc services&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup fstab&lt;br /&gt;
&amp;lt;pre&amp;gt;# Backup the fstab even though only contains stock entries&lt;br /&gt;
cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
&lt;br /&gt;
# Create a working fstab file with an entry for the root device by UUID &lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the working fstab file with an entry for the boot device by UUID&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the stock entries from the original fstab to the working fstab&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Install the new fstab&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup networking&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel and configuring the bootloader ==&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32232</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32232"/>
		<updated>2026-03-29T06:35:54Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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 [[Risc64]] by [[User:AnIDFB]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert, partition and format the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If all looks good, then we can proceed with formatting the partitions&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;mkfs.ext4 /dev/sdb1 &amp;amp;&amp;amp; mkfs.ext4 /dev/sdb2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount the filesystems and lay some preliminary groundwork.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# Mount the target root slice&lt;br /&gt;
mount /dev/sdb2 /mnt&lt;br /&gt;
&lt;br /&gt;
# Create mount point for boot slice&lt;br /&gt;
[ ! -d /mnt/boot ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Mount boot slice&lt;br /&gt;
mount /dev/sdb1 /mnt/boot&lt;br /&gt;
&lt;br /&gt;
# Create directory for extlinux config&lt;br /&gt;
[ ! -d /mnt/boot/extlinux ] &amp;amp;&amp;amp; mkdir -vp /mnt/boot/extlinux&lt;br /&gt;
&lt;br /&gt;
# Create directory for apk config&lt;br /&gt;
[ ! -d /mnt/etc/apk ] &amp;amp;&amp;amp; mkdir -vp /mnt/etc/apk&lt;br /&gt;
&lt;br /&gt;
# Create mount point for devfs&lt;br /&gt;
[ ! -d /mnt/dev ] &amp;amp;&amp;amp; mkdir -vp /mnt/dev&lt;br /&gt;
&lt;br /&gt;
# Create mount point for procfs&lt;br /&gt;
[ ! -d /mnt/proc ] &amp;amp;&amp;amp; mkdir -vp /mnt/proc&lt;br /&gt;
&lt;br /&gt;
# Create mount point for sysfs&lt;br /&gt;
[ ! -d /mnt/sys ] &amp;amp;&amp;amp; mkdir -vp /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Use bind mounts for dev proc and sys within the target device&lt;br /&gt;
mount -o bind /dev /mnt/dev &amp;amp;&amp;amp; mount -o bind /proc /mnt/proc &amp;amp;&amp;amp; mount -o bind /sys /mnt/sys&lt;br /&gt;
&lt;br /&gt;
# Configure apk package manager&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /mnt/etc/apk/repositories&lt;br /&gt;
#/media/vda1/apks&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
http://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Install Alpine from an Alpine host ==&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;apk --root /mnt --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install Alpine from an non-Alpine host ==&lt;br /&gt;
&lt;br /&gt;
Download a minirootfs&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /var/tmp&lt;br /&gt;
wget https://dl-cdn.alpinelinux.org/edge/releases/riscv64/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unzip in /mnt&lt;br /&gt;
&amp;lt;pre&amp;gt;cd /mnt&lt;br /&gt;
tar xfpz /var/tmp/alpine-minirootfs-20260127-riscv64.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&lt;br /&gt;
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}}&lt;br /&gt;
Chroot into /mnt and run &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /mnt /bin/sh&lt;br /&gt;
apk --arch riscv64 --allow-untrusted --initdb add \&lt;br /&gt;
    alpine-base alpine-baselayout alpine-conf alpine-keys alpine-release alpine-baselayout-data \&lt;br /&gt;
    kmod openrc dbus util-linux blkid chrony sysfsutils ssl_client openssh ca-certificates-bundle \&lt;br /&gt;
    alpine-keys ethtool e2fsprogs e2fsprogs-extra libudev-zero libudev-zero-helper parted grep \&lt;br /&gt;
    busybox-mdev-openrc procps-ng net-tools coreutils doas sed gawk findutils bash shadow pciutils&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup openrc services&lt;br /&gt;
&amp;lt;pre&amp;gt;for rc in boot/bootmisc boot/hostname boot/modules boot/sysctl boot/urandom boot/networking \&lt;br /&gt;
	sysinit/devfs sysinit/hwdrivers sysinit/mdev sysinit/modules \&lt;br /&gt;
	shutdown/mount-ro shutdown/killprocs \&lt;br /&gt;
	default/dbus default/networking default/chronyd default/local; do&lt;br /&gt;
	ln -s /etc/init.d/&amp;quot;${rc##*/}&amp;quot; /etc/runlevels/&amp;quot;$rc&amp;quot;&lt;br /&gt;
done&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup fstab&lt;br /&gt;
&amp;lt;pre&amp;gt;# Backup the fstab even though only contains stock entries&lt;br /&gt;
cp /etc/fstab /etc/fstab.orig&lt;br /&gt;
&lt;br /&gt;
# Create a working fstab file with an entry for the root device by UUID &lt;br /&gt;
echo $(blkid /dev/sdb2 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) / \ \ \ \ ext4 rw,relatime 0 1 &amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the working fstab file with an entry for the boot device by UUID&lt;br /&gt;
echo $(blkid /dev/sdb1 | sed &#039;s/.*: //;s/ .*//;s/&amp;quot;//g&#039;) /boot ext4 rw,relatime 0 2 &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Append the stock entries from the original fstab to the working fstab&lt;br /&gt;
cat /etc/fstab.orig &amp;gt;&amp;gt; /etc/fstab.new&lt;br /&gt;
&lt;br /&gt;
# Install the new fstab&lt;br /&gt;
cp /etc/fstab.new /etc/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setup networking&lt;br /&gt;
&amp;lt;pre&amp;gt;[ ! -d /etc/network ] mkdir -vp /etc/networking&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/network/interfaces&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
&lt;br /&gt;
EOF&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel and configuring the bootloader ==&lt;br /&gt;
&lt;br /&gt;
== Basic usability options ==&lt;br /&gt;
&lt;br /&gt;
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&#039;re still chroot /mnt or have booted the system.&lt;br /&gt;
&lt;br /&gt;
=== Add a local user for yourself with escalation privileges ===&lt;br /&gt;
&lt;br /&gt;
Create a user account for yourself with a secondary group of wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;# Create your account&lt;br /&gt;
useradd -G wheel -s /bin/bash -d /home/myuser -m -c &amp;quot;My User&amp;quot; myuser&lt;br /&gt;
# Set your password&lt;br /&gt;
passwd myuser&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a configuration to doas.d for group wheel&lt;br /&gt;
&amp;lt;pre&amp;gt;echo permit persist :wheel &amp;gt; /etc/doas.d/00-wheel.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install Avahi for mdns broadcasts ===&lt;br /&gt;
&lt;br /&gt;
Avahi can broadcast names for services provided by your host.  The default config in the Alpine package provides a configuration for sshd.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# First setup the hostname&lt;br /&gt;
setup-hostname myhost&lt;br /&gt;
&lt;br /&gt;
# Set the hostname&lt;br /&gt;
hostname `cat /etc/hostname`&lt;br /&gt;
&lt;br /&gt;
# Install the avahi apk&lt;br /&gt;
apk add avahi&lt;br /&gt;
&lt;br /&gt;
# Enable and start the avahi daemon&lt;br /&gt;
rc-update add avahi-daemon &amp;amp;&amp;amp; rc-service avahi-daemon start&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32231</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32231"/>
		<updated>2026-03-29T05:35:56Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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 [[Risc64]] by [[User:AnIDFB]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install parted package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add parted&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert and partition the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.  The following section requires a root shell.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;alias p=&amp;quot;parted -sa optimal /dev/sdb&amp;quot;&lt;br /&gt;
p mklabel gpt&lt;br /&gt;
p mkpart boot ext4 0G 512M&lt;br /&gt;
p set 1 boot&lt;br /&gt;
p mkpart root ext4 512M 100%&lt;br /&gt;
p p&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final command should produce output to confirm the result of the executed commands.  It should look something like the following.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Model: Generic STORAGE DEVICE (scsi)&lt;br /&gt;
Disk /dev/sdb: 15.5GB&lt;br /&gt;
Sector size (logical/physical): 512B/512B&lt;br /&gt;
Partition Table: gpt&lt;br /&gt;
Disk Flags: &lt;br /&gt;
&lt;br /&gt;
Number  Start   End     Size    File system  Name  Flags&lt;br /&gt;
 1      1049kB  512MB   511MB   ext4         boot  boot, esp&lt;br /&gt;
 2      512MB   15.5GB  15.0GB               root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel and configuring the bootloader ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32230</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32230"/>
		<updated>2026-03-29T05:11:39Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;extlinux/extlinux.conf&amp;lt;/code&amp;gt; which will be used to configure the boot process.&lt;br /&gt;
&lt;br /&gt;
Those following this guide may find it useful to have a USB UART serial cable available to debug kernel loading.&lt;br /&gt;
&lt;br /&gt;
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 [[Risc64]] by [[User:AnIDFB]].&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
* Need to explicitly disable the RealTek 8852BS module&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;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&lt;br /&gt;
&lt;br /&gt;
The following command will clone just the current HEAD of the patched repository&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --depth 1 https://github.com/jasonmontleon/linux-spacemit.git&lt;br /&gt;
cd linux-spacemit&lt;br /&gt;
make ARCH=riscv k1_defconfig&lt;br /&gt;
make -j$(nprocs)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
== Preparing the media ==&lt;br /&gt;
&lt;br /&gt;
=== Partition and setup the filesystems ===&lt;br /&gt;
==== Install the sgdisk package ====&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add sgdisk&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Insert and partition the boot media ====&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;code&amp;gt;/dev/sdb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Installing the kernel and configuring the bootloader ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32229</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32229"/>
		<updated>2026-03-29T04:02:36Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: /* Setting up a workspace */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;s still a bit of patchwork involved as not all support is upstreamed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32228</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32228"/>
		<updated>2026-03-29T04:01:11Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom built and manually installed kernel required&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;code&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/code&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirements but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Cloning the source, configuring and building the kernel ==&lt;br /&gt;
&lt;br /&gt;
Unfortunately the stock kernels provided by the Alpine Linux project and even the source tarballs from kernel.org will not work.  There&#039;s still a bit of patchwork involved as not all support is upstreamed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32227</id>
		<title>Riscv64 Redo</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Riscv64_Redo&amp;diff=32227"/>
		<updated>2026-03-29T03:43:54Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; Riscv64&lt;br /&gt;
&lt;br /&gt;
riscv64 (RISC-V 64-bit) is one of the [[architecture|architectures]] that Alpine Linux supports. The first stable release was Alpine Linux 3.20. Standard ISO images are available since Alpine Linux 3.23. You can download it from the [https://alpinelinux.org/downloads/ Alpine Linux downloads] page.&lt;br /&gt;
&lt;br /&gt;
RISC-V is an open source instruction set architecture (ISA) that was originally developed at UC Berkeley.  It&#039;s currently maintained by [https://riscv.org/ RISC-V International].  Organizations are allowed to implement the RISC-V ISA with their own custom extensions.  This results in their being some specificity to each implementation that makes it to market.  Below you&#039;ll find links to articles which detail how to get Alpine Linux running on your board or VM.&lt;br /&gt;
&lt;br /&gt;
== Alpine Linux on Specific RISC-V Implementations ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The contributors to the Alpine Linux project are not responsible for any damage/loss experienced by using the following guides.  The following articles are provided as a general reference to be adapted to your specific setup.  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.}}&lt;br /&gt;
* [[Riscv64|Running Alpine riscv64 in QEMU]]&lt;br /&gt;
* [[Installing Alpine Linux on OrangePi RV2]]&lt;br /&gt;
&lt;br /&gt;
== Contribute ==&lt;br /&gt;
* Test out the port and [https://gitlab.alpinelinux.org/alpine/aports/-/issues/?label_name%5B%5D=arch%3Ariscv64 report] the bugs you find.&lt;br /&gt;
* Write and improve guides about the port.&lt;br /&gt;
* Fix [https://gitlab.alpinelinux.org/alpine/aports packages] that are buggy or don&#039;t work on RISC-V.&lt;br /&gt;
&#039;&#039;This section is based on [https://irclogs.alpinelinux.org/%23alpine-riscv64-2025-10.log this] [[Alpine Linux:IRC|IRC]] conversation from 2025-10-01.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32226</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32226"/>
		<updated>2026-03-29T03:43:09Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
* Custom kernel build required&lt;br /&gt;
&lt;br /&gt;
== Setting up a workspace ==&lt;br /&gt;
&lt;br /&gt;
Begin by setting up a RISC-V workspace by following [[Riscv64|Running Alpine riscv64 in QEMU]].  You&#039;ll need to establish a build environment in this QEMU guest.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;code&amp;gt;doas apk add alpine-sdk bison flex openssl-dev ncurses ncurses-dev&amp;lt;/code&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Info|&amp;lt;code&amp;gt;ncurses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ncurses-dev&amp;lt;/code&amp;gt; aren&#039;t a hard requirement but are useful if you want to run &amp;lt;code&amp;gt;make menuconfig&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32225</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32225"/>
		<updated>2026-03-29T03:18:01Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Warning|The following are the issues that are known to exist between the result of this guide and the manufacturer provided image}}&lt;br /&gt;
&lt;br /&gt;
* The WiFi is not functional&lt;br /&gt;
* Manufacturer tools are not included&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32224</id>
		<title>Installing Alpine Linux on OrangePi RV2</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Installing_Alpine_Linux_on_OrangePi_RV2&amp;diff=32224"/>
		<updated>2026-03-29T03:07:30Z</updated>

		<summary type="html">&lt;p&gt;Aarch0x40: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Main Page]] &amp;gt; [[:Category:Architectures|Architectures]] &amp;gt; [[Riscv64]] &amp;gt; Installing Alpine Linux on OrangePi RV2&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
{{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 to be adapted to your specific setup.  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.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Riscv64]]&lt;/div&gt;</summary>
		<author><name>Aarch0x40</name></author>
	</entry>
</feed>