<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>kulesz.me</title>
    <link>/</link>
    <description>Recent content on kulesz.me</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <copyright>All product names and trademarks are the property of their respective owners. Unless stated otherwise, the textual content on kulesz.me created by the author is licensed under the Creative Commons Attribution - Share Alike 4.0 International License (CC-BY-SA 4.0) - see legal notice.</copyright>
    <lastBuildDate>Mon, 29 Dec 2025 01:43:02 +0000</lastBuildDate>
    
        <atom:link href="/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Recommended procedure for installing Debian GNU/Linux 13 (trixie) on ARM64-based machines</title>
      <link>/post/180-debian-trixie-sysvinit-arm64-install/</link>
      <pubDate>Mon, 29 Dec 2025 01:43:02 +0000</pubDate>
      
      <guid>/post/180-debian-trixie-sysvinit-arm64-install/</guid>
      <description>&lt;p&gt;If you want to run Linux on ARM64-based machines, Debian GNU/Linux is an excellent distribution choice.
Due to its universal concept, it works great on laptops, workstations and servers alike.
Unfortunately, Debian officially supports only a small number of ARM64-based machines.
Yet, you can run Debian unmodified on a lot more ARM64-based machines - if you manage to install it.
After discussing some basics and showing how to check the support status for a particular machine, this article describes my recommended way for performing the actual installation using a concrete example.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: This article is a major rewrite of my previous articles covering similar topics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;why-use-the-official-debian-distribution&#34;&gt;Why use the official Debian distribution?&lt;/h1&gt;
&lt;p&gt;Before we dwelve into details, let&amp;rsquo;s first discuss some basics.
I often hear the argument that people want to solve basic tasks like installing the OS as quickly as possible and focus on the more interesting activities in the layers above.
Usually, these people end up downloading and flashing one of the countless unofficial OS images from the Internet.
What&amp;rsquo;s wrong with that?&lt;/p&gt;
&lt;p&gt;Choosing a good base OS for your setup is the foundation for running a trustworthy and secure system.
While this might be irrelevant for a quick and dirty test setup, in case you want to run your system for years and put personal data on it, this aspect can be important.&lt;/p&gt;
&lt;p&gt;Personally, I discourage using unofficial images for a number of reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some unofficial images bundle additional software that is not packaged in the official repositores. Therefore, you never get updates for them. This is bad, especially for security-critical components such as the kernel.&lt;/li&gt;
&lt;li&gt;In addition to trusting the upstream project (such as Debian), you also have to trust the projects and individuals that built the images.&lt;/li&gt;
&lt;li&gt;Apart from trusting these third parties, you also have to trust their build infrastructure.&lt;/li&gt;
&lt;li&gt;Setting up the system yourself, you can optimize the setup to your needs from the very beginning.&lt;/li&gt;
&lt;li&gt;Upstream updates from Debian are more likely to break the system because Debian does not test new packages with the unofficial modifications applied.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other side, running an official distribution, you can be sure to get the best &amp;ldquo;vanilla&amp;rdquo; experience.
In addition, all the base software for your system comes from official sources and was build on their official infrastructure.&lt;/p&gt;
&lt;p&gt;However, not all boards are supported well in mainline linux. Hence, many unofficial Debian distributions (such as Armbian) provide patches that fix issues or add functionality. While this might seem nice to get a new board working, the patches require regular maintenance if they are not upstreamed. Hence, it can happen that certain boards will stop receiving kernel upgrades at some time. On the other hand, when using the official debian kernel, this is unlikely to happen.&lt;/p&gt;
&lt;h1 id=&#34;why-use-this-tutorial-instead-of-the-official-documentation&#34;&gt;Why use this tutorial instead of the official documentation?&lt;/h1&gt;
&lt;p&gt;You may wonder why I recommend following this tutorial instead of installing Debian on your machine using Debian&amp;rsquo;s official documentation.
Here are the arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My approach makes it possible to run the official and unmodified Debian versions on machines for which Debian does not provide official installation instructions (I refer to them using the term &amp;ldquo;unofficially supported machines&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;My approach uses the flash-friendly f2fs filesystem that greatly reduces wear of your flash memory and improves its performance while the official installer does not support f2fs.&lt;/li&gt;
&lt;li&gt;My approach replaces most parts of systemd with sysvinit (Devuan is still a better choice if you want to avoid systemd completely).&lt;/li&gt;
&lt;li&gt;My approach produces nice universal tar archives that can be used for installing Debian to more ARM64-based machines within minutes instead of going through the time-consuming installer process each time.&lt;/li&gt;
&lt;li&gt;My approach uses a modern extlinux configuration of the u-boot bootloader.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;unofficially-supported-machines&#34;&gt;Unofficially supported machines&lt;/h1&gt;
&lt;p&gt;The Linux kernel supports a variety of ARM64-based machines.
Unlike x86 machines, ARM64-based machines require a machine-specific device tree binary (dtb) that is built from source.
As Debian aims to be an universal OS, it ships a generic ARM64 kernel that enables support for as many of these machines as possible by shipping dozens of dtbs.&lt;/p&gt;
&lt;p&gt;The current Debian GNU/Linux 13 (trixie) release ships version 6.12 of the Linux kernel.
To look up the machines it theoretically supports, do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;visit to &lt;code&gt;packages.debian.org&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;use &amp;ldquo;search package directories&amp;rdquo; with &amp;ldquo;only show exact matches&amp;rdquo; and search for the package &lt;code&gt;linux-image-arm64&lt;/code&gt; in the stable distribution.&lt;/li&gt;
&lt;li&gt;hit the search button and click on the result.&lt;/li&gt;
&lt;li&gt;since &lt;code&gt;linux-image-arm64&lt;/code&gt; is a metapackage that depends on the current kernel, check which version it is (as of now, it is &lt;code&gt;linux-image-5.10.0-7-arm64&lt;/code&gt;). Click on this package to show more details.&lt;/li&gt;
&lt;li&gt;click on &amp;ldquo;list of files&amp;rdquo; to see all files contained in this actual kernel package and check the dtb files listed there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your machine is listed there, it is worth trying to run the official distribution of Debian on it.&lt;/p&gt;
&lt;p&gt;If your machine is not listed, don&amp;rsquo;t give up yet - it might still be supported by a newer Linux kernel.
Later in this tutorial, I will show how you can install a newer kernel in the current stable release and get regular updates for it.
However, this only works if your machine is supported at least in the &amp;ldquo;unstable&amp;rdquo; release.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry too much about the name &amp;ldquo;unstable&amp;rdquo; - the kernels in Debian unstable are based on well-tested kernels from stable releases by upstream and usually work well.
They are updated frequently and, thus, receive security updates.
While I consider them okay as a daily driver, they might not be as stable as the kernels from the stable distribution.
Also, you will be switched to newer kernels over time instead of receiving critical updates only.
Hence, I recommend only using the unstable kernels if your machine is not supported or does not work well with the stable kernel.&lt;/p&gt;
&lt;p&gt;To check if your machine has support in the unstable kernel, repeat the previous steps but choose &amp;ldquo;unstable&amp;rdquo; instead of &amp;ldquo;stable&amp;rdquo; for the distribution.
If your machine is still not listed, then you are out of luck for now as your machine is currently not supported (but it might get official support in the future).&lt;/p&gt;
&lt;p&gt;Here is a small list of machines I tried this approach on using the current 6.12 kernel and U-Boot 2025.10:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Manufacturer&lt;/th&gt;
          &lt;th&gt;Make/model&lt;/th&gt;
          &lt;th&gt;Remarks&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;FriendlyElec&lt;/td&gt;
          &lt;td&gt;NanoPi R2S&lt;/td&gt;
          &lt;td&gt;to be tested, worked partially in the past, not tested on Debian 13 yet (observed in Debian 11: incompatible with certain microSD cards, shutdown issues, only one NIC recognized ootb)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;A64 Plus&lt;/td&gt;
          &lt;td&gt;to be tested, worked great in the past, not tested on Debian 13 yet&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;A64 LTS (v1)&lt;/td&gt;
          &lt;td&gt;to be tested, worked great in the past, not tested on Debian 13 yet&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Rock64&lt;/td&gt;
          &lt;td&gt;Works very well&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;RockPro64&lt;/td&gt;
          &lt;td&gt;to be tested, worked mostly in the past, not tested on Debian 13 yet&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Pinebook Pro&lt;/td&gt;
          &lt;td&gt;to be tested, Worked partially in the past, not tested on Debian 13 yet (observed in Debian 11: booting off microSD cards fails, reboot issues, manual extra work needed)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;H64 Model B&lt;/td&gt;
          &lt;td&gt;Works well (entering disk encryption password does not work over serial)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Olimex&lt;/td&gt;
          &lt;td&gt;A64-OLinuXino&lt;/td&gt;
          &lt;td&gt;Works well (entering disk encryption password does not work over serial)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Xunlong&lt;/td&gt;
          &lt;td&gt;OrangePi Zero Plus&lt;/td&gt;
          &lt;td&gt;Worked partially in the past, not tested on Debian 13 yet (observed in Debian 11: NIC does not work, external USB NIC works fine)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;In the following, I will assume you want to install Debian GNU/Linux 13 on a Rock64 by Pine64.&lt;/p&gt;
&lt;h2 id=&#34;concept&#34;&gt;Concept&lt;/h2&gt;
&lt;p&gt;My installation concept covers the following stepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installing a device-independent base system using the official installer&lt;/li&gt;
&lt;li&gt;Customizing the base system&lt;/li&gt;
&lt;li&gt;Adapting the base system for the target&lt;/li&gt;
&lt;li&gt;creating tar archives for boot and root&lt;/li&gt;
&lt;li&gt;building the bootloader (device-specific)&lt;/li&gt;
&lt;li&gt;assembling a device-specific image&lt;/li&gt;
&lt;li&gt;flashing the assembled image&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This might seem a lot of work, but note that the firsttwo steps are device-independent.
Thus, you won&amp;rsquo;t have to redo them when installing other devices in the future.&lt;/p&gt;
&lt;h2 id=&#34;requirements-and-assumptions&#34;&gt;Requirements and assumptions&lt;/h2&gt;
&lt;p&gt;Apart from having an unofficially supported machine, I assume you have basic knowledge about the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creating and operating virtual machines with KVM/QEMU using virt-manager&lt;/li&gt;
&lt;li&gt;operating your ARM64 machine over the serial console&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, you will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a dedicated physical x86 machine with a fresh installation of Debian GNU/Linux 13 with at least 2 GiB of RAM and 20 GiB of storage&lt;/li&gt;
&lt;li&gt;a user account with a user named &lt;code&gt;youruser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;an empty microSD card with a capacity at least 4 GiB&lt;/li&gt;
&lt;li&gt;a working internet connection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, the tutorial should also work with other systems, distributions and environments but some steps may differ.
Also, note that using a VM is only possible if you enable nesting as we will exercise the ability to run ARM64-VMs ourselves.
Using very old hardware (e. g. a single-core 32bit machine) is theoretically possible but practically infeasible.&lt;/p&gt;
&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;step-1-installing-the-base-system&#34;&gt;Step 1: Installing the base system&lt;/h2&gt;
&lt;p&gt;First of all, let&amp;rsquo;s create a directory where we will store all the assets produced in this tutorial:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, download the netinst ISO for arm64 and verify its integrity, see here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure you also have qemu and virt-manager installed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install qemu-efi-aarch64 qemu-system-arm virt-manager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a new virtual machine using the aarch64 architecture as shown here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen010.png&#34; alt=&#34;screen010&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the next step, choose the netinst image you downloaded previously as ISO and select &amp;ldquo;Debian 13&amp;rdquo; as OS.
Give the VM the 768 MiB of RAM (the installer crashed for me with just 512 MiB) and as many cores as you have.
Next, create a disk image with at least 5 GiB (or stick with the default) and leave the default network settings (using NAT).
Finally, fire up your new VM.
You should get a screen like mine:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen020.png&#34; alt=&#34;screen020&#34;&gt;&lt;/p&gt;
&lt;p&gt;After selecting the first option, the &amp;ldquo;oldschool&amp;rdquo; text installer should boot and give you the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen025.png&#34; alt=&#34;screen025&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now run through the installer but follow these guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;choose a generic hostname and domain name (we want to build a generic, reuseable image)&lt;/li&gt;
&lt;li&gt;choose simple passwords for root and the user you create (again, we want to build a generic image)&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;deb.debian.org&lt;/code&gt; as pkg mirror&lt;/li&gt;
&lt;li&gt;partition the disk to have the following layout (watch my &lt;a href=&#34;../160-debian-bullseye-sysvinit-arm64-install/partitioning.webm&#34;&gt;old Debian 11 video&lt;/a&gt; for more details):
&lt;ul&gt;
&lt;li&gt;Partition #1: Size 100M, type ESP (EFI Firmware), no mountpoint, bootable, name &lt;code&gt;efi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Partition #2: Size 500M, type ext4, mountpoint &lt;code&gt;/boot&lt;/code&gt;, name &lt;code&gt;boot&lt;/code&gt;, label &lt;code&gt;boot&lt;/code&gt;, not bootable&lt;/li&gt;
&lt;li&gt;Partition #3: Size maximum, Type physical volume for encryption, name &lt;code&gt;rootencrypted&lt;/code&gt; no mountpoint, not bootable&lt;/li&gt;
&lt;li&gt;Inside the encrypted volume, create a single ext4 partition spanning the whole outside partition with type ext4 and mountpoint &lt;code&gt;/&lt;/code&gt;, name &lt;code&gt;root&lt;/code&gt;, label &lt;code&gt;root&lt;/code&gt;, passphrase &lt;code&gt;abcd&lt;/code&gt; (this will ease further setup)&lt;/li&gt;
&lt;li&gt;no swap&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;when installing packages, unselect all packages for installation in tasksel (our aim is to get a minimal image, we will install specific packages later as we need them).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Don&amp;rsquo;t be confused that the installer will display the crypto device being named &lt;code&gt;vda3_crypt&lt;/code&gt; or similar - that&amp;rsquo;s just the name of crypto device but not the partition label!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apart from the security benefit, an additional advantage of using encryption is that we do not risk data loss from accidentally powering on one of our real devices later as no filesystem is mounted r/w before the password was entered correctly.&lt;/p&gt;
&lt;p&gt;After installing, the system should starting booting up but get stuck with &amp;ldquo;Display output is not active&amp;rdquo;. Due to a regression, the password prompt is not shown in the graphical console, and also entering the password blindly is broken (it used to work Debian 11). Hence, switch to the serial console (View -&amp;gt; Consoles -&amp;gt; Serial 1) to enter it. We will do the rest of the setup from here.
Afterwards, a login shell should be presented. Login as root with the password you have set previously.&lt;/p&gt;
&lt;h2 id=&#34;step-2-customizing-the-base-system&#34;&gt;Step 2: Customizing the base system&lt;/h2&gt;
&lt;h3 id=&#34;sysvinit&#34;&gt;sysvinit&lt;/h3&gt;
&lt;p&gt;First, install sysvinit package and reboot (ignore the warning and error messages):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --allow-remove-essential systemd-sysv- sysvinit-core
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable the serial console (the virt target uses ttyAMA0, later at install time we will switch this to the device of your real hardware):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/inittab
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then reboot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the reboot, system bootup should look as follows:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;header.png&#34; alt=&#34;header&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now, we can remove more systemd bits by installing libpam-elogind:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install libpam-elogind 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;acpi&#34;&gt;ACPI&lt;/h3&gt;
&lt;p&gt;Install the acpi package for handling events such as button presses and sleep modes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install acpid
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;f2fs&#34;&gt;f2fs&lt;/h3&gt;
&lt;p&gt;While the installer does not support installing to f2fs filesystems, f2fs is the filesystem I recommend for flash media.
Add the module to /etc/initramfs-tools/modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;f2fs&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
echo &amp;quot;crc32&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install this package to get support for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install f2fs-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;time-synchronization&#34;&gt;Time synchronization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING: This part works but the daemon fails to synchronize the clock on boot and needs to be run manually. Any suggestions how to fix this are welcome.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most arm64 machine don&amp;rsquo;t have a backup battery for their realtime clock (RTC).
This results in the date and time being wrong each time you disconnect power.
In general, even if your machine has a backup battery, it is a good idea to setup time synchronization.&lt;/p&gt;
&lt;p&gt;Synchronizing date and time can be done using the NTP protocol.
Debian ships several NTP clients you can choose from.
Personally, I like OpenBSD&amp;rsquo;s openntpd as it is very lightweight and has been developed with security in mind.
To install it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install openntpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we want to set the date and time on each boot, change the following in &lt;code&gt;/etc/default/openntpd&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#DAEMON_OPTS=&amp;quot;-f /etc/openntpd/ntpd.conf&amp;quot;
DAEMON_OPTS=&amp;quot;-s -f /etc/openntpd/ntpd.conf&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should start and also run on the next boot. As we want to set the current time also now, restart it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service openntpd restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;dtb-file-handling&#34;&gt;DTB file handling&lt;/h3&gt;
&lt;p&gt;Since we want to use a separate &lt;code&gt;/boot&lt;/code&gt; partition later, we need to make sure the dtb files for the current kernel are there.
Therefore, we create a dtb directory there first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And add the following script that copies the dtb files automatically each time a new kernel is installed or upgraded:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/kernel/postinst.d/copy-dtbs
#!/bin/sh

set -e
version=&amp;quot;$1&amp;quot;

echo Copying current dtb files to /boot/dtbs....
cp -a /usr/lib/linux-image-${version}/. /boot/dtbs/
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s make this script executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /etc/kernel/postinst.d/copy-dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And run it once manually to copy the dtb files for the currently installed kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/kernel/postinst.d/copy-dtbs `uname -r`
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;bootloader-configuration&#34;&gt;Bootloader configuration&lt;/h3&gt;
&lt;p&gt;Create a directory to hold the bootloader configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/extlinux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And create an extlinux boot configuration file (the bootloader u-boot looks them up):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /boot/extlinux/extlinux.conf
TIMEOUT 2
PROMPT 1
DEFAULT debian

LABEL debian
MENU LABEL Linux debian
KERNEL /vmlinuz
INITRD /initrd.img
DEVICETREEDIR /dtbs
APPEND net.ifnames=0 root=LABEL=root cryptopts=source=LABEL=rootencrypted,target=root_crypt,luks
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;kernel-from-unstable-optional&#34;&gt;Kernel from unstable (optional)&lt;/h3&gt;
&lt;p&gt;As discussed previously, it might be necessary to run the kernel from the unstable distribution for certain machines to work better at all.
In addition, some board features might work better with kernels from unstable.
At the time of writing, kernel 6.17 is available in unstable while kernel 6.12 is in stable.&lt;/p&gt;
&lt;p&gt;Some people recommend installing kernels from backports instead of from unstable.
I discourage taking this approach as the kernels in backports often receive security updates quite late.&lt;/p&gt;
&lt;p&gt;So, which kernel should you choose if your board is supported in stable as well?
It depends.
The only advice I can give is: If all features of your board that are relevant to you work with the stable kernel, stick with it.
If not, try the unstable kernel.&lt;/p&gt;
&lt;p&gt;To install the unstable kernel, we need to first add the unstable distribution to apt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/sources.list.d/unstable.list
deb http://deb.debian.org/debian unstable main
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And specify that we only want to install the kernel from unstable (and no other packages):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/preferences.d/99unstable
# Never prefer packages from unstable
Package: *
Pin: release a=unstable
Pin-Priority: 100

# Allow upgrading kernel from unstable
Package: linux-image-arm64
Pin: release a=unstable
Pin-Priority: 500
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we can safely upgrade the kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update
apt install -t unstable linux-image-arm64
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;reboot&#34;&gt;Reboot&lt;/h3&gt;
&lt;p&gt;Before we continue to the next step, let&amp;rsquo;s reboot the system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-3-adapting-the-base-system-for-the-target&#34;&gt;Step 3: Adapting the base system for the target&lt;/h2&gt;
&lt;p&gt;The following changes are &amp;ldquo;devastating&amp;rdquo; and will make the VM unbootable or &amp;ldquo;less unique&amp;rdquo;.
Therefore, I recommend backing up its disk image before applying them (a snapshot would be even better, but KVM on Devuan3 does not seem to support them on aarch64).&lt;/p&gt;
&lt;h3 id=&#34;remove-grub&#34;&gt;Remove GRUB&lt;/h3&gt;
&lt;p&gt;Remove the grub bootloader (we will not use it - and yes you need to do it in this obscure way):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --allow-remove-essential grub-efi-arm64-signed- grub-common- libpam-elogind
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;ssh-servers-openssh-and-dropbear&#34;&gt;SSH servers (openssh and dropbear)&lt;/h3&gt;
&lt;p&gt;Install the regular OpenSSH server together with dropbear for unlocking the machine remotely during boot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --no-install-recommends openssh-server dropbear-initramfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the dropbear port so we don&amp;rsquo;t run into conflicts with the main server (I recommend using different SSH keys for the main and auxiliary SSH server) and add a timeout:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/dropbear/initramfs/dropbear.conf
DROPBEAR_OPTIONS=&amp;quot;-p 4748 -I 60&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an authorized-keys file that limits access to running the cryptsetup binary in dropbear (put your actual SSH public key here):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/dropbear/initramfs/authorized_keys
no-port-forwarding,no-agent-forwarding,no-x11-forwarding,command=&amp;quot;/usr/bin/cryptroot-unlock&amp;quot; ssh- ...
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To set a static IP address that usually works more reliable than DHCP (replace the placeholders):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/initramfs-tools/conf.d/staticip
IP=&amp;quot;&amp;lt;client-ip&amp;gt;::&amp;lt;gw-ip&amp;gt;:&amp;lt;netmask&amp;gt;::eth0:off&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, renegerate the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configure-the-network&#34;&gt;Configure the network&lt;/h3&gt;
&lt;p&gt;Since my setup is using the &amp;ldquo;old-style&amp;rdquo; interface names, you need to change the interface names in &lt;code&gt;/etc/network/interfaces&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use DHCP for the regular system either (recommended), make sure you edit &lt;code&gt;/etc/network/interfaces&lt;/code&gt; accordingly.
For instance, to have a static IP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# The primary network interface
allow-hotplug eth0
#iface eth0 inet dhcp
iface eth0 inet static
        address 192.168.2.11
        netmask 255.255.255.0
        gateway 192.168.2.1
        nameservers 192.168.2.1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;restrict-access-to-the-system&#34;&gt;Restrict access to the system&lt;/h3&gt;
&lt;p&gt;Delete the default user:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;userdel -r user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the keys authorized for dropbear for system access as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /root/.ssh
chmod 700 /root/.ssh
cp /etc/dropbear/initramfs/authorized_keys /root/.ssh/
chmod 600 /root/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards make sure you &lt;strong&gt;edit&lt;/strong&gt; the &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt; file to remove the restrictions (each line should start with &lt;code&gt;ssh-&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;replace-fstab-and-crypttab&#34;&gt;Replace fstab and crypttab&lt;/h3&gt;
&lt;p&gt;Replacing crypttab and fstab should be done as the last steps, otherwise regenerating initramfs might cause troubles.
Replace the fstab as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/fstab
# &amp;lt;file system&amp;gt;        &amp;lt;mount point&amp;gt;  &amp;lt;type&amp;gt;  &amp;lt;options&amp;gt;                   &amp;lt;dump&amp;gt;  &amp;lt;pass&amp;gt;
/dev/mapper/root_crypt /              f2fs    noatime,background_gc=off   0       1
LABEL=boot             /boot          ext4    errors=remount-ro           0       2
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To replace the crypttab file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/crypttab
root_crypt LABEL=&amp;quot;rootencrypted&amp;quot; none luks,initramfs
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, power down your VM:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;poweroff
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-4-creating-tar-archives&#34;&gt;Step 4: Creating tar archives&lt;/h2&gt;
&lt;p&gt;After tweaking the system to our needs, we want to create tar archives that will contain the contents that will be used for the boot and root partitions later.
To do this, we will mount the disk images of the VM directly on the host and extract the files from there.&lt;/p&gt;
&lt;p&gt;To extract the files from the VM, load the nbd module on your host.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;modprobe nbd max_part=8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the VM&amp;rsquo;s disk image (replace the path according to where you stored your virtual disk):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/debian-aarch64.qcow2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create mount points, decrypt and mount the partitions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /mnt/rootfs
mkdir /mnt/bootfs
mount /dev/nbd0p2 /mnt/bootfs
cryptsetup luksOpen /dev/nbd0p3 someroot
mount /dev/mapper/someroot /mnt/rootfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create tar archives and store them as our assets&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar cfvzp /home/youruser/assets/debian13-aarch64-bootfs.tar.gz -C /mnt/bootfs .
tar cfvzp /home/youruser/assets/debian13-aarch64-rootfs.tar.gz -C /mnt/rootfs .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, clean up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;umount /mnt/bootfs
umount /mnt/rootfs
cryptsetup luksClose /dev/mapper/someroot
qemu-nbd -d /dev/nbd0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-5-building-the-bootloader&#34;&gt;Step 5: Building the bootloader&lt;/h2&gt;
&lt;p&gt;We build u-boot on the host machine.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The process of building u-boot is machine-specific! This is just an example!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install device-tree-compiler build-essential gcc make git libssl-dev python3-dev bison flex bc libssl-dev make gcc gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf swig gnutls-dev gcc-aarch64-linux-gnu gcc-arm-none-eabi python3-setuptools python3-pyelftools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check the tags listed on this website to find out what the latest lts version of trusted-firmware-a is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clone the trusted-firmware-a source repository with that tag (in our case: `lts-v2.12.8):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone --depth=1 -b lts-v2.12.8  https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
cd trusted-firmware-a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compile the firmware:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3328 bl31
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set a variable pointing to the build artifact:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export BL31=${PWD}/build/rk3328/release/bl31/bl31.elf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave the build directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find the latest stable release of u-boot by inspecting their Git tags here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://source.denx.de/u-boot/u-boot/-/tags
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, clone this tag (in our case: `v2025.10) of the u-boot repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone --depth=1  -b v2025.10 git://git.denx.de/u-boot.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change into its directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd u-boot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create the configuration from the default config (again, adapt it if you have a different board):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- rock64-rk3328_defconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the build (change &lt;code&gt;-j16&lt;/code&gt; to match the number of your actual cpu threads):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -j4 CROSS_COMPILE=aarch64-linux-gnu-
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the assets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp idbloader.img /home/youruser/assets/
cp u-boot.itb /home/youruser/assets/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-6-installation--flashing&#34;&gt;Step 6: Installation / Flashing&lt;/h2&gt;
&lt;p&gt;With all goodies in place, we can now flash the contents to the storage of your machine. In the following we assume that your machine uses a microSD card for storage (such as the Rock64).&lt;/p&gt;
&lt;h3 id=&#34;partitioning&#34;&gt;Partitioning&lt;/h3&gt;
&lt;p&gt;As a friend of the KISS principle I recommend using a dead-simple MBR partitioning scheme instead of using GPT.&lt;/p&gt;
&lt;p&gt;First, change to our assets directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, insert your microSD card and check that is has been recognized:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the following, we assume that your device is recognized as &lt;code&gt;/dev/sdX&lt;/code&gt; (replace &lt;code&gt;/dev/sdX&lt;/code&gt; with the actual name of your device).&lt;/p&gt;
&lt;p&gt;Now, overwrite the first megabytes of the card with zeroes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/sdX bs=1M count=256
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, remove the microSD card and re-insert it so its partitioning information will be updated in your OS and check its assigned device name (could be the same as before, but could also be different):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create a template to hold our partition table (adjust the size of the boot partition if you have a bigger microSD card, but don&amp;rsquo;t make it too big):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;sfdisk.template
label: mbr
unit: sectors
first-lba: 64

start=        2048, size=       16384
start=       18432, size=      614400, bootable
start=      632832
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, apply the template to your microSD card:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/sbin/sfdisk /dev/sdX &amp;lt; sfdisk.template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now check dmesg again and make sure the three new partitions have been recognized (e. g. as &lt;code&gt;/dev/sdX1&lt;/code&gt;, &lt;code&gt;/dev/sdX2&lt;/code&gt; and &lt;code&gt;/dev/sdX3&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;filesystem-creation&#34;&gt;Filesystem creation&lt;/h3&gt;
&lt;p&gt;Now, create an ext4 filesystem to hold our boot partition (flash wear should not be an issue as normally no writes occur on &lt;code&gt;/boot&lt;/code&gt; during normal operation):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 -L boot /dev/sdX2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the root partition, we create an encrypted partition, unlock it, and format it using the f2fs filesystem with filesystem options recommended in the ArchLinux Wiki.
To make encryption more secure, calculate the value for &lt;code&gt;--pbkdf-memory&lt;/code&gt; by subtracting 64 MiB from the physical memory available on your target device. In our example, we would use &lt;code&gt;1984&lt;/code&gt; for our Rock64 that has 2 GiB of RAM.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksFormat /dev/sdX3 --label=rootencrypted --pbkdf-memory 1948
cryptsetup luksOpen /dev/sdX3 somename
mkfs.f2fs -O extra_attr,inode_checksum,sb_checksum -l root /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;mounting-filesystems-and-copying-files&#34;&gt;Mounting filesystems and copying files&lt;/h3&gt;
&lt;p&gt;Mount the partitions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /mnt/targetbootfs
mkdir -p /mnt/targetrootfs
mount /dev/sdX2 /mnt/targetbootfs
mount /dev/mapper/somename /mnt/targetrootfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Extract the archives:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar xzvpf /home/youruser/assets/debian13-aarch64-bootfs.tar.gz -C /mnt/targetbootfs/.
tar xzvpf /home/youruser/assets/debian13-aarch64-rootfs.tar.gz -C /mnt/targetrootfs/.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;device-specific-adjustments&#34;&gt;Device-specific adjustments&lt;/h3&gt;
&lt;p&gt;Next, adjust the settings for the serial console. To do that, edit the file &lt;code&gt;/mnt/etc/inittab&lt;/code&gt; and adjust the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This setting is not machine-specific but chipset-specific. Below are some examples for common SoCs:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;SoC&lt;/th&gt;
          &lt;th&gt;serial device&lt;/th&gt;
          &lt;th&gt;Baud rate&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Rockchip RK3328, RK3399&lt;/td&gt;
          &lt;td&gt;/dev/ttyS2&lt;/td&gt;
          &lt;td&gt;1500000&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Allwinner A64, H5, H6&lt;/td&gt;
          &lt;td&gt;/dev/ttyS0&lt;/td&gt;
          &lt;td&gt;115200&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Hence, for the Rock64, the serial device is &lt;code&gt;ttyS2&lt;/code&gt; (not &lt;code&gt;ttyAMA0&lt;/code&gt;) and it uses a baud rate of &lt;code&gt;15000000&lt;/code&gt; (not &lt;code&gt;115200&lt;/code&gt;).
Again, other boards may need different settings.&lt;/p&gt;
&lt;p&gt;So, in our case, change the line as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyS2 1500000 vt100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some devices (e. g. the A64-OLinuXino) require a different DTB file than the one included in the Debian kernel package. In this case, overwrite the existing dtb file in the bootfs partition (replace &lt;code&gt;&amp;lt;platform&amp;gt;&lt;/code&gt; by your actual platform).
Make sure you prevent your dtb file from being overwritten by kernel upgrades. Thus, once you booted the final system, adapt the file &lt;code&gt;/etc/kernel/postinst.d/copy-dtbs&lt;/code&gt; accordingly. To copy the dtb file once:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /path/to/your/special/dtb-file /mnt/dtbs/&amp;lt;platform&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;unmounting-and-cleanup&#34;&gt;Unmounting and cleanup&lt;/h3&gt;
&lt;p&gt;Sync and unmount the filesystems:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sync
umount /mnt/targetbootfs
umount /mnt/targetrootfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Close the crypto device:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksClose /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;flash-bootloader&#34;&gt;Flash bootloader&lt;/h3&gt;
&lt;p&gt;As the last step, we need to write the bootloader to the device.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: This procedure is SoC-specific! Other SoCs require different commands!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For our Rock64. do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=idbloader.img of=/dev/sdX seek=64 conv=notrunc
dd if=u-boot.itb of=/dev/sdX seek=16384 conv=notrunc
sync
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-7-first-boot&#34;&gt;Step 7: First boot&lt;/h2&gt;
&lt;h3 id=&#34;bootup-and-first-changes&#34;&gt;Bootup and first changes&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s it! Hook up the serial console to your board, put in the microSD card and enjoy.&lt;/p&gt;
&lt;p&gt;After bootup, I recommend to renegerate the SSH keys as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm -v /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
rm /etc/dropbear/initramfs/*_key
dpkg-reconfigure dropbear-initramfs
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;device-specific-notes&#34;&gt;Device-specific notes&lt;/h1&gt;
&lt;h2 id=&#34;pinebook-pro&#34;&gt;Pinebook Pro&lt;/h2&gt;
&lt;p&gt;(under construction)&lt;/p&gt;
&lt;h2 id=&#34;other-devices&#34;&gt;Other devices&lt;/h2&gt;
&lt;p&gt;(under construction)&lt;/p&gt;
&lt;h1 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h1&gt;
&lt;p&gt;(under construction)&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;(none yet)&lt;/p&gt;
&lt;h1 id=&#34;credits&#34;&gt;Credits&lt;/h1&gt;
&lt;p&gt;I would like to thank all the helpful minds that shared feedback on previous versions of this concept for prior Debian/Devuan versions.&lt;/p&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2025-12-20] Initial major rewrite for Debian 13 (based on earlier articles, see its changelog for details on past changes)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Coming soon&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>OsmAnd via Android Auto - a practical and privacy-friendly offline navigation solution?</title>
      <link>/post/170_osmand_auto/</link>
      <pubDate>Mon, 15 Aug 2022 15:40:02 +0000</pubDate>
      
      <guid>/post/170_osmand_auto/</guid>
      <description>&lt;p&gt;Modern cars are equipped with headunits that support Android Auto or Apple Carplay. With the recently added support for Android Auto in OsmAnd - an established open source offline maps and navigation app - my hope for a privacy-friendly solution was reawaken. Hence, I investigated whether it was practically possible to use use this combination in a data-literate way. I stumbled over several caveats and irritating privacy-invasive issues but also found a semi-satifactionary workaround for the time being.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h1 id=&#34;targeted-audience&#34;&gt;Targeted audience&lt;/h1&gt;
&lt;p&gt;If you are a person that has a stock Android smartphone with the preinstalled Google Apps and services running and is comfortable with this setup this article is NOT for you.
On the other hand, if you use a custom Android Distribution such as LineageOS, GrapheneOS or Replicant or even a &amp;ldquo;true&amp;rdquo; Linux Mobile system such as postmarketOS, Mobian or Ubuntu Touch you are part of the targeted audience.
Generally, I assume that readers of this article are data-literate, care about their privacy and want to effectively stay in control with whom they share which data.&lt;/p&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;All data and information provided in this article is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this article and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/p&gt;
&lt;p&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this article.&lt;/p&gt;
&lt;h1 id=&#34;caveat-1-google-apps-gapps-required&#34;&gt;Caveat #1: Google Apps (&amp;ldquo;gapps&amp;rdquo;) required&lt;/h1&gt;
&lt;p&gt;The first surprise for newcomers is that you can&amp;rsquo;t use Android Auto with a &amp;ldquo;free&amp;rdquo; Android distribution that was built from the components of the Android Open Source Project (&amp;ldquo;AOSP&amp;rdquo;) such as LineageOS, GrapheneOS or Replicant.
Instead, Android Auto is part of the proprietary &amp;ldquo;gapps&amp;rdquo; framework and requires the installation of these proprietary components.
This is sad since the major motivation for many users of &amp;ldquo;free&amp;rdquo; Android distributions is to avoid the installation of proprietary components.&lt;/p&gt;
&lt;p&gt;The resulting practical consequence for a privacy-friendly setup is that a dedicated Android device solely for Android Auto needs to be used.
While not ideal, plugging in a second device and using it for navigation via the headunit is still much more convenient than using an external device.&lt;/p&gt;
&lt;p&gt;The additional Android device could be any stock Android device or a device running LineageOS plus &amp;ldquo;gapps&amp;rdquo;.
However, unless you don&amp;rsquo;t already own a device with an outdated Android version that does not support Android Auto at all, I don&amp;rsquo;t see many benefits of such an setup.
I rather find it legally and ethically problematic to install proprietary software from questionable sources on such a device.&lt;/p&gt;
&lt;p&gt;Another noteworthy issue is that not only Android Auto&amp;rsquo;s implementation but even the protocol is not open.
However, the protocol has been recently reverse-engineered by BlueWave Studio&amp;rsquo;s OpenAuto project [1].&lt;/p&gt;
&lt;h1 id=&#34;caveat-2-additional-playstore-only-apps-required&#34;&gt;Caveat #2: Additional &amp;ldquo;Playstore-only&amp;rdquo; apps required&lt;/h1&gt;
&lt;p&gt;In addition to the basic &amp;ldquo;gapps&amp;rdquo; framework, the installation of additional apps that are only available from the Google Play Store is required. These are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android Auto&lt;/li&gt;
&lt;li&gt;Google App&lt;/li&gt;
&lt;li&gt;Google Speech Services&lt;/li&gt;
&lt;li&gt;Google Maps (what an irony&amp;hellip;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While &amp;ldquo;Google App&amp;rdquo; is already part of gapps, it will likely need to be updated to match the version of Android Auto. Unless you install all these apps before connecting your device with your car, the Android device will tell you that it can&amp;rsquo;t work with your car until these dependencies are satisfied. For privacy reasons, you better don&amp;rsquo;t want to ever go online with your Android device after your device was in touch with your car so better install these requirements beforehand.&lt;/p&gt;
&lt;p&gt;So, the even bigger caveat here is that in order to use OsmAnd with Android Auto and need to have a Google Account to install these required apps.&lt;/p&gt;
&lt;p&gt;And yes - in theory, you probably could also download these apps from &amp;ldquo;alternative&amp;rdquo; stores such as those that use the API of the Google&amp;rsquo;s Playstore to fetch the apk files using fake accounts. However, you will very likely violate Google&amp;rsquo;s terms and conditions and, in addition, you will eventually even commit a copyright infringement by doing so. See [2] for a more detailed discussion about using such stores.&lt;/p&gt;
&lt;h1 id=&#34;caveat-3-no-hands-free-phone-calls-while-navigating&#34;&gt;Caveat #3: No hands-free phone calls while navigating&lt;/h1&gt;
&lt;p&gt;Maybe you already have a headunit in your car that allows you for hands-free calling using the built-in microphone and speakers over bluetooth?
Unless you do not give permission to your smartphone for syncing your contacts list and calling history with the headunit in your car, such a solution might seem privacy-wise acceptable.
Of course, you can never technically rule out that a head unit running proprietary software will not record the calling history or even your phone calls without your consent anyways.
However, this would be certainly illegal in the EU and, hance, it depends on your personal level of paranoia whether you consider this a viable threat.&lt;/p&gt;
&lt;p&gt;The more interesting question for me was whether you could navigate using OsmAnd via Android Auto and simultenously use hands-free calling to place or answer calls.
The very bad news here is - you can&amp;rsquo;t - at least for the head unit I tried with!
This is because Android Auto seems to use Bluetooth for Audio and assumes that you use the same device for calling as for phone calls.
You need to first disconnect the additional (dedicated) Android Auto device in order to be able to use hands-free phone calls again.&lt;/p&gt;
&lt;h1 id=&#34;caveat-4-tricky-initial-setup&#34;&gt;Caveat #4: Tricky initial setup&lt;/h1&gt;
&lt;p&gt;In order to replicate my setup you need to do the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get an Android device with gapps (I tested this using a device running Android 10 - be warned that Android 12 is known to have issues with OsmAnd and Android Auto at the time of writing).&lt;/li&gt;
&lt;li&gt;Install adb on your computer.&lt;/li&gt;
&lt;li&gt;Get access to the play store (create a Google Account).&lt;/li&gt;
&lt;li&gt;Download the required apps mentioned in the section &amp;ldquo;Caveat #2&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Optional: Unassociate the Google Account from your device and close the account.&lt;/li&gt;
&lt;li&gt;Download the apk file for OsmAnd from the F-Droid store (from the F-Droid website directly, not using the F-Droid App!)&lt;/li&gt;
&lt;li&gt;Enable developer mode and activate adb on your Android device&lt;/li&gt;
&lt;li&gt;Install the OsmAnd app using the adb workaround described below (otherwise the OsmAnd icon will be missing in Android Auto and you won&amp;rsquo;t be able to use it!).&lt;/li&gt;
&lt;li&gt;Start OsmAnd and download any maps and additional content (such as POIs) you require.&lt;/li&gt;
&lt;li&gt;Disable wifi on your device (ideally with kill switches or another effective airgap method)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Due to an issue discussed in [3], the OsmAnd app needs to be installed using the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb push net.osmand.plus_424.apk /data/local/tmp
adb shell pm install -i &amp;quot;com.android.vending&amp;quot; -r /data/local/tmp/net.osmand.plus_424.apk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, this initial setup requires some work. But believe me that finding out what needs to be done here was even more work. ;-)&lt;/p&gt;
&lt;h1 id=&#34;caveat-5-uncomfortable-updates&#34;&gt;Caveat #5: Uncomfortable updates&lt;/h1&gt;
&lt;p&gt;So far so good for the initial setup. But what to do for updating maps or adding POIs without the risk of data leaks?
Here are three suggestions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;download the updated content on another device (e. g. your main smartphone) and transfer the files manually over a wired connection (adb, rsync or friends)&lt;/li&gt;
&lt;li&gt;setup a firewall that only allows connections to map and POI providers and download the content with the Android device sitting behind this firewall.&lt;/li&gt;
&lt;li&gt;if you don&amp;rsquo;t update content frequently wipe the Android device and redo the initial setup (eventually in some scripted/automated way)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please let me know if you have any better suggestions!&lt;/p&gt;
&lt;h1 id=&#34;conclusion-and-future-perspectives&#34;&gt;Conclusion and future perspectives&lt;/h1&gt;
&lt;p&gt;I find it highly irritating that car drivers are virtually forced into signing a contract with Google just to be able to use a car&amp;rsquo;s head unit via Android Auto for a 3rd party navigation app that does not need any Google service at all.&lt;/p&gt;
&lt;p&gt;The described setup might seem like a messy and complicated workaround at first.
Yet it is the best privacy-friendly solution I am aware of for the time being.
I find this approach more convenient than attaching a second dedicated navigation system or using OsmAnd via some smartphone holder in the car instead of using the headunit which is actually there for this purpose.&lt;/p&gt;
&lt;p&gt;Of course, the described setup has several drawbacks, the biggest one proabably being the bluetooth issue.
To workaround the bluetooth issue, my recommendedation is to use the built-in hands-free calling when not navigating and to use an external bluetooth headset to cover the remaining situations.&lt;/p&gt;
&lt;p&gt;I looked for better alternatives and found the AACS project by by Tomasz [4] that reimplements Android Auto for native Linux. AACS allows you to display the output of a Linux machine on the headunit and process input from the headunit&amp;rsquo;s touchscreen. I haven&amp;rsquo;t tested this approach yet but it sounds very promising. I hope true Linux Mobile apps will provide such a facility ootb in the near future. Even though I am not aware of any equivalent alternative to OsmAnd for Linux mobile systems yet, running OsmAnd via anbox using AACS instead of proprietary Android Auto client on a native Android device sounds like a great step in the right direction.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;[1] &lt;a href=&#34;https://github.com/opencardev/openauto&#34;&gt;https://github.com/opencardev/openauto&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a href=&#34;https://mrdatenschutz.de/aurora-store-datenschutz-google-play-client-legal/&#34;&gt;https://mrdatenschutz.de/aurora-store-datenschutz-google-play-client-legal/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] &lt;a href=&#34;https://github.com/osmandapp/OsmAnd/issues/13514#issuecomment-1086203926&#34;&gt;https://github.com/osmandapp/OsmAnd/issues/13514#issuecomment-1086203926&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] &lt;a href=&#34;https://opensource.com/article/20/12/android-auto-open-source&#34;&gt;https://opensource.com/article/20/12/android-auto-open-source&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;credits&#34;&gt;Credits&lt;/h1&gt;
&lt;p&gt;(none yet)&lt;/p&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2022-08-15] Initial version&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Recommended procedure for installing Debian GNU/Linux 11 (bullseye) on ARM64-based machines</title>
      <link>/post/160-debian-bullseye-sysvinit-arm64-install/</link>
      <pubDate>Sat, 21 Aug 2021 16:30:02 +0000</pubDate>
      
      <guid>/post/160-debian-bullseye-sysvinit-arm64-install/</guid>
      <description>&lt;p&gt;If you want to run Linux on ARM64-based machines, Debian GNU/Linux is an excellent distribution choice.
Due to its universal concept, it works great on laptops, workstations and servers alike.
Unfortunately, Debian officially supports only a small number of ARM64-based machines (12 at the time of writing).
Yet, you can run Debian unmodified on a lot more ARM64-based machines - if you manage to install it.
After discussing some basics and showing how to check the support status for a particular machine, this article describes my recommended way for performing the actual installation using a concrete example.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: This article is a major rewrite of my previous articles covering similar topics. Apart from updating it for Debian GNU/Linux 11, I removed instructions for Devuan GNU+Linux to reduce the number of IFs and make the article simpler to follow (not because I discourage using Devuan GNU+Linux).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;why-use-official-distributions&#34;&gt;Why use official distributions?&lt;/h1&gt;
&lt;p&gt;Before we dwelve into details, let&amp;rsquo;s first discuss some basics.
I often hear the argument that people want to solve basic stuff like installing the OS as quickly as possible and focus on the more interesting stuff in the layers above.
Usually, these people end up downloading and flashing one of the countless unofficial OS images from the Internet.
What&amp;rsquo;s wrong with that?&lt;/p&gt;
&lt;p&gt;Choosing a good base OS for your setup is the foundation for running a trustworthy and secure system.
Sure, this might be irrelevant for a quick and dirty test setup.
However, if you want to run your system for years and put personal data on it, this aspect can be important.&lt;/p&gt;
&lt;p&gt;Personally, I discourage using unofficial images for a number of reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Many unofficial images bundle additional software that is not packaged in the official repositores. Therefore, you never get updates for them. This is bad, especially for security-critical components such as the kernel.&lt;/li&gt;
&lt;li&gt;In addition to trusting the upstream project (such as Debian), you also have to trust the projects and individuals that built the images.&lt;/li&gt;
&lt;li&gt;Apart from trusting these third parties, you also have to trust their build infrastructure.&lt;/li&gt;
&lt;li&gt;Setting up the system yourself, you can optimize the setup to your needs from the very beginning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other side, running an official distribution, you can be sure to get the best &amp;ldquo;vanilla&amp;rdquo; experience.
In addition, all the base software for your system comes from official sources and was build on their official infrastructure.&lt;/p&gt;
&lt;h1 id=&#34;why-use-this-tutorial-instead-of-the-official-documentation&#34;&gt;Why use this tutorial instead of the official documentation?&lt;/h1&gt;
&lt;p&gt;You may wonder why I recommend following this tutorial instead of installing Debian on your machine using Debian&amp;rsquo;s official documentation.
Here are the arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My approach makes it possible to run the official and unmodified Debian versions on machines for which Debian does not provide official installation instructions (I refer to them using the term &amp;ldquo;unofficially supported machines&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;My approach uses the flash-friendly f2fs filesystem that greatly reduces wear of your flash memory and improves its performance while the official installer does not support f2fs.&lt;/li&gt;
&lt;li&gt;My approach replaces most parts of systemd with sysvinit (Devuan is still a better choice if you want to avoid systemd completely).&lt;/li&gt;
&lt;li&gt;My approach produces nice universal tar archives that can be used for installing Debian to more ARM64-based machines within minutes instead of going through the time-consuming installer process each time.&lt;/li&gt;
&lt;li&gt;My approach uses the modern extlinux configuration of the u-boot bootloader (instead of the outdated binary format that is difficult to edit).&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;unofficially-supported-machines&#34;&gt;Unofficially supported machines&lt;/h1&gt;
&lt;p&gt;The Linux kernel supports a variety of ARM64-based machines.
Unlike x86 machines, ARM64-based machines require a machine-specific device tree binary (dtb) that is built from source.
As Debian aims to be an universal OS, it ships a generic ARM64 kernel that enables support for as many of these machines as possible by shipping dozens of dtbs.&lt;/p&gt;
&lt;p&gt;The current Debian GNU/Linux 11 (bullseye) release ships version 5.10 of the Linux kernel.
To look up the machines it theoretically supports, do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;visit to &lt;code&gt;packages.debian.org&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;use &amp;ldquo;search package directories&amp;rdquo; with &amp;ldquo;only show exact matches&amp;rdquo; and search for the package &lt;code&gt;linux-image-arm64&lt;/code&gt; in the stable distribution.&lt;/li&gt;
&lt;li&gt;hit the search button and click on the result.&lt;/li&gt;
&lt;li&gt;since &lt;code&gt;linux-image-arm64&lt;/code&gt; is a metapackage that depends on the current kernel, check which version it is (as of now, it is &lt;code&gt;linux-image-5.10.0-7-arm64&lt;/code&gt;). Click on this package to show more details.&lt;/li&gt;
&lt;li&gt;click on &amp;ldquo;list of files&amp;rdquo; to see all files contained in this actual kernel package and check the dtb files listed there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your machine is listed there, you might be able to run the official distribution of Debian on it.&lt;/p&gt;
&lt;p&gt;If your machine is not listed, don&amp;rsquo;t give up yet - it might still be supported by a newer Linux kernel.
Later in this tutorial, I will show how you can install a newer kernel in the current stable release and get regular updates for it.
However, this only works if your machine is supported at least in the &amp;ldquo;unstable&amp;rdquo; release.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry too much about the name &amp;ldquo;unstable&amp;rdquo; - the kernels in Debian unstable are based on well-tested kernels from upstream and usually work well.
They are updated frequently and, thus, receive security updates.
While I consider them okay as a daily driver, they are not as stable as the kernels from the stable distribution.&lt;/p&gt;
&lt;p&gt;To check if your machine has support in the unstable kernel, repeat the previous steps but choose &amp;ldquo;unstable&amp;rdquo; instead of &amp;ldquo;stable&amp;rdquo; for the distribution.
If your machine is still not listed, then you are out of luck for now as your machine is currently not supported (but it might get official support in the future).&lt;/p&gt;
&lt;p&gt;Here is a small list of machines I tried this approach on using the current 5.10 kernel and U-Boot 2021.XX:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Manufacturer&lt;/th&gt;
          &lt;th&gt;Make/model&lt;/th&gt;
          &lt;th&gt;Remarks&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Olimex&lt;/td&gt;
          &lt;td&gt;A64-OLinuXino&lt;/td&gt;
          &lt;td&gt;Works partially (entering disk encryption password does not work over serial)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Xunlong&lt;/td&gt;
          &lt;td&gt;OrangePi Zero Plus&lt;/td&gt;
          &lt;td&gt;Works partially (NIC does not work, external USB NIC works fine)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;FriendlyElec&lt;/td&gt;
          &lt;td&gt;NanoPi R2S&lt;/td&gt;
          &lt;td&gt;Works partially (incompatible with certain microSD cards, shutdown issues, only one NIC recognized ootb)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;A64 Plus&lt;/td&gt;
          &lt;td&gt;Works great&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;A64 LTS&lt;/td&gt;
          &lt;td&gt;Works great&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Rock64&lt;/td&gt;
          &lt;td&gt;not tested yet with Debian 11&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;RockPro64&lt;/td&gt;
          &lt;td&gt;not tested yet with Debian 11&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Pinebook Pro&lt;/td&gt;
          &lt;td&gt;Works partially (booting off microSD cards fails, reboot issues, manual extra work needed)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;You have a board that is at least unofficially supported by the unstable kernel (see previous section)? Great - let&amp;rsquo;s get our hands dirty!&lt;/p&gt;
&lt;p&gt;In the following, I will assume you want to install Debian GNU/Linux 11 on a NanoPi R2S by FriendlyElec.&lt;/p&gt;
&lt;h2 id=&#34;concept&#34;&gt;Concept&lt;/h2&gt;
&lt;p&gt;My installation concept covers the following stepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installing a device-independent base system using the official installer&lt;/li&gt;
&lt;li&gt;Customizing the base system&lt;/li&gt;
&lt;li&gt;Adapting the base system for the target&lt;/li&gt;
&lt;li&gt;creating tar archives for boot and root&lt;/li&gt;
&lt;li&gt;building the bootloader (device-specific)&lt;/li&gt;
&lt;li&gt;assembling a device-specific image&lt;/li&gt;
&lt;li&gt;flashing the assembled image&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This might seem a lot of work, but note that the firsttwo steps are device-independent.
Thus, you won&amp;rsquo;t have to redo them when installing other devices in the future.&lt;/p&gt;
&lt;h2 id=&#34;requirements-and-assumptions&#34;&gt;Requirements and assumptions&lt;/h2&gt;
&lt;p&gt;Apart from having an unofficially supported machine, I assume you have basic knowledge about the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creating and operating virtual machines with KVM/QEMU using virt-manager&lt;/li&gt;
&lt;li&gt;operating your ARM64 machine over the serial console&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, you will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a dedicated physical x86 machine with a fresh installation of Debian GNU/Linux 11 with at least 2 GiB of RAM and 20 GiB of storage&lt;/li&gt;
&lt;li&gt;a user account with a user named &lt;code&gt;youruser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;an empty microSD card with a capacity at least 4 GiB&lt;/li&gt;
&lt;li&gt;a working internet connection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, the tutorial should also work with other systems, distributions and environments but some steps may differ.
Also, note that using a VM is only possible if you enable nesting as we will exercise the ability to run ARM64-VMs ourselves.
Using very old hardware (e. g. a single-core 32bit machine) is theoretically possible but practically infeasible.&lt;/p&gt;
&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;step-1-installing-the-base-system&#34;&gt;Step 1: Installing the base system&lt;/h2&gt;
&lt;p&gt;First of all, let&amp;rsquo;s create a directory where we will store all the assets produced in this tutorial:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, download the mini ISO for arm64 from the following location:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://deb.debian.org/debian/dists/bullseye/main/installer-arm64/current/images/netboot/mini.iso
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure you also have qemu and virt-manager installed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install qemu-efi-aarch64 qemu-system-arm virt-manager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a new virtual machine using the aarch64 architecture as shown here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen010.png&#34; alt=&#34;screen010&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the next step, choose the mini.iso you downloaded previously as ISO and select &amp;ldquo;Debian Testing&amp;rdquo; as OS.
Give the VM the default of 1.5 GiB of RAM and as many cores as you have.
Next, create a disk image with at least 5 GiB (or stick with the default) and leave the default network settings (using NAT).
Finally, fire up your new VM.
You should get a screen like mine:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen020.png&#34; alt=&#34;screen020&#34;&gt;&lt;/p&gt;
&lt;p&gt;After selecting the first option, the &amp;ldquo;oldschool&amp;rdquo; text installer should boot and give you the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen025.png&#34; alt=&#34;screen025&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now run through the installer but follow these guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;choose a generic hostname and domain name (we want to build a generic, reuseable image)&lt;/li&gt;
&lt;li&gt;choose simple passwords for root and the user you create (again, we want to build a generic image)&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;deb.debian.org&lt;/code&gt; as pkg mirror&lt;/li&gt;
&lt;li&gt;partition the disk to have the following layout (watch my &lt;a href=&#34;partitioning.webm&#34;&gt;video&lt;/a&gt; for more details):
&lt;ul&gt;
&lt;li&gt;Partition #1: Size 100M, type ESP (EFI Firmware), no mountpoint, bootable, name &lt;code&gt;efi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Partition #2: Size 500M, type ext4, mountpoint &lt;code&gt;/boot&lt;/code&gt;, name &lt;code&gt;boot&lt;/code&gt;, label &lt;code&gt;boot&lt;/code&gt;, not bootable&lt;/li&gt;
&lt;li&gt;Partition #3: Size maximum, Type physical volume for encryption, name &lt;code&gt;rootencrypted&lt;/code&gt; no mountpoint, not bootable&lt;/li&gt;
&lt;li&gt;Unside the encrypted volume, create a single ext4 partition spanning the whole outside partition with type ext4 and mountpoint &lt;code&gt;/&lt;/code&gt;, name &lt;code&gt;root&lt;/code&gt;, label &lt;code&gt;root&lt;/code&gt;, passphrase &lt;code&gt;abcd&lt;/code&gt; (this will ease further setup)&lt;/li&gt;
&lt;li&gt;no swap&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;when installing packages, unselect all packages for installation in tasksel (our aim is to get a minimal image, we will install specific packages later as we need them).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Don&amp;rsquo;t be confused that the installer will display the crypto device being named &lt;code&gt;sda3_crypt&lt;/code&gt; or similar - that&amp;rsquo;s just the name of crypto device but not the partition label!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After installing, the system should boot up fine and present you with a login shell.
In case the installed system does not boot but you get stuck in the Tianocore EFI shell instead, see the troubleshooting section.&lt;/p&gt;
&lt;h2 id=&#34;step-2-customizing-the-base-system&#34;&gt;Step 2: Customizing the base system&lt;/h2&gt;
&lt;h3 id=&#34;sysvinit&#34;&gt;sysvinit&lt;/h3&gt;
&lt;p&gt;First, install sysvinit package and reboot (you could see some errors, ignore them):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install sysvinit-core
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable the serial console (the virt target uses ttyAMA0, later at install time we will switch this to the device of your real hardware):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/inittab
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then reboot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the reboot, system bootup should look as follows:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;header.png&#34; alt=&#34;header&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now, you can remove most of the systemd bits by installing install libpam-elogind:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install libpam-elogind 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;acpi&#34;&gt;ACPI&lt;/h3&gt;
&lt;p&gt;Install the acpi package for handling events such as button presses and sleep modes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install acpid
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;f2fs&#34;&gt;f2fs&lt;/h3&gt;
&lt;p&gt;While the installer does not support installing to f2fs filesystems, f2fs is the filesystem I recommend for flash media.
Add the module to /etc/initramfs-tools/modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;f2fs&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
echo &amp;quot;crc32&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install this package to get support for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install f2fs-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;time-synchronization&#34;&gt;Time synchronization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING: This part works but the daemon fails to synchronize the clock on boot and needs to be run manually. Any suggestions how to fix this are welcome.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some arm64 machine don&amp;rsquo;t have a backup battery for their realtime clock (RTC).
This results in the date and time being wrong each time you disconnect power.
In general, even if your machine has a backup battery, it is a good idea to setup time synchronization.&lt;/p&gt;
&lt;p&gt;Synchronizing date and time can be done using the NTP protocol.
Debian ships several NTP clients you can choose from.
Personally, I recommend OpenBSD&amp;rsquo;s openntpd as it is very lightweight and has been developed with security in mind.
To install it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install openntpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should start and also run on the next boot.
To initially update the clock (openntpd takes a lot of time otherwise):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ntpd -s -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;dtb-file-handling&#34;&gt;DTB file handling&lt;/h3&gt;
&lt;p&gt;Since we want to use a separate &lt;code&gt;/boot&lt;/code&gt; partition later, we need to make sure the dtb files for the current kernel are there.
Therefore, we create a dtb directory there first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And add the following script that copies the dtb files automatically each time a new kernel is installed or upgraded:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/kernel/postinst.d/copy-dtbs
#!/bin/sh

set -e
version=&amp;quot;$1&amp;quot;

echo Copying current dtb files to /boot/dtbs....
cp -a /usr/lib/linux-image-${version}/. /boot/dtbs/
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s make this script executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /etc/kernel/postinst.d/copy-dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And run it once manually to copy the dtb files for the currently installed kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/kernel/postinst.d/copy-dtbs `uname -r`
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;bootloader-configuration&#34;&gt;Bootloader configuration&lt;/h3&gt;
&lt;p&gt;Create a directory to hold the bootloader configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/extlinux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And create an extlinux boot configuration file (the bootloader u-boot looks them up):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /boot/extlinux/extlinux.conf
TIMEOUT 2
PROMPT 1
DEFAULT debian

LABEL debian
MENU LABEL Linux debian
KERNEL /vmlinuz
INITRD /initrd.img
DEVICETREEDIR /dtbs
APPEND net.ifnames=0 root=LABEL=root cryptopts=source=LABEL=rootencrypted,target=root_crypt,luks
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;kernel-from-unstable-optional&#34;&gt;Kernel from unstable (optional)&lt;/h3&gt;
&lt;p&gt;As discussed previously, it might be necessary to run the kernel from the unstable distribution for certain machines to work better at all.
In addition, some board features might work better with kernels from unstable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; At the time of writing, the unstable distribution does not provide a newer kernel yet. Hence, you will have to wait a few days/weeks before following this approach would make much sense.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Some people recommend installing kernels from backports instead of from unstable. However, I discourage taking this approach as the kernels in backports often receive security updates quite late.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, which kernel should you choose if your board is supported in stable as well?
It depends.
The only advice I can give is: If all features of your board that are relevant to you work with the stable kernel, stick with it.
If not, try the unstable kernel.&lt;/p&gt;
&lt;p&gt;To install the unstable kernel, we need to first add the unstable distribution to apt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/sources.list.d/unstable.list
deb http://deb.debian.org/debian unstable main
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And specify that we only want to install the kernel from unstable (and no other packages):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/preferences.d/99unstable
# Never prefer packages from unstable
Package: *
Pin: release a=unstable
Pin-Priority: 100

# Allow upgrading kernel from unstable
Package: linux-image-arm64
Pin: release a=unstable
Pin-Priority: 500
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we can safely upgrade the kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update
apt install -t unstable linux-image-arm64
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;reboot&#34;&gt;Reboot&lt;/h3&gt;
&lt;p&gt;Before we continue to the next step, let&amp;rsquo;s reboot the system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-3-adapting-the-base-system-for-the-target&#34;&gt;Step 3: Adapting the base system for the target&lt;/h2&gt;
&lt;p&gt;The following changes are &amp;ldquo;devastating&amp;rdquo; and will make the VM unbootable or &amp;ldquo;less unique&amp;rdquo;.
Therefore, I recommend backing up its disk image before applying them (a snapshot would be even better, but KVM on Devuan3 does not seem to support them on aarch64).&lt;/p&gt;
&lt;h3 id=&#34;remove-grub&#34;&gt;Remove GRUB&lt;/h3&gt;
&lt;p&gt;Remove the grub bootloader (we will not use it):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt autoremove grub-efi-arm64 grub-common
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;ssh-servers-openssh-and-dropbear&#34;&gt;SSH servers (openssh and dropbear)&lt;/h3&gt;
&lt;p&gt;Install the regular OpenSSH server together with dropbear for unlocking the machine remotely during boot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --no-install-recommends openssh-server dropbear-initramfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the dropbear port so we don&amp;rsquo;t run into conflicts with the main server (I recommend using different SSH keys for the main and auxiliary SSH server) and add a timeout:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/dropbear-initramfs/config
DROPBEAR_OPTIONS=&amp;quot;-p 4748 -I 60&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an authorized-keys file that limits access to running the cryptsetup binary in dropbear (put your actual SSH public key here):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/dropbear-initramfs/authorized_keys
no-port-forwarding,no-agent-forwarding,no-x11-forwarding,command=&amp;quot;/usr/bin/cryptroot-unlock&amp;quot; ssh- ...
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To set a static IP address that usually works more reliable than DHCP (replace the placeholders):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/initramfs-tools/conf.d/staticip
IP=&amp;quot;&amp;lt;client-ip&amp;gt;::&amp;lt;gw-ip&amp;gt;:&amp;lt;netmask&amp;gt;::eth0:off&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, renegerate the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configure-the-network&#34;&gt;Configure the network&lt;/h3&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use DHCP for the regular system either (recommended), make sure you edit &lt;code&gt;/etc/network/interfaces&lt;/code&gt; accordingly.
For instance, to have a static IP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# The primary network interface
allow-hotplug eth0
#iface eth0 inet dhcp
iface eth0 inet static
        address 192.168.2.11
        netmask 255.255.255.0
        gateway 192.168.2.1
        nameservers 192.168.2.1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;restrict-access-to-the-system&#34;&gt;Restrict access to the system&lt;/h3&gt;
&lt;p&gt;Delete the default user:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;userdel -r user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the keys authorized for dropbear for system access as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /root/.ssh
chmod 700 /root/.ssh
cp /etc/dropbear-initramfs/authorized_keys /root/.ssh/
chmod 600 /root/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards make sure you &lt;strong&gt;edit&lt;/strong&gt; the &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt; file to remove the restrictions (each line should start with &lt;code&gt;ssh-&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;replace-fstab-and-crypttab&#34;&gt;Replace fstab and crypttab&lt;/h3&gt;
&lt;p&gt;Replacing crypttab and fstab should be done as the last steps, otherwise regenerating initramfs might cause troubles.
Replace the fstab as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/fstab
# &amp;lt;file system&amp;gt;        &amp;lt;mount point&amp;gt;  &amp;lt;type&amp;gt;  &amp;lt;options&amp;gt;                   &amp;lt;dump&amp;gt;  &amp;lt;pass&amp;gt;
/dev/mapper/root_crypt /              f2fs    noatime,background_gc=off   0       1
LABEL=boot             /boot          ext4    errors=remount-ro           0       2
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To replace the crypttab file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/crypttab
root_crypt LABEL=&amp;quot;rootencrypted&amp;quot; none luks,initramfs
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-4-creating-tar-archives&#34;&gt;Step 4: Creating tar archives&lt;/h2&gt;
&lt;p&gt;After tweaking the system to our needs, we want to create tar archives that will contain the contents that will be used for the boot and root partitions later.
To do this, we will mount the disk images of the VM directly on the host and extract the files from there.&lt;/p&gt;
&lt;p&gt;First, power down your VM:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;poweroff
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To extract the files from the VM, load the nbd module on your host.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;modprobe nbd max_part=8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the VM&amp;rsquo;s disk image (replace the path according to where you stored your virtual disk):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/debian-aarch64.qcow2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the boot partition (the guided installation installs to the second partition by default) and create a tar archive with our bootfs and store it in our assets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/nbd0p2 /mnt
cd /mnt
tar cfvzp /home/youruser/assets/debian11-aarch64-bootfs.tar.gz .
cd
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do the same for the rootfs as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksOpen /dev/nbd0p3 someroot
mount /dev/mapper/someroot /mnt
cd /mnt
tar cfvzp /home/youruser/assets/debian11-aarch64-rootfs.tar.gz .
cd
umount /mnt
cryptsetup luksClose /dev/mapper/someroot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, clean up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-nbd -d /dev/nbd0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-5-building-the-bootloader&#34;&gt;Step 5: Building the bootloader&lt;/h2&gt;
&lt;p&gt;We build u-boot on the host machine.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The process of building u-boot is machine-specific! This is just an example!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install device-tree-compiler build-essential gcc make git libssl-dev python3-dev bison flex bc libssl-dev make gcc swig gcc-aarch64-linux-gnu gcc-arm-none-eabi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clone ARM&amp;rsquo;s Trusted-Firmware source repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/ARM-software/arm-trusted-firmware
cd arm-trusted-firmware
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Checkout the latest stable tag (check with &lt;code&gt;git tag&lt;/code&gt;, it was &lt;code&gt;v2.5&lt;/code&gt; at the time of writing):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout v2.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compile the firmware:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3328 bl31
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave the build directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, clone the u-boot repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git://git.denx.de/u-boot.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change into its directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd u-boot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Checkout the latest stable tag (again, check with &lt;code&gt;git tag&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout v2021.07
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a symlink to the previously produced arm trusted firmware build (if you built for a different board, adapt the link):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ln -s ../arm-trusted-firmware/build/rk3328/release/bl31/bl31.elf bl31.elf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create the configuration from the default config (again, adapt it if you have a different board):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- BL31=bl31.elf nanopi-r2s-rk3328_defconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the build (change &lt;code&gt;-j16&lt;/code&gt; to match the number of your actual cpu threads):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -j16 CROSS_COMPILE=aarch64-linux-gnu- BL31=bl31.elf all u-boot.itb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the assets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp idbloader.img /home/youruser/assets/
cp u-boot.itb /home/youruser/assets/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-6-installation--flashing&#34;&gt;Step 6: Installation / Flashing&lt;/h2&gt;
&lt;p&gt;With all goodies in place, we can now flash the contents to the storage of your machine. In the following we assume that your machine uses a microSD card for storage (such as the NanoPI R2s).&lt;/p&gt;
&lt;p&gt;As a friend of the KISS principle I recommend using a dead-simple MBR partitioning scheme instead of using GPT.&lt;/p&gt;
&lt;p&gt;First, change to our assets directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, insert your microSD card and check that is has been recognized:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the following, we assume that your device is recognized as &lt;code&gt;/dev/sdX&lt;/code&gt; (replace &lt;code&gt;/dev/sdX&lt;/code&gt; with the actual name of your device).&lt;/p&gt;
&lt;p&gt;Now, overwrite the first megabytes of the card with zeroes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/sdX bs=1M count=256
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, remove the microSD card and re-insert it so its partitioning information will be updated in your OS and check its assigned device name (could be the same as before, but could also be different):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create a template to hold our partition table (adjust the size of the boot partition if you have a bigger microSD card, but don&amp;rsquo;t make it too big):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;sfdisk.template
label: mbr
unit: sectors
first-lba: 64

start=        2048, size=       16384
start=       18432, size=      614400, bootable
start=      632832
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, apply the template to your microSD card:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/sbin/sfdisk /dev/sdX &amp;lt; sfdisk.template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now check dmesg again and make sure the three new partitions have been recognized (e. g. as &lt;code&gt;/dev/sdX1&lt;/code&gt;, &lt;code&gt;/dev/sdX2&lt;/code&gt; and &lt;code&gt;/dev/sdX3&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, create an ext4 filesystem to hold our boot partition (flash wear should not be an issue as normally no writes occur on &lt;code&gt;/boot&lt;/code&gt; during normal operation):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 -L boot /dev/sdX2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the root partition, we create an encrypted partition, unlock it, and format it using the f2fs filesystem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: To make encryption more secure, set the value for &lt;code&gt;--pbkdf-memory 256&lt;/code&gt; 64 MiB lower than the physical memory available on your target device.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksFormat /dev/sdX3 --label=rootencrypted --pbkdf-memory 384
cryptsetup luksOpen /dev/sdX3 somename
mkfs.f2fs -l root /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the boot partition, extract the tar archive :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/sdX2 /mnt
cd /mnt
tar xzvpf /home/youruser/assets/debian11-aarch64-bootfs.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some devices (e. g. the A64-OLinuXino) require a different DTB file than the one included in the Debian kernel package. In this case, overwrite the existing dtb file in the bootfs partition (replace &lt;code&gt;&amp;lt;platform&amp;gt;&lt;/code&gt; by your actual platform):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /path/to/your/special/dtb-file /mnt/dtbs/&amp;lt;platform&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Make sure you prevent your dtb file from being overwritten by kernel upgrades. Thus, once you booted the final system, adapt the file &lt;code&gt;/etc/kernel/postinst.d/copy-dtbs&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unmount the bootfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sync
cd
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do the same for the rootfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mapper/somename /mnt
cd /mnt
tar xzvpf /home/youruser/assets/debian11-aarch64-rootfs.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we unmount it, take the chance to adjust the settings for the serial console. To do that, edit the file &lt;code&gt;/mnt/etc/inittab&lt;/code&gt; and adjust the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This setting is not machine-specific but chipset-specific. Below are some examples for common SoCs:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;SoC&lt;/th&gt;
          &lt;th&gt;serial device&lt;/th&gt;
          &lt;th&gt;Baud rate&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Rockchip RK3328, RK3399&lt;/td&gt;
          &lt;td&gt;/dev/ttyS2&lt;/td&gt;
          &lt;td&gt;1500000&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Allwinner A64, H5, H6&lt;/td&gt;
          &lt;td&gt;/dev/ttyS0&lt;/td&gt;
          &lt;td&gt;115200&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Hence, for the NanoPI R2s, the serial device is &lt;code&gt;ttyS2&lt;/code&gt; (not &lt;code&gt;ttyAMA0&lt;/code&gt;) and it uses a baud rate of &lt;code&gt;15000000&lt;/code&gt; (not &lt;code&gt;115200&lt;/code&gt;).
Again, other boards may need different settings.&lt;/p&gt;
&lt;p&gt;So, in our case, change the line as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyS2 1500000 vt100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that last change done, unmount the new rootfs&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sync
cd /home/youruser/assets
umount /mnt
cryptsetup luksClose /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the last step, we need to write the bootloader to the device.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: This procedure is SoC-specific! Other SoCs require different commands!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For our NanoPI R2s. do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=idbloader.img of=/dev/sdX seek=64 conv=notrunc
dd if=u-boot.itb of=/dev/sdX seek=16384 conv=notrunc
sync
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-7-first-boot&#34;&gt;Step 7: First boot&lt;/h2&gt;
&lt;h3 id=&#34;bootup-and-first-changes&#34;&gt;Bootup and first changes&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s it! Hook up the serial console to your board, put in the microSD card and enjoy.&lt;/p&gt;
&lt;p&gt;After bootup, I recommend to renegerate the SSH keys as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm -v /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
rm /etc/dropbear-initramfs/*_key
dpkg-reconfigure dropbear-initramfs
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;device-specific-notes&#34;&gt;Device-specific notes&lt;/h1&gt;
&lt;h2 id=&#34;pinebook-pro&#34;&gt;Pinebook Pro&lt;/h2&gt;
&lt;p&gt;I found that booting from sdcard did not work properly. Using eMMC instead works fine.
Also, there are issues with u-boot and the display that have to be worked around.&lt;/p&gt;
&lt;h3 id=&#34;u-boot&#34;&gt;u-boot&lt;/h3&gt;
&lt;p&gt;At the time of writing, there are three issues with u-boot that have to be kept in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;version &lt;code&gt;v2021.10-rc4&lt;/code&gt; is broken (does not recognize eMMC). Version &lt;code&gt;v2021.07&lt;/code&gt; works.&lt;/li&gt;
&lt;li&gt;Debian does not work with preboot enabled (see below).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When compiling u-boot, comment out &lt;code&gt;PREBOOT&lt;/code&gt; like this in &lt;code&gt;pinebook-pro_defconfig&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# PREBOOT=y`
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;display&#34;&gt;Display&lt;/h3&gt;
&lt;p&gt;In order to get the display working properly, you have to work with the device using the serial console.
Add the following modules to initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/initramfs-tools/modules
analogix_dp
drm
drm_kms_helper
panel-simple
pwm_bl
pwm_rockchip
pwm_regulator
rockchipdrm
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards, run the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u -k all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to enter the LUKS password using your keyboard, add the following to the kernel APPEND line in &lt;code&gt;/boot/extlinux/extlinux.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console=tty0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;known-issues&#34;&gt;Known issues&lt;/h3&gt;
&lt;p&gt;When rebooting the device, the screen output is garbeled.&lt;/p&gt;
&lt;h2 id=&#34;other-devices&#34;&gt;Other devices&lt;/h2&gt;
&lt;p&gt;(under construction)&lt;/p&gt;
&lt;h1 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h1&gt;
&lt;h2 id=&#34;boot-stuck-in-uefi-shell&#34;&gt;Boot stuck in UEFI shell&lt;/h2&gt;
&lt;p&gt;As of 2021-01-12, installations can become stuck in the Tianocore UEFI shell after the installation or when boot parameters of the VM are changed.
The actual fault seems to be caused by nvram (the nvram file is written by libvirtd).&lt;/p&gt;
&lt;p&gt;To fix this issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;start the VM&lt;/li&gt;
&lt;li&gt;When bumped into the EFI shell, type &amp;ldquo;exit&amp;rdquo; to get to the boot manager&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Boot Maintenance Manager&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Boot Options&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Add Boot Option&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select the presented boot option &amp;ldquo;No volume label &amp;hellip;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;&amp;lt;EFI&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;&amp;lt;debian&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;grubaa64.efi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Press Enter to input the description&lt;/li&gt;
&lt;li&gt;Enter some name (e.g. &lt;code&gt;debian&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Save and commit changes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select Change Boot order&lt;/li&gt;
&lt;li&gt;Hit Enter&lt;/li&gt;
&lt;li&gt;use the +/- keys to move the new entry up.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Commit changes and exit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Go back to main page&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use &amp;ldquo;F10&amp;rdquo; to save the changes&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;continue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;(none yet)&lt;/p&gt;
&lt;h1 id=&#34;credits&#34;&gt;Credits&lt;/h1&gt;
&lt;p&gt;Last but not least, I would like to thank all the helpful minds in the official Devuan forums who helped me resolve various
small issues I encountered when building up this concept.&lt;/p&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2021-09-19] Added device-specific notes for the Pinebook Pro&lt;/li&gt;
&lt;li&gt;[2021-08-21] Initial major rewrite for Debian 11 (based on earlier article, see its changelog for details on past changes)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Coming soon&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>HowTo: PINEBOOK Pro with Debian GNU/Linux 10 or Devuan GNU&#43;Linux 3 using mainline kernel and u-boot</title>
      <link>/post/150_devuan_pinebookpro/</link>
      <pubDate>Tue, 05 Jan 2021 04:10:02 +0000</pubDate>
      
      <guid>/post/150_devuan_pinebookpro/</guid>
      <description>&lt;p&gt;I have written this guide to outline how I finally managed to get the official version of Devuan GNU+Linux 3 or Debian GNU/Linux 10 installed on a PINEBOOK Pro.
It shows how to achieve this using official mainline u-boot and kernel from upstream (no unofficial patches) and without using third-party repositories.
However, it does use self-compiled (unpackaged) versions of u-boot and kernel as tweaking their default build configuration files is currently still required.&lt;/p&gt;
&lt;p&gt;This is how the result looks like on my device:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;pbp.jpg&#34; alt=&#34;PBP&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;status&#34;&gt;Status&lt;/h1&gt;
&lt;p&gt;As of 2021-01-05:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Most basic functionality is there.&lt;/li&gt;
&lt;li&gt;The display works but requires the official Debian kernel to be recompiled with one configuration parameter changed (covered in this guide).&lt;/li&gt;
&lt;li&gt;Adjusting the display brightness using hotkeys does not work out-of-the-box (at least in LXQt).&lt;/li&gt;
&lt;li&gt;The disk encryption password has to be entered either blindly on-device or using the serial console as the display turns on too late (during init instead of initramfs). If you you decide to enter the password on-device, boot messages will still be displayed on the serial console (but no password prompt).&lt;/li&gt;
&lt;li&gt;The microSD functionality is broken (several kernel errors).&lt;/li&gt;
&lt;li&gt;Using external video-out and wifi requires loading non-free blobs (the ones for wifi can be installed using official Debian packages from the non-free section). I am not sure whether this applies to bluetooth as well.&lt;/li&gt;
&lt;li&gt;Reboots often result in garbled screen output. Therefore, to perform a reboot, it is advised to turn the device off and on again.&lt;/li&gt;
&lt;li&gt;Using further deblobbed sources (e.g. Linux/Libre or cleaned trusted firmware) has not been tried.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;covered-topics-and-goals&#34;&gt;Covered topics and goals&lt;/h1&gt;
&lt;p&gt;This guide builds upon my general guide for building Devuan GNU+Linux 3 or Debian GNU/Linux 10 for various ARM64 boards [1].
It basically adds steps which are specific for the PINEBOOK Pro.
The goal is to supplement my general guide instead of copying it.&lt;/p&gt;
&lt;p&gt;As the display does not work directly after installation, a working serial console connection to your PINEBOOK Pro is required.
Alternatively, you could log in remotely using a USB-ethernet adapter or include the steps in the preparation, but these alternatives are not covered in this guide.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; This guide is WORK-IN-PROGRESS (WIP) and has not been fully tested.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;prepare-the-assets&#34;&gt;Prepare the assets&lt;/h1&gt;
&lt;p&gt;Follow my general guide  for installing Debian/Devuan on arm64 [1] but with the following deviations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Step 2: Install the unstable kernel (it is marked as optional in the guide, however, the PINEBOOK Pro requires it).&lt;/li&gt;
&lt;li&gt;Step 3: Do not install the ssh server and dropbear (unless you really want to).&lt;/li&gt;
&lt;li&gt;Step 3: Do not delete your regular user (you don&amp;rsquo;t want to have just root on a laptop).&lt;/li&gt;
&lt;li&gt;Step 5: This guide has been written using version tags &lt;code&gt;v2.4&lt;/code&gt; for the trusted firmware and &lt;code&gt;v2020.10&lt;/code&gt; for u-boot.&lt;/li&gt;
&lt;li&gt;Step 5: When building u-boot, use the configuration file &lt;code&gt;pinebook-pro_defconfig&lt;/code&gt;, but comment the line (&lt;code&gt;PREBOOT=y&lt;/code&gt;) in it before building (obtained this hint from [2]). The configuration file resides in the &lt;code&gt;configs&lt;/code&gt; subdirectory of u-boot.&lt;/li&gt;
&lt;li&gt;Step 6 and 7: Skip these steps, as they differ substantially (this is what this guide is for).&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;initial-installation--flashing&#34;&gt;Initial installation / flashing&lt;/h1&gt;
&lt;p&gt;As of now, the Linux kernel 5.10 shipped in Debian unstable has severe issues with microSD cards.
Therefore, it is required to install a different OS on the PINEBOOK Pro first and flash our Debian/Devuan files from there.&lt;/p&gt;
&lt;h2 id=&#34;grabbing-artifacts&#34;&gt;Grabbing artifacts&lt;/h2&gt;
&lt;p&gt;First of all, copy the following artifacts from step 5 to a USB drive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;devuan-aarch64-bootfs.tar.gz&lt;/li&gt;
&lt;li&gt;devuan-aarch64-rootfs.tar.gz&lt;/li&gt;
&lt;li&gt;idbloader.img&lt;/li&gt;
&lt;li&gt;u-boot.itb&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;preparing-armbian&#34;&gt;Preparing Armbian&lt;/h2&gt;
&lt;p&gt;This guide assumes that the installation on the PINEBOOK Pro is done using Armbian.
Therefore, download and flash Armbian as described on their website to a microSD card.
Once you have Armbian running, connect to the internet (e. g. using wifi or an USB-Ethernet adapter).&lt;/p&gt;
&lt;p&gt;Next, install additional packages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install cryptsetup f2fs-tools sfdisk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, insert the USB drive with the files from step 5, mount it (if not done automatically) and change to the directory where it is mounted.
We will refer to this path as &lt;code&gt;/path/to/your/mounted/usb/drive/&lt;/code&gt; in the rest of this guide.&lt;/p&gt;
&lt;h2 id=&#34;verifying-disks-important&#34;&gt;Verifying disks (IMPORTANT)&lt;/h2&gt;
&lt;p&gt;Before we start flashing, verify using fdisk that mmcblk2 is your internal eMMC flash and mmcblk1 is the microSD card from where your Armbian is running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fdisk -l
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Do not execute the following steps if this is not the case!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;flashing&#34;&gt;Flashing&lt;/h2&gt;
&lt;p&gt;Wipe out the first sectors of the internal eMMC:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/mmcblk2 bs=1M count=100
sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a sfdisk template:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;sfdisk.template
label: mbr
unit: sectors
first-lba: 64

start=        2048, size=       16384
start=       18432, size=      614400, bootable
start=      632832
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Partition the internal eMMC flash:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/sbin/sfdisk devuan3-rockpro64.img &amp;lt; sfdisk.template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Format the boot partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 -L boot /dev/mmcblk2p2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the root partition, create an encrypted partition (choose a strong passphrase), unlock it, and format it using the f2fs filesystem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksFormat /dev/mmcblk2p3 --label=rootencrypted
cryptsetup luksOpen /dev/mmcblk2p3 somename
mkfs.f2fs -l root /dev/mmcblk2p3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Flash the boot partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mmcblk2p2 /mnt
cd /mnt
tar xzvpf /path/to/your/mounted/usb/drive/devuan-aarch64-bootfs.tar.gz .
sync
cd
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Flash the root partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mapper/somename /mnt
cd /mnt
tar xzvpf /path/to/your/mounted/usb/drive/devuan-aarch64-rootfs.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the following line in &lt;code&gt;/mnt/etc/inittab&lt;/code&gt; (only required for Devuan, not for Debian):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 screen
T0:23:respawn:/sbin/getty -L ttyS2 1500000 screen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition, uncomment the following lines in order to activate the regular consoles in &lt;code&gt;/mnt/etc/inittab&lt;/code&gt; as well (again, this only applies to Devuan):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unmount the stuff:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /path/to/your/mounted/usb/drive/
umount /mnt
cryptsetup luksClose /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Flash the bootloader and sync the contents:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=idbloader.img of=/dev/mmcblk2 seek=64 conv=notrunc
dd if=u-boot.itb of=/dev/mmcblk2 seek=16384 conv=notrunc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;powering-down&#34;&gt;Powering down&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Shutdown down Armbian.&lt;/li&gt;
&lt;li&gt;Remove the microSD card.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;intermediate-test&#34;&gt;Intermediate test&lt;/h2&gt;
&lt;p&gt;Connect your serial console to the PINEBOOK Pro and another computer.
Start your serial emulator and connect it. If you are using picocom and have only one USB-Serial device connected, the following should do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picocom -b 1500000 /dev/ttyUSB0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, power on your PINEBOOK Pro and watch it boot.
You should see u-boot and the kernel booting, then it should stop in initrd asking for the disk encryption password.
Enter the password, let the boot finish and log in.&lt;/p&gt;
&lt;h1 id=&#34;getting-the-display-to-work&#34;&gt;Getting the display to work&lt;/h1&gt;
&lt;p&gt;There are basically two reasons why the display does not work out-of-the-box:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Additional kernel modules need to be loaded (see [3]).&lt;/li&gt;
&lt;li&gt;The configuration used by Debian to compile the Linux kernel sets a parameter that needs to be changed (see [4]).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;loading-additional-kernel-modules&#34;&gt;Loading additional kernel modules&lt;/h2&gt;
&lt;p&gt;Add the required modules to the initramfs configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/initramfs-tools/modules
analogix_dp
drm
drm_kms_helper
panel-simple
pwm_bl
rockchipdrm
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And rebuild the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;recompiling-the-kernel&#34;&gt;Recompiling the kernel&lt;/h2&gt;
&lt;p&gt;You can recompile the kernel either on the PINEBOOK Pro directly or on another machine running Debian/Devuan.
I recommend the latter as it takes quite long on the device itself at heats it up which is not ideal for the battery.&lt;/p&gt;
&lt;p&gt;No matter where you build, install the following packages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install build-essential gcc-aarch64-linux-gnu git unzip bison flex libssl-dev bc pigz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then grab the official Linux kernel source (use the current version and verify the download as described on kernel.org):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.4.tar.xz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unpack the sources:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar xvf linux-5.10.4.tar.xz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy the default Debian kernel config (if you are building externally, copy it to the machine where you are doing it):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd linux-5.10.4
cp /boot/config-`uname-r` .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Edit the &lt;code&gt;.config&lt;/code&gt; file and change the following line so its value is an empty string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_SYSTEM_TRUSTED_KEYS=&amp;quot;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also change the setting &lt;code&gt;CONFIG_ROCKCHIP_CDN_DP&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# CONFIG_ROCKCHIP_CDN_DP is not set
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition, I recommend adding some string to your kernel to make it better recognizable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_LOCALVERSION=&amp;quot;.my01&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, change the following entry in the &lt;code&gt;Makefile&lt;/code&gt; to significantly speed up packing when compilation ends:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#XGZIP = gzip
XGZIP = pigz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the build (on-device):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -j6 bindeb-pkg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or if you are building on a different device (change &lt;code&gt;-j16&lt;/code&gt; to match the number of the CPU threads you want to use, typically the maximum you have):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -j16 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bindeb-pkg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the build finishes, you should get the following Debian packages in the parent of the directory where you unpacked the kernel source (names will differ if you used a different kernel):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;linux-headers-5.10.4.my01_5.10.4.my01-1_arm64.deb&lt;/li&gt;
&lt;li&gt;linux-image-5.10.4.my01_5.10.4.my01-1_arm64.deb&lt;/li&gt;
&lt;li&gt;linux-image-5.10.4.my01-dbg_5.10.4.my01-1_arm64.deb&lt;/li&gt;
&lt;li&gt;linux-libc-dev_5.10.4.my01-1_arm64.deb&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you built the kernel externally, copy these files to your PINEBOOK Pro (otherwise you can use them directly).
Install the kernel package (the other debs are only required for debugging and compiling additional modules):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dpkg -i linux-image-5.10.4.my01_5.10.4.my01-1_arm64.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remove the currently installed kernel and the metapackage (otherwise updates could break your display again):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt autoremove linux-image-`uname-r`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check the symlinks in &lt;code&gt;/boot/vmlinuz&lt;/code&gt; and &lt;code&gt;/boot/initrd.img&lt;/code&gt; point to the newly installed kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls -l /boot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s it!
Power down the PINEBOOK Pro (do not just reboot as this might cause garbled display output).
Power the device back on, wait a bit and enter your drive encryption password using the serial console.
After entering the password, your screen should finally turn on.&lt;/p&gt;
&lt;p&gt;Remember: You are now running your device with a self-compiled kernel that gets no automatic updates.
Make sure you download, build and install new kernel versions regularly so you don&amp;rsquo;t miss out on security updates!&lt;/p&gt;
&lt;h2 id=&#34;enter-drive-encryption-password-on-device&#34;&gt;Enter drive encryption password on-device&lt;/h2&gt;
&lt;p&gt;I did not succeed to persuade the display to turn on before the password prompt is shown.
However, you can choose to enter the password &amp;ldquo;blindly&amp;rdquo; on-device.
You will get boot messages on the serial console but the password will need to be entered on-device.
To do this, add the following parameter in the &lt;code&gt;append&lt;/code&gt; line to your &lt;code&gt;/boot/extlinux/extlinux.conf&lt;/code&gt; line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console=ttyS2,1500000 console=tty0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Power down the laptop, power it on, wait aprox 30 seconds and enter the password blindly to continue booting.&lt;/p&gt;
&lt;h2 id=&#34;increasing-backlight-brightness&#34;&gt;Increasing backlight brightness&lt;/h2&gt;
&lt;p&gt;Changing the brightness via hotkeys does not work ootb on the LXQt desktop.
However, the brightness of the display&amp;rsquo;s backlight can be set to maximum via the following command as root:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo 4095 &amp;gt; /sys/devices/platforms/edp-backlight/backlight/edp-backlight
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The value &lt;code&gt;4095&lt;/code&gt; is the maximum, you can also set a lower value of course.&lt;/p&gt;
&lt;h1 id=&#34;additional-blobs-for-wifi-and-video-out&#34;&gt;Additional blobs for wifi and video-out&lt;/h1&gt;
&lt;p&gt;I discourage the use of non-free blobs and recommend using the PINEBOOK Pro with a ath9k-based USB wifi dongle instead.
However, if there is interest I will update this section and add the necessary steps.&lt;/p&gt;
&lt;h1 id=&#34;credits&#34;&gt;Credits&lt;/h1&gt;
&lt;p&gt;I would like to thank all the helpful minds in the official PINE64 forums (especially the users &amp;ldquo;toons&amp;rdquo;, &amp;ldquo;as400&amp;rdquo; and &amp;ldquo;schwarzwieweiss&amp;rdquo;) who pointed me to the principal solutions for some of the steps covered in this guide.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of external resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://www.kulesz.me/post/140-debian-devuan-arm64-install/&#34;&gt;https://www.kulesz.me/post/140-debian-devuan-arm64-install/&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://forum.pine64.org/showthread.php?tid=9744&amp;amp;pid=86475#pid86475&#34;&gt;https://forum.pine64.org/showthread.php?tid=9744&amp;amp;pid=86475#pid86475&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://forum.pine64.org/showthread.php?tid=12534&amp;amp;pid=86682#pid86682&#34;&gt;https://forum.pine64.org/showthread.php?tid=12534&amp;amp;pid=86682#pid86682&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://forum.pine64.org/showthread.php?tid=12534&amp;amp;pid=86977#pid86977&#34;&gt;https://forum.pine64.org/showthread.php?tid=12534&amp;amp;pid=86977#pid86977&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2021-01-09] Added missing kernel config parameter (&lt;code&gt;ROCKCHIP_CDN_DP&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[2021-01-07] Added photo, refined information about non-free blobs&lt;/li&gt;
&lt;li&gt;[2021-01-05] Changed info about not being able to enter password on-device, added section how to achieve this, added section about display brightness&lt;/li&gt;
&lt;li&gt;[2021-01-05] Posted in forums (PINE64 and dev1galaxy) and updated status, fixed mmcblk1 mention in section &amp;ldquo;Verifying disks&amp;rdquo;, fixed various small glitches&lt;/li&gt;
&lt;li&gt;[2021-01-05] First publication&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Please use the discussion forum thread in [4]. I will consider adding further options once this guide gets more mature.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Installing Devuan GNU&#43;Linux or Debian GNU/Linux on ARM64-based SbCs that are not officially supported</title>
      <link>/post/140-debian-devuan-arm64-install/</link>
      <pubDate>Sun, 21 Jun 2020 21:30:02 +0000</pubDate>
      
      <guid>/post/140-debian-devuan-arm64-install/</guid>
      <description>&lt;p&gt;If you want to self-host stuff at home using an ARM64-based board running Linux, both Debian GNU/Linux and Devuan GNU+Linux are excellent distribution choices.
Unfortunately, they officially support only very few ARM64-based boards.
Yet, you can run them unmodified on a lot more boards - if you manage to install them.
After discussing some basics and showing how to check the support status for a particular board, this article describes my recommended way for performing the actual installation by a concrete example.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h1 id=&#34;why-use-official-distributions&#34;&gt;Why use official distributions?&lt;/h1&gt;
&lt;p&gt;Before we dwelve into details, let&amp;rsquo;s discuss some basic things first.
I often hear the argument that people want to solve basic stuff like installing the OS as quickly as possible and focus on the more interesting stuff in the layers above.
Usually, these people end up downloading and flashing one of the countless unofficial OS images from the Internet.
What&amp;rsquo;s wrong with that?&lt;/p&gt;
&lt;p&gt;Choosing a good base OS for your setup is the foundation for running a trustworthy and secure system.
Sure, this might be irrelevant for a quick and dirty test setup.
However, if you want to run your system for years and put personal data on it, this aspect is critical.&lt;/p&gt;
&lt;p&gt;Personally, I discourage using unofficial images for a number of reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Many unofficial images bundle additional software that is not packaged in the official repositores. Therefore, you never get updates for them. This is bad, especially for critical components such as the kernel.&lt;/li&gt;
&lt;li&gt;In addition to trusting the upstream project (such as Debian), you also have to trust the projects and individuals that built the images.&lt;/li&gt;
&lt;li&gt;Apart from trusting these third parties, you also have to trust their build infrastructure.&lt;/li&gt;
&lt;li&gt;Setting up the system yourself, you can optimize the setup to your needs from the very beginning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other side, running an official distribution, you can be sure to get the best &amp;ldquo;vanilla&amp;rdquo; experience.
In addition, all the base software for your system comes from official sources and was build on their official infrastructure.&lt;/p&gt;
&lt;h1 id=&#34;unofficially-supported-boards&#34;&gt;Unofficially supported boards&lt;/h1&gt;
&lt;p&gt;The Linux kernel supports a variety of ARM64-based boards.
Unlike x86 machines, ARM64-based boards require a board-specific device tree binary (dtb) that is built from source.
As Debian aims to be an universal OS, it ships a generic ARM64 kernel that enables support for as many of these boards as possible by shipping dozens of dtbs.
This is also true for Devuan since it uses Debian&amp;rsquo;s unmodified kernel.&lt;/p&gt;
&lt;p&gt;The current OS versions (Debian 10 and Devuan 3) ship version 4.19 of the Linux kernel.
To look them up the boards they theoretically support, do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;visit to &lt;code&gt;packages.debian.org&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;use &amp;ldquo;search package directories&amp;rdquo; with &amp;ldquo;only show exact matches&amp;rdquo; and search for the package &lt;code&gt;linux-image-arm64&lt;/code&gt; in the stable distribution.&lt;/li&gt;
&lt;li&gt;hit the search button and click on the result.&lt;/li&gt;
&lt;li&gt;since &lt;code&gt;linux-image-arm64&lt;/code&gt; is a metapackage that depends on the current kernel, check which version it is (as of now, it is &lt;code&gt;linux-image-4.19.0-9-arm64&lt;/code&gt;). Click on this package to show more details.&lt;/li&gt;
&lt;li&gt;click on &amp;ldquo;list of files&amp;rdquo; to see all files contained in this actual kernel package and check the dtb files listed there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your board is listed here, chances are good you will be able to run the official distribution of Debian or Devuan on it.&lt;/p&gt;
&lt;p&gt;If your board is not listed, don&amp;rsquo;t give up yet - it might still be supported by a newer Linux kernel.
Later in this tutorial, I will show how you can install a newer kernel in the current stable release and get regular updates for it.
However, this only works if your board is supported at least in the &amp;ldquo;unstable&amp;rdquo; release.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry too much about the name &amp;ldquo;unstable&amp;rdquo; - the kernels in Debian unstable are based on well-tested kernels from upstream and usually work well.
They are updated frequently and, thus, receive security updates.
While I consider them okay as a daily driver, they are not as stable as the kernels from the stable distribution.&lt;/p&gt;
&lt;p&gt;To check if your board has support in the unstable kernel, repeat the previous steps but choose &amp;ldquo;unstable&amp;rdquo; instead of &amp;ldquo;stable&amp;rdquo; for the distribution.
If your board is still not listed, then you are out of luck for now as your board is currently not supported (but it might get official support in the future).&lt;/p&gt;
&lt;p&gt;Here is a small list of boards I tried this approach on using the current 5.7 kernel and U-Boot 2020.07:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Manufacturer&lt;/th&gt;
          &lt;th&gt;Make/model&lt;/th&gt;
          &lt;th&gt;Remarks&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Olimex&lt;/td&gt;
          &lt;td&gt;A64-OLinuXino&lt;/td&gt;
          &lt;td&gt;works (only kernel 4.9 works reliably, needs dtb from 5.4, see ¹)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Rock64&lt;/td&gt;
          &lt;td&gt;works mostly (issues with USB 3)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;RockPro64&lt;/td&gt;
          &lt;td&gt;works partially, usable only from eMMC (issues with sdcard and USB 3)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Pine64&lt;/td&gt;
          &lt;td&gt;Pinebook Pro&lt;/td&gt;
          &lt;td&gt;works but requires extra steps as discussed in [4]&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Xunlong&lt;/td&gt;
          &lt;td&gt;OrangePi Zero Plus&lt;/td&gt;
          &lt;td&gt;works&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;1: Use the stable kernel (4.9) but replace the DTB file with the one from 5.4 (otherwise ethernet is broken) and add the kernel commandline parameter &lt;code&gt;console=ttyS0,115200&lt;/code&gt; to disable the HDMI output. With HDMI output enabled and running newer kernels, the device hangs up as soon as the HDMI output turns the display off (after aprox one minute). Also, since Kernel 5.7, LUKS password prompts go to HDMI on this board and are not displayed on the serial console.&lt;/p&gt;
&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;You have a board that is at least unofficially supported by the unstable kernel (see previous section)? Great - let&amp;rsquo;s get our hands dirty!&lt;/p&gt;
&lt;p&gt;In the following, I will assume you want to install Devuan 3 on a RockPro64 by Pine64 &lt;a href=&#34;#rockpro64&#34;&gt;[1]&lt;/a&gt;.
You can also use this guide with small variations if you want to install Debian instead of Devuan or use a different hardware.&lt;/p&gt;
&lt;h2 id=&#34;concept&#34;&gt;Concept&lt;/h2&gt;
&lt;p&gt;My installation concept covers the following stepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installing a device-independent base system using the official installer&lt;/li&gt;
&lt;li&gt;Customizing the base system&lt;/li&gt;
&lt;li&gt;Adapting the base system for the target&lt;/li&gt;
&lt;li&gt;creating tar archives for boot and root&lt;/li&gt;
&lt;li&gt;building the bootloader (device-specific)&lt;/li&gt;
&lt;li&gt;assembling a device-specific image&lt;/li&gt;
&lt;li&gt;flashing the assembled image&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This might seem a lot of work, but note that the firsttwo steps are device-independent.
Thus, won&amp;rsquo;t have to redo them when installing other devices in the future.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This concept borrows and enhances some ideas from my previous debootstrap-based approach.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;requirements-and-assumptions&#34;&gt;Requirements and assumptions&lt;/h2&gt;
&lt;p&gt;Apart from having an unofficially supported board, I assume you have basic knowledge about the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creating and operating virtual machines with KVM/QEMU using virt-manager&lt;/li&gt;
&lt;li&gt;operating your ARM64 board using the serial console&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, you will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a dedicated physical x86 machine with a fresh installation of Debian GNU/Linux 10 or Devuan GNU+Linux 3 with at least 2 GiB of RAM and 20 GiB of storage&lt;/li&gt;
&lt;li&gt;a user account with a user named &lt;code&gt;youruser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;an empty microSD card with a capacity at least 4 GiB&lt;/li&gt;
&lt;li&gt;a working internet connection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, the tutorial should also work with other systems, distributions and environments but some steps may differ.
Also, note that using a VM is only possible if you enable nesting as we will exercise the ability to run ARM64-VMs ourselves.
Using very old hardware (e. g. a single-core 32bit machine) is theoretically possible but practically infeasible&lt;/p&gt;
&lt;h2 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;step-1-installing-the-base-system&#34;&gt;Step 1: Installing the base system&lt;/h2&gt;
&lt;p&gt;First of all, let&amp;rsquo;s create a directory where we will store all the assets produced in this tutorial:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, download the mini ISO for arm64 from the following location:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://pkgmaster.devuan.org/devuan/dists/beowulf/main/installer-arm64/current/images/netboot/mini.iso
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;IMPORTANT: Make sure you use a current mini.iso. Using an outdated one you downloaded in the past can lead to issues like the disk not being recognized in the installer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you want to have Debian instead of Devuan, use the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://deb.debian.org/debian/dists/stable/main/installer-arm64/current/images/netboot/mini.iso
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure you also have qemu and virt-manager installed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install qemu-efi-aarch64 qemu-system-arm virt-manager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a new virtual machine using the aarch64 architecture as shown here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen010.png&#34; alt=&#34;screen010&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the next step, choose the mini.iso you downloaded previously as ISO and select &amp;ldquo;Debian 10&amp;rdquo; as OS.
Give the VM the default of 1 GiB of RAM and as many cores as you have.
Next, create a disk image with at least 5 GiB (or stick with the default) and leave the default network settings (using NAT).
Finally, fire up your new VM.
You should get a screen like mine:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen020.png&#34; alt=&#34;screen020&#34;&gt;&lt;/p&gt;
&lt;p&gt;After selecting the first option, the &amp;ldquo;oldschool&amp;rdquo; text installer should boot and give you the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;screen025.png&#34; alt=&#34;screen025&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now run through the installer but follow these guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;choose a generic hostname and domain name (we want to build a generic, reuseable image)&lt;/li&gt;
&lt;li&gt;choose simple passwords for root and the user you create (again, we want to build a generic image)&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;deb.devuan.org&lt;/code&gt; as pkg mirror&lt;/li&gt;
&lt;li&gt;partition the disk to have the following layout (watch my &lt;a href=&#34;partitioning.webm&#34;&gt;video&lt;/a&gt; for more details):
&lt;ul&gt;
&lt;li&gt;Partition #1: Size 100M, type ESP (EFI Firmware), no mountpoint, bootable, name &amp;ldquo;efi&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Partition #2: Size 500M, type ext4, mountpoint &lt;code&gt;/boot&lt;/code&gt;, name &amp;ldquo;boot&amp;rdquo;, label &amp;ldquo;boot&amp;rdquo;, not bootable&lt;/li&gt;
&lt;li&gt;Partition #3: Size maximum, Type physical volume for encryption, name &amp;ldquo;rootencrypted&amp;rdquo; no mountpoint, not bootable&lt;/li&gt;
&lt;li&gt;Unside the encrypted volume, create a single ext4 partition spanning the whole outside partition with type ext4 and mountpoint &lt;code&gt;/&lt;/code&gt;, name root, label &amp;ldquo;root&amp;rdquo;, passphrase &lt;code&gt;abcd&lt;/code&gt; (this will ease further setup)&lt;/li&gt;
&lt;li&gt;no swap&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;when installing packages, unselect all packages for installation in tasksel (our aim is to get a minimal image, we will install specific packages later as we need them).&lt;/li&gt;
&lt;li&gt;regarding init, the approach should work with both sysvinit and openrc (choose what you prefer).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: Don&amp;rsquo;t be confused that the installer will display the crypto device being named &lt;code&gt;sda3_crypt&lt;/code&gt; or similar - that&amp;rsquo;s just the name of crypto device but not the partition label!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After installing, the system should boot up as shown here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;header.png&#34; alt=&#34;header&#34;&gt;&lt;/p&gt;
&lt;p&gt;In case the installed system does not boot but you get stuck in the Tianocore EFI shell instead, see the troubleshooting section.&lt;/p&gt;
&lt;h2 id=&#34;step-2-customizing-the-base-system&#34;&gt;Step 2: Customizing the base system&lt;/h2&gt;
&lt;h3 id=&#34;fix-slow-shutdowns&#34;&gt;Fix slow shutdowns&lt;/h3&gt;
&lt;p&gt;(only needed in Devuan)&lt;/p&gt;
&lt;p&gt;Due to a bug in Devuan 3 you need to replace the cryptsetup-functions script as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --no-install-recommends wget ca-certificates
cd /lib/cryptsetup
mv cryptdisks-functions cryptdisks-functions.ORIG
wget https://git.devuan.org/devuan/cryptsetup-modified-functions/raw/branch/master/cryptdisks-functions
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;f2fs&#34;&gt;f2fs&lt;/h3&gt;
&lt;p&gt;While the installer does not support installing to f2fs filesystems, f2fs is the filesystem I recommend for flash media.
Add the module to /etc/initramfs-tools/modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;f2fs&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
echo &amp;quot;crc32&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install this package to get support for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install f2fs-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;time-synchronization&#34;&gt;Time synchronization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING: This part works but the daemon fails to synchronize the clock on boot and needs to be run manually. Any suggestions how to fix this are welcome.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most SbCs don&amp;rsquo;t have a backup battery for their realtime clock (RTC).
This results in the date and time being wrong each time you disconnect power.
In general, even if your board has a backup battery, it is a good idea to setup time synchronization.&lt;/p&gt;
&lt;p&gt;Synchronizing date and time can be done using the NTP protocol.
Debian ships several NTP clients you can choose from.
Personally, I recommend OpenBSD&amp;rsquo;s openntpd as it is very lightweight and has been developed with security in mind.
To install it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install openntpd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should start and also run on the next boot.
In case you want to test it or sync manually, you can invoke it as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ntpd -s -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;dtb-file-handling&#34;&gt;DTB file handling&lt;/h3&gt;
&lt;p&gt;Since we want to use a separate &lt;code&gt;/boot&lt;/code&gt; partition later, we need to make sure the dtb files for the current kernel are there.
Therefore, we create a dtb directory there first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And add the following script that copies the dtb files automatically each time a new kernel is installed or upgraded:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/kernel/postinst.d/copy-dtbs
#!/bin/sh

set -e
version=&amp;quot;$1&amp;quot;

echo Copying current dtb files to /boot/dtbs....
cp -a /usr/lib/linux-image-${version}/. /boot/dtbs/
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s make this script executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /etc/kernel/postinst.d/copy-dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And run it once manually to copy the dtb files for the currently installed kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/kernel/postinst.d/copy-dtbs `uname -r`
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;bootloader-configuration&#34;&gt;Bootloader configuration&lt;/h3&gt;
&lt;p&gt;Create a directory to hold the bootloader configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/extlinux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And create an extlinux boot configuration file (the bootloader u-boot looks them up):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /boot/extlinux/extlinux.conf
TIMEOUT 2
PROMPT 1
DEFAULT devuan

LABEL devuan
MENU LABEL Linux devuan
KERNEL /vmlinuz
INITRD /initrd.img
DEVICETREEDIR /dtbs
APPEND root=LABEL=root cryptopts=source=LABEL=rootencrypted,target=root_crypt,luks
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;kernel-from-unstable-optional&#34;&gt;Kernel from unstable (optional)&lt;/h3&gt;
&lt;p&gt;As discussed previously, it might be necessary to run the kernel from the unstable distribution in order for your board to work.
In addition, some board features might work better with kernels from unstable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Some people recommend installing kernels from backports instead of from unstable. However, I discourage taking this approach as the kernels in backports often receive security updates quite late.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, which kernel should you choose if your board is supported in stable as well?
It depends.
The only advice I can give is: If all features of your board that are relevant to you work with the stable kernel, stick with it.
If not, try the unstable kernel.&lt;/p&gt;
&lt;p&gt;To install the unstable kernel, we need to first add the unstable distribution to apt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/sources.list.d/unstable.list
deb http://deb.devuan.org/merged unstable main
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And specify that we only want to install the kernel from unstable (and no other packages):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;/etc/apt/preferences.d/99unstable
# Never prefer packages from unstable
Package: *
Pin: release a=unstable
Pin-Priority: 100

# Allow upgrading kernel from unstable
Package: linux-image-arm64
Pin: release a=unstable
Pin-Priority: 500
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we can safely upgrade the kernel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update
apt install -t unstable linux-image-arm64
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;reboot&#34;&gt;Reboot&lt;/h3&gt;
&lt;p&gt;Before we continue to the next step, let&amp;rsquo;s reboot the system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-3-adapting-the-base-system-for-the-target&#34;&gt;Step 3: Adapting the base system for the target&lt;/h2&gt;
&lt;p&gt;The following changes are &amp;ldquo;devastating&amp;rdquo; and will make the VM unbootable or &amp;ldquo;less unique&amp;rdquo;.
Therefore, I recommend backing up its disk image before applying them (a snapshot would be even better, but KVM on Devuan3 does not seem to support them on aarch64).&lt;/p&gt;
&lt;h3 id=&#34;remove-grub&#34;&gt;Remove GRUB&lt;/h3&gt;
&lt;p&gt;Remove the grub bootloader (we will not use it):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt autoremove grub-efi-arm64 grub-common
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;ssh-servers-openssh-and-dropbear&#34;&gt;SSH servers (openssh and dropbear)&lt;/h3&gt;
&lt;p&gt;Install the regular OpenSSH server together with dropbear for unlocking the machine remotely during boot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install --no-install-recommends openssh-server dropbear-initramfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the dropbear port so we don&amp;rsquo;t run into conflicts with the main server (I recommend using different SSH keys for the main and auxiliary SSH server) and add a timeout:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/dropbear-initramfs/config
DROPBEAR_OPTIONS=&amp;quot;-p 4748 -I 60&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remove the insecure dss certificate key automatically created by dropbear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm /etc/dropbear-initramfs/dropbear_dss_host_key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an authorized-keys file that limits access to running the cryptsetup binary in dropbear (put your actual SSH public key here):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/dropbear-initramfs/authorized_keys
no-port-forwarding,no-agent-forwarding,no-x11-forwarding,command=&amp;quot;/usr/bin/cryptroot-unlock&amp;quot; ssh- ...
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To set a static IP address that usually works more reliable than DHCP (replace the placeholders):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/initramfs-tools/conf.d/staticip
IP=&amp;quot;&amp;lt;client-ip&amp;gt;::&amp;lt;gw-ip&amp;gt;:&amp;lt;netmask&amp;gt;::eth0:off&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(only for Devuan) For a reason I yet have to investigate, the cryptroot-unlock scripts does not find the crypttab file in the initramfs and bails out with the message &amp;ldquo;Try again later&amp;rdquo;.
As an ugly hotfix, edit the file &lt;code&gt;/usr/share/cryptsetup/initramfs/bin/cryptroot-unlock&lt;/code&gt; and comment out the line that
does the &lt;code&gt;exit 1&lt;/code&gt; command so it looks as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Too early, init-top/cryptroot hasn&#39;t finished yet
echo &amp;quot;Try again later&amp;quot; &amp;gt;&amp;amp;2
#exit 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, renegerate the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configure-the-network&#34;&gt;Configure the network&lt;/h3&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use DHCP for the regular system either (recommended), make sure you edit &lt;code&gt;/etc/network/interfaces&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;h3 id=&#34;restrict-access-to-the-system&#34;&gt;Restrict access to the system&lt;/h3&gt;
&lt;p&gt;Delete the default user:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;userdel -r user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the keys authorized for dropbear for system access as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /root/.ssh
chmod 700 /root/.ssh
cp /etc/dropbear-initramfs/authorized_keys /root/.ssh/
chmod 600 /root/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards make sure you &lt;strong&gt;edit&lt;/strong&gt; the &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt; file to remove the restrictions (each line should start with &lt;code&gt;ssh-&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;replace-fstab-and-crypttab&#34;&gt;Replace fstab and crypttab&lt;/h3&gt;
&lt;p&gt;Replacing crypttab and fstab should be done as the last steps, otherwise regenerating initramfs might cause troubles.
Replace the fstab as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/fstab
# &amp;lt;file system&amp;gt;        &amp;lt;mount point&amp;gt;  &amp;lt;type&amp;gt;  &amp;lt;options&amp;gt;                   &amp;lt;dump&amp;gt;  &amp;lt;pass&amp;gt;
/dev/mapper/root_crypt /              f2fs    noatime,background_gc=off   0       1
LABEL=boot             /boot          ext4    errors=remount-ro           0       2
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To replace the crypttab file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /etc/crypttab
root_crypt LABEL=&amp;quot;rootencrypted&amp;quot; none luks,initramfs
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-4-creating-tar-archives&#34;&gt;Step 4: Creating tar archives&lt;/h2&gt;
&lt;p&gt;After tweaking the system to our needs, we want to create tar archives that will contain the contents that will be used for the boot and root partitions later.
To do this, we will mount the disk images of the VM directly on the host and extract the files from there.&lt;/p&gt;
&lt;p&gt;First, power down your VM:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;poweroff
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To extract the files from the VM, load the nbd module on your host.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;modprobe nbd max_part=8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the VM&amp;rsquo;s disk image (replace the path according to where you stored your virtual disk):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/devuan-aarch64.qcow2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the boot partition (the guided installation installs to the second partition by default) and create a tar archive with our bootfs and store it in our assets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/nbd0p2 /mnt
cd /mnt
tar cfvzp /home/youruser/assets/devuan-aarch64-bootfs.tar.gz .
cd
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do the same for the rootfs as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksOpen /dev/nbd0p3 someroot
mount /dev/mapper/someroot /mnt
cd /mnt
tar cfvzp /home/youruser/assets/devuan-aarch64-rootfs.tar.gz .
cd
umount /mnt
cryptsetup luksClose /dev/mapper/someroot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, clean up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-nbd -d /dev/nbd0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-5-building-the-bootloader&#34;&gt;Step 5: Building the bootloader&lt;/h2&gt;
&lt;p&gt;We build u-boot on the host machine.&lt;/p&gt;
&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install device-tree-compiler build-essential gcc make git libssl-dev python3-dev bison flex bc libssl-dev make gcc swig gcc-aarch64-linux-gnu gcc-arm-none-eabi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clone ARM&amp;rsquo;s Trusted-Firmware source repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/ARM-software/arm-trusted-firmware
cd arm-trusted-firmware
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Checkout the latest stable tag (check with &lt;code&gt;git tag&lt;/code&gt;, it was &lt;code&gt;v2.3&lt;/code&gt; at the time of writing):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout v2.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compile the firmware (for other platforms, replace &lt;code&gt;rk3399&lt;/code&gt; - e. g. by &lt;code&gt;rk3288&lt;/code&gt; if you build for a Rock64 board):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl31
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave the build directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, clone the u-boot repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git://git.denx.de/u-boot.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change into its directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd u-boot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Checkout the latest stable tag (again, check with &lt;code&gt;git tag&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout v2020.07
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a symlink to the previously produced arm trusted firmware build (if you built for a different board, adapt the link):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ln -s ../arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf bl31.elf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create the configuration from the default config (again, adapt it if you have a different board):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make CROSS_COMPILE=aarch64-linux-gnu- BL31=bl31.elf rockpro64-rk3399_defconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the build (change &lt;code&gt;-j16&lt;/code&gt; to match the number of your actual cpu threads):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -j16 CROSS_COMPILE=aarch64-linux-gnu- BL31=bl31.elf all u-boot.itb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the assets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp u-boot/idbloader.img /home/youruser/assets/
cp u-boot/u-boot.itb /home/youruser/assets/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-6-assembling-a-device-specific-image&#34;&gt;Step 6: Assembling a device-specific image&lt;/h2&gt;
&lt;p&gt;With all goodies in place, we can now create a flashable image for your board.
Unless you need more than four partitions I recommend sticking with a dead-simple MBR partition scheme instead of using GPT.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Alternatively, you can also write the installation to your flash media directly instead of creating an image as described here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before we start, let&amp;rsquo;s install kpartx:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install kpartx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, change to our assets directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /home/youruser/assets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an image file for your device:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=devuan3-rockpro64.img bs=1M count=4096
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create a template to hold our partition table (adjust the size of the boot partition if you have a bigger microSD card, but don&amp;rsquo;t make it too big):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39;&amp;gt;&amp;gt;sfdisk.template
label: mbr
unit: sectors
first-lba: 64

start=        2048, size=       16384
start=       18432, size=      614400, bootable
start=      632832
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, apply the template to the disk image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/sbin/sfdisk devuan3-rockpro64.img &amp;lt; sfdisk.template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Refresh the partition information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kpartx -v -a devuan3-rockpro64.img
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should result in three devices (&lt;code&gt;loop0p1&lt;/code&gt; to &lt;code&gt;loop0p3&lt;/code&gt;) showing up.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: Double-check this! If you have other active loop devices already, the following command might destroy your data!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, create an ext4 filesystem to hold our boot partition (flash wear should not be an issue as normally no writes occur on &lt;code&gt;/boot&lt;/code&gt; during normal operation):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 -L boot /dev/mapper/loop0p2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the root partition, we create an encrypted partition, unlock it, and format it using the f2fs filesystem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cryptsetup luksFormat /dev/mapper/loop0p3 --label=rootencrypted
cryptsetup luksOpen /dev/mapper/loop0p3 somename
mkfs.f2fs -l root /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the boot partition, extract the tar archive :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mapper/loop0p2 /mnt
cd /mnt
tar xzvpf /home/youruser/assets/devuan-aarch64-bootfs.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some devices (e. g. the A64-OLinuXino) require a different DTB file than the one included in the Debian kernel package. In this case, overwrite the existing dtb file in the bootfs partition (replace &lt;code&gt;&amp;lt;platform&amp;gt;&lt;/code&gt; by your actual platform):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /path/to/your/special/dtb-file /mnt/dtbs/&amp;lt;platform&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Make sure you prevent your dtb file from being overwritten by kernel upgrades. Thus, once you booted the final system, adapt the file &lt;code&gt;/etc/kernel/postinst.d/copy-dtbs&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unmount the bootfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sync
cd
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do the same for the rootfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/mapper/somename /mnt
cd /mnt
tar xzvpf /home/youruser/assets/devuan-aarch64-rootfs.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we unmount it, take the chance to adjust the settings for the serial console (only needed for Devuan, in Debian systemd automatically figures out the serial device).
To do that, edit the file &lt;code&gt;/mnt/etc/inittab&lt;/code&gt; and adjust the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyAMA0 115200 screen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the RockPro64, the serial device is &lt;code&gt;ttyS2&lt;/code&gt; (not &lt;code&gt;ttyAMA0&lt;/code&gt;) and it uses a baud rate of &lt;code&gt;15000000&lt;/code&gt; (not &lt;code&gt;115200&lt;/code&gt;).
Again, other boards may need different settings.&lt;/p&gt;
&lt;p&gt;In our case, change the line as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T0:23:respawn:/sbin/getty -L ttyS2 1500000 screen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that last change done, unmount the new rootfs&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sync
cd /home/youruser/assets
umount /mnt
cryptsetup luksClose /dev/mapper/somename
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the last step, we need to write the bootloader to the device.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: This procedure is SoC-specific! Other SoCs require different commands!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For our RockPro64. do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=idbloader.img of=devuan3-rockpro64.img seek=64 conv=notrunc
dd if=u-boot.itb of=devuan3-rockpro64.img seek=16384 conv=notrunc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your image is now ready to be flashed.&lt;/p&gt;
&lt;h2 id=&#34;step-7-flashing-and-final-modifications&#34;&gt;Step 7: Flashing and final modifications&lt;/h2&gt;
&lt;h3 id=&#34;flashing&#34;&gt;Flashing&lt;/h3&gt;
&lt;p&gt;To flash it to an microSD card (replace &lt;code&gt;/dev/sdX&lt;/code&gt; by the actual device):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=devuan3-rockpro64.img of=/dev/sdX bs=1M
sync
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;bootup-and-first-changes&#34;&gt;Bootup and first changes&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s it! Hook up the serial console to your board, put in the microSD card and enjoy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING: the next part was not tested!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After bootup, I recommend to renegerate the SSH keys as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm -v /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And to regenerate the keys used by dropbear-initramfs (deleting the dss key again):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm /etc/dropbear-initramfs/*_key
dpkg-reconfigure dropbear-initramfs
rm /etc/dropbear-initramfs/dropbear_dss_host_key
update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;troubleshooting-and-device-specific-workarounds&#34;&gt;Troubleshooting and device-specific workarounds&lt;/h1&gt;
&lt;h2 id=&#34;generic&#34;&gt;Generic&lt;/h2&gt;
&lt;h3 id=&#34;boot-stuck-in-uefi-shell&#34;&gt;Boot stuck in UEFI shell&lt;/h3&gt;
&lt;p&gt;As of 2021-01-12, installations can become stuck in the Tianocore UEFI shell after the installation or when boot parameters of the VM are changed.
The actual fault seems to be caused by nvram (the nvram file is written by libvirtd).&lt;/p&gt;
&lt;p&gt;To fix this issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;start the VM&lt;/li&gt;
&lt;li&gt;When bumped into the EFI shell, type &amp;ldquo;exit&amp;rdquo; to get to the boot manager&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Boot Maintenance Manager&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Boot Options&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Choose &amp;ldquo;Add Boot Option&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select the presented boot option &amp;ldquo;No volume label &amp;hellip;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;&amp;lt;EFI&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;&amp;lt;debian&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;grubaa64.efi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Press Enter to input the description&lt;/li&gt;
&lt;li&gt;Enter some name (e.g. &lt;code&gt;debian&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Save and commit changes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select Change Boot order&lt;/li&gt;
&lt;li&gt;Hit Enter&lt;/li&gt;
&lt;li&gt;use the +/- keys to move the new entry up.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Commit changes and exit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Go back to main page&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use &amp;ldquo;F10&amp;rdquo; to save the changes&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;continue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pinebook-pro&#34;&gt;PINEBOOK Pro&lt;/h2&gt;
&lt;p&gt;I published a separate article on that [4].&lt;/p&gt;
&lt;h2 id=&#34;rockpro-64&#34;&gt;ROCKPro 64&lt;/h2&gt;
&lt;h3 id=&#34;boot-issues&#34;&gt;Boot issues&lt;/h3&gt;
&lt;p&gt;When building u-boot in step 5, use the configuration file for the ROCKPro 64, but comment the line (PREBOOT=y) in it before building .
There is more detail on this in the separate article about the PINEBOOK Pro as they share the same chipset. [4].&lt;/p&gt;
&lt;h3 id=&#34;dropbear-timing-issue&#34;&gt;Dropbear timing issue&lt;/h3&gt;
&lt;p&gt;On this device there is a timing issue which leads to dropbear starting before the network is available.
This can be worked around by editing the file &lt;code&gt;/usr/share/initramfs-tools/scripts/init-premount/dropbear&lt;/code&gt; and adding the following line in the &lt;code&gt;run_dropbear()&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; sleep 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards, rebuild the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;broken-ethernet&#34;&gt;Broken ethernet&lt;/h3&gt;
&lt;p&gt;Another issue on this device is that ethernet often does not work in the regular system although it worked in dropbear.
This seems to be an issue with the driver.
It can be worked around by creating a small script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt; /root/fix-network.sh
#!/bin/bash
sleep 5
/sbin/rmmod dwmac_rk
sleep 1
/sbin/modprobe dwmac_rk
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, make it executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /root/fix-network.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And add the following line to cron:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@reboot /root/fix-network.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;system-fan-not-running&#34;&gt;System fan not running&lt;/h3&gt;
&lt;p&gt;The system fan is not running while the system is waiting in dropbear to be decrypted.
This can become a thermal issue if you are using the NAS case and have power-hungry hard drives installed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TODO: Add instructions here&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;broken-pcie&#34;&gt;Broken PCIe&lt;/h3&gt;
&lt;p&gt;Due to various faults the ROCKPro 64 works unreliable with many PCIe cards/modules.
In these cases, failures can be observed as SMP errors and kernel crashes.
In addition, the link speed remains limited to PCIe gen1.&lt;/p&gt;
&lt;p&gt;If you encounter these issues, you can try to recompile the dts file to enable gen2 support.
However, some users report that this might work only on boards with revision 2.1 (although not all boards with this revision seem to be the same).&lt;/p&gt;
&lt;p&gt;To do this, install the device tree compiler and wget:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install build-essential bison flex libssl-dev gcc-arm-linux-gnueabihf bc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, download the necessary bits:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.19.tar.xz
tar xvf linux-5.10.19.tar.xz
cd linux-5.10.19.tar.xz
make olddefconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, edit the file &lt;code&gt;arch/arm64/boot/dts/rockchip/rk3399.dtsi&lt;/code&gt; and change the following line as described in the corresponding patch [5]:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;max-link-speed = &amp;lt;2&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then recompile the dtbs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And replace the dtb file (after backing up the original ones):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /boot/dtbs/rockchip/rk3399-rockpro64-v2.dtb /boot/dtbs/rockchip/rk3399-rockpro64-v2.dtb.ORIG
cp /boot/dtbs/rockchip/rk3399-rockpro64.dtb /boot/dtbs/rockchip/rk3399-rockpro64.dtb.ORIG
cp arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dtb /boot/dtbs/rockchip/
cp arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtb /boot/dtbs/rockchip/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reboot the kernel and check if this works for you. If it does, copy the file to root&amp;rsquo;s home directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /root
mkdir dtbs-rockpro64
cp /boot/dtbs/rockchip/rk3399-rockpro64* .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, add a corresponding line to your &lt;code&gt;/etc/kernel/postinst.d/copy-dtbs&lt;/code&gt; script:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TODO: describe the line&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;pine-64-lts&#34;&gt;Pine 64-LTS&lt;/h2&gt;
&lt;h3 id=&#34;boot-regression&#34;&gt;Boot regression&lt;/h3&gt;
&lt;p&gt;A DTB change merged in March 2021 into the Linux kernel makes the Pine A64-LTS non-bootable (the non-LTS PINE A64 and A64+ are not affected). If you encounter this issue, use a static copy of the DTB files from the previous kernels.&lt;/p&gt;
&lt;p&gt;Alternatively, you can download the kernel&amp;rsquo;s source code and change the following line in &lt;code&gt;arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd-gpios = &amp;lt;&amp;amp;pio 5 6 GPIO_ACTIVE_LOW&amp;gt;; /* PF6 */
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd-gpios = &amp;lt;&amp;amp;pio 5 6 GPIO_ACTIVE_HIGH&amp;gt;; /* PF6 */
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, recompile the dtbs and adapt your &lt;code&gt;/etc/kernel/postinst.d/copy-dtbs&lt;/code&gt; script accordingly.&lt;/p&gt;
&lt;p&gt;Credit for this fix goes to Andre Przywara who is maintaing the DTS files in the Linux kernel. I am in contact with him to get the fix upstreamed, so the A64-LTS will boot fine in the future again without the need for manual fixes.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://www.pine64.org/rockpro64/&#34;&gt;https://www.pine64.org/rockpro64/&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://dev1galaxy.org/viewtopic.php?id=3624&#34;&gt;https://dev1galaxy.org/viewtopic.php?id=3624&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://hamy.io/post/0009/how-to-install-luks-encrypted-ubuntu-18.04.x-server-and-enable-remote-unlocking&#34;&gt;https://hamy.io/post/0009/how-to-install-luks-encrypted-ubuntu-18.04.x-server-and-enable-remote-unlocking&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://www.kulesz.me/post/150_devuan_pinebookpro/&#34;&gt;https://www.kulesz.me/post/150_devuan_pinebookpro/&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;li&gt;[5] &lt;!-- raw HTML omitted --&gt;&lt;a href=&#34;https://patchwork.kernel.org/project/linux-rockchip/patch/20200423150510.6216-1-pgwipeout@gmail.com/&#34;&gt;https://patchwork.kernel.org/project/linux-rockchip/patch/20200423150510.6216-1-pgwipeout@gmail.com/&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;credits&#34;&gt;Credits&lt;/h1&gt;
&lt;p&gt;Last but not least, I would like to thank all the helpful minds in the official Devuan forums who helped me resolve various
small issues I encountered when building up this concept.&lt;/p&gt;
&lt;p&gt;Also, I would like to thank &amp;ldquo;n4tter4ngell&amp;rdquo; from the PINE64 forums who contributed the workaround for the dropbear issue on the ROCKPro 64.&lt;/p&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2021-04-04] Add workaround for boot regression on A64-LTS boards&lt;/li&gt;
&lt;li&gt;[2021-03-06] Added device-specific note regarding the fan and broken PCIe in rockpro64 boards&lt;/li&gt;
&lt;li&gt;[2021-02-20] Marked cryptroot-unlock modifications as Devuan-only&lt;/li&gt;
&lt;li&gt;[2021-01-28] Supplemented some labels in partitioning section&lt;/li&gt;
&lt;li&gt;[2021-01-13] Added hint about uboot-issue in ROCKPro64, fixed @cron issue, removed &amp;ldquo;Disable the password for the root account&amp;rdquo;, add missing cd command&lt;/li&gt;
&lt;li&gt;[2021-01-12] Replaced the previous workaround for the qemu/efi issue by a better solution&lt;/li&gt;
&lt;li&gt;[2021-01-12] Added workaround for qemu/efi regression in Debian stable&lt;/li&gt;
&lt;li&gt;[2021-01-09] Add section about device-specific workarounds, split credits and external references&lt;/li&gt;
&lt;li&gt;[2020-10-31] Add partitioning video, fix misleading OS type and add hint about crypto device naming (all in step 1) and add warning about partially broken openntpd (in step 2)&lt;/li&gt;
&lt;li&gt;[2020-07-30] Remove package grub-common as well (this saves around 18 MiB)&lt;/li&gt;
&lt;li&gt;[2020-07-23] Disable instead of delete the root password; fix instructions for ssh key regeneration&lt;/li&gt;
&lt;li&gt;[2020-07-18] Rework step 3 with several details, update OLinuxino-A64 status and tweaks&lt;/li&gt;
&lt;li&gt;[2020-07-15] Major rewrite, now uses FDE with unencrypted boot&lt;/li&gt;
&lt;li&gt;[2020-06-21] Initial writeup&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fosstodon.org/web/statuses/104384241577314150&#34;&gt;Join the discussion on Mastadon (external resource)&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Building a freedom-friendly wifi pocket-router</title>
      <link>/post/130-pocket-router/</link>
      <pubDate>Sun, 19 Apr 2020 14:35:02 +0000</pubDate>
      
      <guid>/post/130-pocket-router/</guid>
      <description>&lt;p&gt;Installing and configuring operating systems on single-board computers can be painful when there is no nearby ethernet connection available.
A pocket-router that provides wired internet access over an existing wireless network can help here.
In this article, I discuss why I decided to build one myself and describe the particular steps conducted.
Moreover, I also present measures regarding performance and power consumption.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;10.jpg&#34; alt=&#34;Overview&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;motivation&#34;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;Reinventing the wheel is usually a bad idea.
Therefore, I first looked for a ready-made wifi router that would meet my expectations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the device should be as small as possible&lt;/li&gt;
&lt;li&gt;the device should run only free firmware and software that is actively supported&lt;/li&gt;
&lt;li&gt;it should be easy to configure the device on-the-go&lt;/li&gt;
&lt;li&gt;the device should require low power and no dedicated wall plug (ideally it should be powered from an USB port of the &amp;ldquo;device-under-installation&amp;rdquo; or from a small power bank)&lt;/li&gt;
&lt;li&gt;powering off the device should be safely possible by just pulling the power connector&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With such high expectations set, it might not come as a big surprise that it was hard to find such a device.
The closest match I came across was the &amp;ldquo;Free Software Wireless-N Mini VPN Router&amp;rdquo; from Thinkpenguin [1].
Unfortunately, I did not find a local retailer for this device.
In addition, with just 16 megs of MTD flash and 64 megs of RAM this device is rather limited in terms of resources (but luckily not endangered in losing upstream support at the moment).&lt;/p&gt;
&lt;p&gt;Since I had plenty leftover parts from other projects anyways, I decided against buying more stuff and for taking the self-building path.
Another argument pro building such device yourself is that are a later free to easily switch hardware if you find that you require more performance.&lt;/p&gt;
&lt;h1 id=&#34;hardware&#34;&gt;Hardware&lt;/h1&gt;
&lt;p&gt;I selected the following hard- and software from my home inventory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Xunlong OrangePi Zero [2] with small plastic case&lt;/li&gt;
&lt;li&gt;old microSD card (even ancient cards with just 512 MB of storage would suffice)&lt;/li&gt;
&lt;li&gt;Atheros-based USB-Wifi dongle with ath9k chipset such as [3]&lt;/li&gt;
&lt;li&gt;OpenWRT [4] - this article is based on version 19.07.2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please note that while the OrangePi Zero already provides on-board wifi, I decided against using it because (1) it requires non-free firmware, (2) it is not officially by OpenWRT, and, (3) performance and driver support seemed quite poor to me.&lt;/p&gt;
&lt;p&gt;Ignoring the OrangePi Zero&amp;rsquo;s onboard-wifi, I am not aware of any non-free firmware or other binary blobs that would be required to operate the selected hardware.
Therefore, it should also be possible to use LibreCMC instead of OpenWRT.
Since LibreCMC does not provide any binary builds for this platform, I decided to stick with OpenWRT.&lt;/p&gt;
&lt;p&gt;I would like to stress that there is absolutely no need to use the described hardware.
If you already have an arbitrary single-board computer that is supported by OpenWRT and a compatible wifi dongle you should be perfectly fine.
However, depending on the particular hardware, you might need to slightly adapt some of the described steps.&lt;/p&gt;
&lt;p&gt;For the installation itself, you need some additional equipment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a serial console (USB-TTL)&lt;/li&gt;
&lt;li&gt;a computer capable of using the serial console to connect to the pocker-router&lt;/li&gt;
&lt;li&gt;a terminal emulation program such as picocom [5]&lt;/li&gt;
&lt;li&gt;a web browser&lt;/li&gt;
&lt;li&gt;a LAN port in your router/firewall that serves IP addresses via DHCP and provides internet access&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;step-1-installing-openwrt&#34;&gt;Step 1: Installing OpenWRT&lt;/h1&gt;
&lt;p&gt;First of all, locate the OpenWRT image for your hardware using their website.
Make sure to use the squashfs image and not the ext4 variant because otherwise your device will later lack the ability to be safely unplugged without additional steps.&lt;/p&gt;
&lt;p&gt;The next step is to retrieve the particular OpenWRT image, check its hashsum and unpacked it.
This is how it looked like on my OrangePi Zero:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://downloads.openwrt.org/releases/19.07.2/targets/sunxi/cortexa7/openwrt-19.07.2-sunxi-cortexa7-sun8i-h2-plus-orangepi-zero-squashfs-sdcard.img.gz
sha256sum openwrt-19.07.2-sunxi-cortexa7-sun8i-h2-plus-orangepi-zero-squashfs-sdcard.img.gz
gunzip openwrt-19.07.2-sunxi-cortexa7-sun8i-h2-plus-orangepi-zero-squashfs-sdcard.img.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the image can be written to an sdcard that is is connected to your computer (replace &lt;code&gt;/dev/sdX&lt;/code&gt; by the actual device):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=openwrt-19.07.2-sunxi-cortexa7-sun8i-h2-plus-orangepi-zero-squashfs-sdcard.img of=/dev/sdX bs=1M
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, take out the sdcard and you you should be ready for the next step.&lt;/p&gt;
&lt;h1 id=&#34;step-2-adding-usb-wifi-support&#34;&gt;Step 2: Adding USB wifi support&lt;/h1&gt;
&lt;p&gt;With the microSD card inserted, hook up the serial console to your pocket-router, start the terminal emulation program on the connected computer and attach the power connector to the pocket-router.
You should see OpenWRT boot up.
This is how it looked like in my case:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;15.jpg&#34; alt=&#34;Overview&#34;&gt;&lt;/p&gt;
&lt;p&gt;OpenWRT is optimized for size.
Therefore, support for USB wifi devices is not enabled by default and requires the installation of additional packages.
This is where things get a little tricky if your device device has only one ethernet port like mine.
In this case, OpenWRT will configure the only ethernet port to be the LAN side of the network - leaving you without a WAN connection in the first place.
Adding hardware such as USB ethernet adapters does not help since drivers for such devices are also missing from the default installation.&lt;/p&gt;
&lt;p&gt;To install additional packages, we need to reconfigure the ethernet port temporarily to be used as WAN port via the serial console.
Therefore, edit &lt;code&gt;/etc/config/network&lt;/code&gt; and uncomment the whole LAN section.
The resulting LAN section should look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#config interface &#39;lan&#39;
#        option ifname &#39;eth0&#39;
#        option proto &#39;static&#39;
#        option ipaddr &#39;192.168.1.1&#39;
#        option netmask &#39;255.255.255.0&#39;
#        option delegate &#39;0&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the LAN section neutralized, add a WAN configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;config interface &#39;wan&#39;
       option ifname &#39;eth0&#39;
       option proto &#39;dhcp&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And restart the network:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service network restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Connect the ethernet port of your pocket-router to a any LAN port that provides internet access (typically the &amp;ldquo;normal&amp;rdquo; router you already use).
Inspect the output of &lt;code&gt;ip a&lt;/code&gt; and make sure you have internet access e. g. by using the &lt;code&gt;ping&lt;/code&gt; command.
With internet access established, we can update the package lists and download the modules required for our usb wifi dongle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;opkg update
opkg install kmod-ath9k-htc
opkg install wpa-supplicant
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(If you want to use a wifi dongle with a different chipset, please replace the &lt;code&gt;kmod-ath9k-htc&lt;/code&gt; package in the previous step acoordingly.)&lt;/p&gt;
&lt;p&gt;Finally, revert the configuration changes (remove or comment the added wan section and uncomment the lan section) and restart the network once more:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service network restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-3-configuring-the-wan-side&#34;&gt;Step 3: Configuring the WAN side&lt;/h1&gt;
&lt;p&gt;The remaining steps are easy and should be self-explanatory for anyone who has setup OpenWRT to use the wifi as WAN connection before:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connect your computer to the pocket-router and open OpenWRT&amp;rsquo;s web-based configuration page in your browser by pointing it to the URL of the administration page (&lt;code&gt;http://192.168.1.1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Log in using the empty password and make sure you set a new, strong password.&lt;/li&gt;
&lt;li&gt;Navigate to &amp;ldquo;Network&amp;rdquo; -&amp;gt; &amp;ldquo;Wireless&amp;rdquo;. You should see at least one radio device here.&lt;/li&gt;
&lt;li&gt;Click on the topmost &amp;ldquo;radio0&amp;rdquo; device and hit &amp;ldquo;Scan&amp;rdquo; to search for wireless networks.&lt;/li&gt;
&lt;li&gt;Click on the button &amp;ldquo;Join netwoprk&amp;rdquo; next to the network you want to use.&lt;/li&gt;
&lt;li&gt;Check the box &amp;ldquo;replace wireless configuration&amp;rdquo; and provide the connection parameters (typically your WPA passphrase).&lt;/li&gt;
&lt;li&gt;hit &amp;ldquo;Submit&amp;rdquo; and then &amp;ldquo;Save&amp;rdquo; in the following screen.&lt;/li&gt;
&lt;li&gt;Hit &amp;ldquo;Save &amp;amp; Apply&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s it!
You can now unplug the your pocket-router from its power line and disconnect the serial console.
Plug your new pocket-router to the LAN port of your &amp;ldquo;computer-to-be-installed&amp;rdquo;, connect power (a USB port should be sufficient) and enjoy internet access!&lt;/p&gt;
&lt;h1 id=&#34;measurements&#34;&gt;Measurements&lt;/h1&gt;
&lt;p&gt;To check whether the pocket-router behaves as expected I conducted a few basic measurements.&lt;/p&gt;
&lt;h2 id=&#34;performance&#34;&gt;Performance&lt;/h2&gt;
&lt;p&gt;The pocket-router is fully operational in less than &lt;strong&gt;34 seconds&lt;/strong&gt; (measured: from plugging in to getting the first ping response from a system on the WAN side).&lt;/p&gt;
&lt;p&gt;To measure performance, I ran a speedtest using the service provided by nPerf [6] from a Lenovo Thinkpad X200 connected to the pocket-router.
The &amp;ldquo;real&amp;rdquo; wifi router that provides 802.11n wireless service was located about 10 meters away in a different room with one wall inbetween.
The speedtest reported a transfer speed of &lt;strong&gt;46 MBit/s&lt;/strong&gt; and a latency of &lt;strong&gt;15 ms&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;power-consumption&#34;&gt;Power consumption&lt;/h2&gt;
&lt;p&gt;The pocket-router takes a little less than &lt;strong&gt;1.5 Watts&lt;/strong&gt; in idle mode (WAN and LAN connected but no traffic):&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;20.jpg&#34; alt=&#34;Power-idle&#34;&gt;&lt;/p&gt;
&lt;p&gt;Under full load (when running a speed test) the power consumption did not increase when measuring downstream traffic.
However, when uploading data, power consumption increased to around &lt;strong&gt;2.5 Watts&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;30.jpg&#34; alt=&#34;Power-tx&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;final-thoughts&#34;&gt;Final thoughts&lt;/h1&gt;
&lt;p&gt;A self-built pocket-router like the device described in this article can be quite handy - not only for my original use case.
Building one yourself with OpenWRT is easy except for downloading the required packages when using a device that has just one LAN port.
I hope that this article provided some help with that.
Feedback is highly appreciated!&lt;/p&gt;
&lt;h1 id=&#34;references&#34;&gt;References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;a href=&#34;https://www.thinkpenguin.com/gnu-linux/free-software-wireless-n-mini-vpn-router-tpe-r1100&#34;&gt;https://www.thinkpenguin.com/gnu-linux/free-software-wireless-n-mini-vpn-router-tpe-r1100&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;a href=&#34;http://www.orangepi.org/orangepizero/&#34;&gt;http://www.orangepi.org/orangepizero/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;a href=&#34;https://www.thinkpenguin.com/gnu-linux/penguin-wireless-n-usb-adapter-gnu-linux-tpe-n150usb&#34;&gt;https://www.thinkpenguin.com/gnu-linux/penguin-wireless-n-usb-adapter-gnu-linux-tpe-n150usb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;a href=&#34;https://openwrt.org/&#34;&gt;https://openwrt.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5] &lt;a href=&#34;https://github.com/npat-efault/picocom&#34;&gt;https://github.com/npat-efault/picocom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[6] &lt;a href=&#34;https://www.nperf.com/en/&#34;&gt;https://www.nperf.com/en/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fosstodon.org/web/statuses/104025982828596474&#34;&gt;Join the discussion on Mastadon (external resource)&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>HowTo: Install Devuan 3 GNU&#43;Linux (beowulf) base system on ARM via Debootstrap</title>
      <link>/post/120-devuan-arm/</link>
      <pubDate>Mon, 15 Jul 2019 02:37:00 +0200</pubDate>
      
      <guid>/post/120-devuan-arm/</guid>
      <description>&lt;p&gt;This tutorial describes a method I developed to prepare and install a Devuan 3 (beowulf) base system for the armhf architecture.
I should also work for arm64 and others with small modifications.
Instead of building machine-specific images, I debootstrap a single unified build that can be used across numerous ARMv7 boards without rebuilding.&lt;/p&gt;
&lt;p&gt;Of course, the build is still architecture-specific, so if you use arm64 or another architecture instead of armhf you will need to build a separate image.&lt;/p&gt;
&lt;h1 id=&#34;requirements-and-assumptions&#34;&gt;Requirements and assumptions&lt;/h1&gt;
&lt;p&gt;To apply this tutorial you will need the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ARM board supported by the Linux Kernel 4.19. This tutorial assumes you have a 32bit (armhf) board. If your board has a different architecture (e.g. arm64) it should also work with slight modifications (not covered in this tutorial). Check the dtb files shipped by default with Debian in &lt;a href=&#34;#armmp-filelist&#34;&gt;[1]&lt;/a&gt; and &lt;a href=&#34;#arm64-filelist&#34;&gt;[2]&lt;/a&gt; to see if your board is supported. If your board is not listed there but supported by the Linux Kernel 4.19, it should still work, but you will have to obtain and add the dtb files yourself (not covered in this tutorial).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;working u-boot image (preferably mainline) for your device that is not ancient (ability to boot kernels directly from ext4 partitions, support for extlinux.conf)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;working serial console attached to your ARM board&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why not use the provided images on the Devuan mirrors?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;there are no images for beowulf yet (installing ascii and upgrading is not what I wanted)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the images for ascii use a hard-coded, unmaintained kernel without any working concept for security updates&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the images for ascii are shipped with proprietary blobs and the sources.list file includes non-free sources as well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the images for ascii include packages not installed in the base setup that everybody might want (e.g. screen, openssh-server)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the images use ext4 for the root filesystem but I prefer using f2fs in order to reduce wear of my flash media.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the images for ascii use the old-style u-boot configuration (boot.scr and boot.cmd) that is hard to maintain.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this tutorial is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this tutorial and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event, the author or this forum will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;step-1-prepare-environment&#34;&gt;Step 1: Prepare environment&lt;/h1&gt;
&lt;p&gt;I strongly recommend to use a virtual machine with a live environment for preparation because this significantly lowers the risk of data loss in case of errors (e.g. if you specify the wrong device name in some command).
In principle, you can use any environment that supports Debootstrap (even Alpine Linux).&lt;/p&gt;
&lt;p&gt;I used a Debian 10 GNU/Linux Live CD.
Using a Devuan GNU+Linux Live CD would make some things simpler, however, the current ascii Live CD has a severe unpatched apt vulnerability and thus, was not considered as an viable option.&lt;/p&gt;
&lt;p&gt;Refresh the package index and install wget:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install wget
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Download the Devuan keyring (check &lt;code&gt;http://deb.devuan.org/devuan/pool/main/d/devuan-keyring/&lt;/code&gt; for the latest version):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget http://deb.devuan.org/devuan/pool/main/d/devuan-keyring/devuan-keyring_2017.10.03_all.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And install it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dpkg -i devuan-keyring_2017.10.03_all.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the necessary dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install binfmt-support qemu qemu-user-static
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Download devuan&amp;rsquo;s debootstrap (again, check for the latest version of it):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget http://deb.devuan.org/devuan/pool/main/d/debootstrap/debootstrap_1.0.114%2Bdevuan1_all.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install devuan&amp;rsquo;s debootstrap:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dpkg -i debootstrap_1.0.114+devuan1_all.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-2-create-chroot&#34;&gt;Step 2: Create chroot&lt;/h1&gt;
&lt;p&gt;We will be doing the rest as root, so become root first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo su -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a directory for your chroot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir devuan_armhf_beowulf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run debootstrap (might take a while):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qemu-debootstrap --arch armhf beowulf devuan_armhf_beowulf http://deb.devuan.org/merged/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After it finished, chroot into the environment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chroot devuan_armhf_beowulf
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-3-customize-chroot&#34;&gt;Step 3: Customize chroot&lt;/h1&gt;
&lt;p&gt;Install the base locales:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install locales
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable the default locale:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;en_US.UTF-8 UTF-8&amp;quot; &amp;gt;&amp;gt; /etc/locale.gen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And generate it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;locale-gen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the generic packaged kernel for armv7 systems:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install linux-image-armmp-lpae
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a directory inside &lt;code&gt;/boot&lt;/code&gt; to hold the device tree binary (dtb) files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /boot/dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create a hook script that will copy over the dtb files each time a new kernel is installed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /etc/kernel/postinst.d/copy-dtbs
#!/bin/sh

set -e
version=&amp;quot;$1&amp;quot;

echo Copying current dtb files to /boot/dtbs....
cp /usr/lib/linux-image-${version}/*.dtb /boot/dtbs/
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And make it executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /etc/kernel/postinst.d/copy-dtbs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Call the script once to make sure it works and to initially copy over the current dtb files (replace &lt;code&gt;4.19.0-5-armmp-lpae&lt;/code&gt; by the current version at the time of installation):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/kernel/postinst.d/copy-dtbs 4.19.0-5-armmp-lpae
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create extlinux dir (it will hold the configuration files the u-boot bootloader will use):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /extlinux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an initial extlinux config file (can be customized in the next step):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; /extlinux/extlinux.conf
TIMEOUT 20
PROMPT 1
DEFAULT devuan

LABEL devuan
MENU LABEL Linux devuan
KERNEL /vmlinuz
INITRD /initrd.img
DEVICETREEDIR /dtbs
APPEND root=/dev/mmcblk0p1
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Activate the serial console (if your target machine has a console other than &lt;code&gt;ttyS0&lt;/code&gt; such as &lt;code&gt;AMA0&lt;/code&gt; adapt it):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;T1:12345:respawn:/sbin/agetty -L ttyS0 115200 vt100&amp;quot; &amp;gt;&amp;gt; /etc/inittab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set the root password (use some generic default password, you will want to change it later anyways):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remove the &lt;code&gt;/data&lt;/code&gt; directory created by apt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm -rf /data
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-3b-optional-add-f2fs-support&#34;&gt;Step 3b (optional): Add f2fs support&lt;/h1&gt;
&lt;p&gt;Install the f2fs tools:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install f2fs-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the module to &lt;code&gt;/etc/initramfs-tools/modules&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;f2fs&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
echo &amp;quot;crc32&amp;quot; &amp;gt;&amp;gt; /etc/initramfs-tools/modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And regerate the initrd:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-3c-optional-add-firmware&#34;&gt;Step 3c (optional): Add firmware&lt;/h1&gt;
&lt;p&gt;Depending on the devices you want to operate in your system it can be a good idea to install additional firmware.
For instance, I am using ath9k-based USB devices so let&amp;rsquo;s add the open source firmware for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install firmware-ath9k-htc
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-4-pack&#34;&gt;Step 4: Pack&lt;/h1&gt;
&lt;p&gt;Exit the chroot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change to the directory of the chroot and pack it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd devuan_armhf_beowulf
tar cfvzp /root/beowulf_armhf.tar.gz .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have a nice tar.gz archive that can be used for deploying on the target machines.
Fetch this archive from your live environment and put it in a safe place.&lt;/p&gt;
&lt;h1 id=&#34;step-5-partition-and-flash&#34;&gt;Step 5: Partition and flash&lt;/h1&gt;
&lt;p&gt;The system as we prepared it is suitable for flashing on a (micro) sdcard that contains everything in one partition with a ext4 filesystem.
This is the most simple setup but has some disadvantages.&lt;/p&gt;
&lt;p&gt;Having a separate boot partition is good if you want to sign and verify your boot chain (kernel, initrd, dtb) later.
It also helps if your device has another storage (e.g. eMMC) that is not supported by the boot-loader - you can have &lt;code&gt;/boot&lt;/code&gt; on your sdcard and use other devices for the root filesystem and the rest.&lt;/p&gt;
&lt;p&gt;In the following, we will cover both variants.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING:&lt;/strong&gt; Make sure to change &lt;code&gt;/dev/sdX&lt;/code&gt; in the following examples to match the actual device name of your sdcard!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But before we get to that, I suggest you first erase your sdcard so that you are sure there are no leftovers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=/dev/sdX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Furhermore, make sure &lt;code&gt;/mnt/&lt;/code&gt; is not mounted by inspecting the output of the following command (ideally, it would give no output):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount|grep /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(this tutorial will assume you can use &lt;code&gt;/mnt&lt;/code&gt; as mount point in the following)&lt;/p&gt;
&lt;h2 id=&#34;variant-1-single-all-in-one-ext4-partition&#34;&gt;Variant 1: Single &amp;ldquo;all-in-one&amp;rdquo; ext4 partition&lt;/h2&gt;
&lt;p&gt;Create a MBR partition table and a single ext4 partition on your sdcard:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;o
n
p
1


w
&amp;quot; | fdisk /dev/sdX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an ext4 filesystem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 /dev/sdX1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/sdX1 /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unpack the rootfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar xzvpf /path/to/your/beowulf_armhf.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add an fstab entry:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; etc/fstab
/dev/mmcblk0p1 / ext4 errors=remount-ro 0 0
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exit, sync and unmount:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /
sync
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;variant-2-separate-boot-and-root-partitions&#34;&gt;Variant 2: Separate boot and root partitions&lt;/h2&gt;
&lt;p&gt;In this variant, we will use a small bootable ext4 partition to hold &lt;code&gt;/boot&lt;/code&gt; and a bigger f2fs partition for the root filesystem on the rest of the sdcard.
Create such a MBR partition table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &amp;quot;o
n
p
1

+1G
n
p
2


a
1
w
&amp;quot; | fdisk /dev/sdX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Format the first filesystem as ext4 and the second one as f2fs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkfs.ext4 -m0 /dev/sdX1
mkfs.f2fs /dev/sdX2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create directories for the mount points:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /tmp/mnt-boot
mkdir -p /tmp/mnt-root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the filesystems:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/sdX1 /tmp/mnt-boot
mount /dev/sdX2 /tmp/mnt-root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Extract the image to the root first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /tmp/mnt-root
tar xzvpf /path/to/your/beowulf_armhf.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create the fstab file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;&amp;gt; etc/fstab
/dev/mmcblk0p1 /boot ext4 errors=remount-ro 0 0
/dev/mmcblk0p2 / f2fs defaults 0 0
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Move contents that belong to boot contents and remove symlinks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mv boot/* /tmp/mnt-boot/
rm -rf boot
mkdir boot
mv extlinux /tmp/mnt-boot/
rm initrd*
rm vmlinuz*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recreate the symlinks (replace &lt;code&gt;4.19.0-5-armmp-lpae&lt;/code&gt; by the actual version):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /tmp/mnt-boot
ln -s vmlinuz-4.19.0-5-armmp-lpae vmlinuz
ln -s initrd.img-4.19.0-5-armmp-lpae initrd.img
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, change the entires in the extlinux configuration file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sed -i &amp;quot;/DEVICETREEDIR/c\DEVICETREEDIR /dtbs&amp;quot; extlinux/extlinux.conf
sed -i &amp;quot;/APPEND/c\APPEND root=/dev/mmcblk0p2&amp;quot; extlinux/extlinux.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exit, sync and unmount:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /
sync
umount /tmp/mnt-root
umount /tmp/mnt-boot
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;step-6-flash-bootloader-and-boot&#34;&gt;Step 6: Flash bootloader and boot&lt;/h1&gt;
&lt;p&gt;Finally, install your bootloader.
This is board-specific, e.g. for an Allwinner-A20-based Cubietruck board you would do it as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dd if=/path/to/your/u-boot-sunxi-with-spl-cubietruck.bin of=/dev/sdX bs=1k seek=8
sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s already it! Put the prepared sdcard in your device, hooks up your serial console and give it a try!&lt;/p&gt;
&lt;h1 id=&#34;step-7-post-installation&#34;&gt;Step 7: Post-Installation&lt;/h1&gt;
&lt;p&gt;Now that you got your system booted, you probably want to do further configuration (specific for this installation) after booting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;change the root password&lt;/li&gt;
&lt;li&gt;add additional user accounts&lt;/li&gt;
&lt;li&gt;configure network&lt;/li&gt;
&lt;li&gt;configure sources.list to include security-updates etc.&lt;/li&gt;
&lt;li&gt;configure timezone settings&lt;/li&gt;
&lt;li&gt;reconfigure locale&lt;/li&gt;
&lt;li&gt;configure fstab, so filesystem is remounted read-only in case of a boot after a crash&lt;/li&gt;
&lt;li&gt;install an ssh server&lt;/li&gt;
&lt;li&gt;install your favorite packages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tutorial does not cover these steps, however, I plan to create one that tackles these steps for any Debootstrap-based installations, soon.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://packages.debian.org/buster/armhf/linux-image-4.19.0-5-armmp-lpae/filelist&#34;&gt;https://packages.debian.org/buster/armhf/linux-image-4.19.0-5-armmp-lpae/filelist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://packages.debian.org/buster/arm64/linux-image-4.19.0-5-arm64/filelist&#34;&gt;https://packages.debian.org/buster/arm64/linux-image-4.19.0-5-arm64/filelist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2019-07-15] Major rewrite, published on this site&lt;/li&gt;
&lt;li&gt;[2019-04-14] Initial writeup posted in the Devuan forums&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fosstodon.org/web/statuses/xxxxxx&#34;&gt;Join the discussion on Mastadon (external resource)&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Looking for a functional and secure smartphone that runs only free software? Be patient!</title>
      <link>/post/110-smartphones/</link>
      <pubDate>Sun, 12 May 2019 08:30:10 +0000</pubDate>
      
      <guid>/post/110-smartphones/</guid>
      <description>&lt;h1 id=&#34;motivation&#34;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;On many occasions, I have seen myself and other free software enthusiasts being asked which smartphones and mobile operating systems they can recommend to users who are looking for a free (owner-controlled) and secure smartphone that respects their freedom and privacy.&lt;/p&gt;
&lt;p&gt;I would like to share some of my thoughts about this complex topic. However, please be warned, that it might be disappointing for those who might expect to get clear recommendations in the conclusion.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have written an article on this topic back in spring 2018, but many things have changed since then. Therefore, I decided to conduct a major revision of said article here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;general-freedom-and-security-concerns&#34;&gt;General freedom and security concerns&lt;/h1&gt;
&lt;p&gt;Before I&amp;rsquo;ll dive into specific operating systems and devices I would like to discuss some general issues with today&amp;rsquo;s mobile devices first.&lt;/p&gt;
&lt;h2 id=&#34;firmware-vulnerabilities&#34;&gt;Firmware vulnerabilities&lt;/h2&gt;
&lt;p&gt;If you run closed-source firmware (this is required to operate most smartphones today) you are the mercy of the vendor to provide you with updates. If you look at the Android Security bulletin, almost every month severe critical vulnerabilities in these firmwares need to be patched.&lt;/p&gt;
&lt;p&gt;Unfortunately, many vendors refuse to provide updated firmware if they consider the affected devices are EOL. This is even true for extreme cases such as the &amp;ldquo;Broadpwn&amp;rdquo; exploit (affects BCM43xx wifi chipsets found on more than a billion of devices). This makes these devices de-facto eletronic waste and further worsens the environmental issues that pose a severe threat to our planet already today.&lt;/p&gt;
&lt;h2 id=&#34;bootloader-freedom&#34;&gt;Bootloader freedom&lt;/h2&gt;
&lt;p&gt;Before an operating system can be booted, the hardware has to be initialized. This is usually done by one (or more) bootloaders. As far as I know, there are no modern smartphones (yet) that come preinstalled with a free bootloader or where the proprietary bootloader can be replaced. Few exceptions may be some (quite dated) devices such as the Nokia N900. Also, some partially successful attempts to install the free uboot bootloader on older devices such as the Samsung Galaxy S3 have been reported.&lt;/p&gt;
&lt;h2 id=&#34;hardware-backed-security-requires-closed-source-firmware&#34;&gt;Hardware-backed security requires closed-source firmware&lt;/h2&gt;
&lt;p&gt;Modern SoCs come with a TEE (Trusted Execution Environment) as part of their chip design. These separate systems promise to securely process/store credentials such as fingerprints or (parts of) device encryption keys. I am not aware of any such subsystem that would be open source. Thus, the proper operation of such subsystems is near-impossible to audit for mere mortals (although the main developer of GrapheneOS claimed to have successfully done this in the past [1]).&lt;/p&gt;
&lt;p&gt;Apart from trust and verifiability, using TEEs to store disk encryption keys usually comes at the price of not having separate PINs/passwords for the lockscreen and disk encryption key (like on newer Android devices). Therefore, you have to enter your most valuable credentials in &amp;ldquo;train conditions&amp;rdquo;. This is highly problematic since these credentials allow attackers to gain full access to the storage of your device once they get hold of it - even if it was at rest (completely powered off).&lt;/p&gt;
&lt;h2 id=&#34;modem-isolation&#34;&gt;Modem isolation&lt;/h2&gt;
&lt;p&gt;Many modern SoCs do not have a clear separation between the baseband processor (that runs the non-free radio firmware) and the SoC. This means, that you actually have to trust the firmware of the baseband firmware vendor.&lt;/p&gt;
&lt;p&gt;There is at least one known case of a backdoor built into the layer above that was detected on older Samsung devices and mitigated by Replicant developers [2].&lt;/p&gt;
&lt;h2 id=&#34;other-partitions-with-non-free-binaries-and-data&#34;&gt;Other partitions with non-free binaries and data&lt;/h2&gt;
&lt;p&gt;Some people may think that by re-flashing a ROM or factory image they return their device its &amp;ldquo;original state&amp;rdquo;. However, almost all modern smartphones contain a bunch of partitions that remain untouched during flashing. For instance, here is a listing of partition names and corresponding flash partitions from a Nexus 5:&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;It is hard to find documentation on what the purpose of these partitions is and, depending on the device, there are many different partitions. Also, for partitions that usually don&amp;rsquo;t change I haven&amp;rsquo;t seen any lists of hashes from OEMs. Therefore, if you buy a used phone you have to be aware that there is (1) no official way to reset these partitions to their factory state and (2) it&amp;rsquo;s hard to tell if any of these partitions have been modified. Most of these partitions can be modified if you have root access, therefore, if you ever executed something with root rights it could have tampered with one of those.&lt;/p&gt;
&lt;h1 id=&#34;inclusion-criteria-and-covered-aspects&#34;&gt;Inclusion Criteria and Covered Aspects&lt;/h1&gt;
&lt;p&gt;In the next section, I want to briefly discusses pros and cons of a few (partially) free mobile operating systems (skipping completely proprietary systems like iOS or Windows Phone). Both Android and non-Android-based systems will be discussed. However, near-dead projects like B2G/FirefoxOS will not be covered. Also, I excluded systems that require to pay license fees and extend free platforms by closed-source components (such as SailfishOS).&lt;/p&gt;
&lt;p&gt;In the following, I&amp;rsquo;d like to focus on the following aspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;choice and availability of supported devices&lt;/li&gt;
&lt;li&gt;functionality&lt;/li&gt;
&lt;li&gt;security hardening&lt;/li&gt;
&lt;li&gt;verified boot with owner-supplied keys and free bootloader possible?&lt;/li&gt;
&lt;li&gt;Modem isolation&lt;/li&gt;
&lt;li&gt;inclusion of the non-free Google Apps&lt;/li&gt;
&lt;li&gt;support period (both OS and firmware) and ease of updates&lt;/li&gt;
&lt;li&gt;necessity for non-free components running with root privileges&lt;/li&gt;
&lt;li&gt;availability of &amp;ldquo;first hand&amp;rdquo; factory images from the vendor&lt;/li&gt;
&lt;li&gt;necessity to run non-free software on your computer in order to flash factory images&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;android-based-operating-systems&#34;&gt;Android-based Operating Systems&lt;/h1&gt;
&lt;h2 id=&#34;stock-android&#34;&gt;Stock Android&lt;/h2&gt;
&lt;p&gt;This is the binary Android distribution from Google and comes pre-installed on Google Pixel devices (and Google Nexus devices).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only available for quite pricey Pixel devices (available for older Nexus devices as well, but even the latest ones are EOL since January 2019)&lt;/li&gt;
&lt;li&gt;Fully functional&lt;/li&gt;
&lt;li&gt;Standard Android Security (not hardened), no root privileges for the user&lt;/li&gt;
&lt;li&gt;Verified boot with locked closed-source bootloaders, owner-supplied keys not supported&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on all supported devices (no proper modem isolation, if at all)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are pre-installed and not removable&lt;/li&gt;
&lt;li&gt;Short support period (3 years from beginning of sales for each model), but clearly communicated; covers firmware updates as well (Google gets them from the firmware vendors and publishes them); Updates delivered once per month and easy to install&lt;/li&gt;
&lt;li&gt;All supported devices require vast amounts of closed-source firmware&lt;/li&gt;
&lt;li&gt;Factory images available directly from Google&lt;/li&gt;
&lt;li&gt;No non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;vendor-modified-android&#34;&gt;Vendor-modified Android&lt;/h2&gt;
&lt;p&gt;This is the Android distribution you will find on typical phones manufactured by OEMs like Samsung, HTC, LG, Sony, Huawei etc. These Android distributions are based on Stock Android but customized by the OEM and in case of &amp;ldquo;branded&amp;rdquo; devices also by the network operator.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ultimate choice of devices in all price ranges&lt;/li&gt;
&lt;li&gt;Fully functional&lt;/li&gt;
&lt;li&gt;Standard Android Security (not hardened), no root privileges for the user (but can be easily obtained on many devices thanks to unpatched security holes)&lt;/li&gt;
&lt;li&gt;Verified boot with locked closed-source bootloaders; security varies among bootloaders (many have severe issues so it is possible to unlock the bootloader without wiping user data, rendering this feature completely useless); I am not aware of any devices that allow to use owner-supplied keys&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on most devices&lt;/li&gt;
&lt;li&gt;Google Apps and Services are pre-installed and not removable.&lt;/li&gt;
&lt;li&gt;Often very short and unclear support periods (depending on the vendor) and no formal EOL declaration (highly dependant on the OEM); often irregular, delayed or incomplete updates (e. g. do not include updated firmware, sometimes no updates at all: additional customizations by network operators often lead to further delay of updates; situation got slightly better for newer devices due to Google&amp;rsquo;s Trello project&lt;/li&gt;
&lt;li&gt;I am not aware of any devices that do not require closed-source firmware (a few devices require &amp;ldquo;only a few megabytes&amp;rdquo; of non-free firmware, others require often around 100-200 MB)&lt;/li&gt;
&lt;li&gt;Usually no factory images available from the vendor (depends on the vendor, but most of them do not provide them to end-users)&lt;/li&gt;
&lt;li&gt;Flashing factory images (if available) usually requires non-free software by the OEM that in turn only runs only on non-free operating Systems such as Windows or OS X.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;android-one&#34;&gt;Android One&lt;/h2&gt;
&lt;p&gt;Meanwhile, several vendors also offer devices with &amp;ldquo;Android One&amp;rdquo; that promises to deliver a stock Android experience on non-Pixel devices coming from third-party vendors. These devices are mostly free from customizations (but may contain pre-installed apps).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fair choice of devices, many are quite affordable&lt;/li&gt;
&lt;li&gt;Standard Android Security (not hardened), no root privileges for the user&lt;/li&gt;
&lt;li&gt;Verified boot with locked closed-source bootloaders, owner-supplied keys not supported&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on all supported devices I know about (no proper modem isolation, if at all)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are pre-installed and not removable&lt;/li&gt;
&lt;li&gt;Short support period (3 years from beginning of sales for each model) and usually hard to find for a specific device; Android updates and some firmware updates from Google (Google gets firmware updates for certain platforms from the vendors and publishes them each month); updates are easy to apply&lt;/li&gt;
&lt;li&gt;I am not aware of any devices that do not require closed-source firmware (a few devices require &amp;ldquo;only a few megabytes&amp;rdquo; of firmware, others require often around 100-200 MB)&lt;/li&gt;
&lt;li&gt;Factory images offered only by some vendors&lt;/li&gt;
&lt;li&gt;Flashing factory images (if available) usually requires non-free software by the OEM that in turn only runs only on non-free operating Systems such as Windows or OS X.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;android-open-source-project-aosp&#34;&gt;Android Open Source Project (AOSP)&lt;/h2&gt;
&lt;p&gt;The source distribution of Stock Android&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In theory, most devices that run vendor-modified Android or Android One should be able to run it &amp;mdash; in practice, it is only feasible to use AOSP on Pixel and Nexus devices from Google as well as very few other devices (e.g. some devices from Sony&amp;rsquo;s &amp;ldquo;Open Devices Program&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;Fully functional for Google Nexus and Pixel devices (unfortunately not so for devices from vendors like Sony where functionality is often reported to be broken)&lt;/li&gt;
&lt;li&gt;Verified boot with locked closed-source bootloaders and user-supplied keys (complicated to set up and very poorly documented, only possible on Pixel devices and two outdated Nexus devices)&lt;/li&gt;
&lt;li&gt;Standard Android Security (not hardened), no root privileges for the user (option to build userdebug variant that allows for root but weakens security even worse)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included&lt;/li&gt;
&lt;li&gt;Support period and updates are the same as for stock Android for Google devices; updates for other devices vary and often lack firmware updates; no binary builds available &amp;mdash; has to be self-compiled by the user (very cumbersome, official instructions highly incomplete and error-prone &amp;mdash; sometimes even require yet undocumented procedures due to changes in the build system)&lt;/li&gt;
&lt;li&gt;All supported devices require vast amounts of closed-source firmware&lt;/li&gt;
&lt;li&gt;No non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;grapheneos&#34;&gt;GrapheneOS&lt;/h2&gt;
&lt;p&gt;Security-oriented AOSP variant, recently relaunched as community project by the former CTO of CopperheadOS&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Very limited device support (only Google Pixel devices supported at the moment)&lt;/li&gt;
&lt;li&gt;Fully functional&lt;/li&gt;
&lt;li&gt;Tightly hardened for security (includes kernel patches, a hardened browser and much more)&lt;/li&gt;
&lt;li&gt;Verified boot with locked closed-source bootloaders and vendor-supplied keys; user-supplied keys are supported (complicated to set up but well-documented, requires recompilation)&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on all supported devices (no proper modem isolation, if at all)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included&lt;/li&gt;
&lt;li&gt;Support period and updates are the same as for stock Android; if you trust the project you can use the binary builds from their update site, making updates as easy as on stock Android&lt;/li&gt;
&lt;li&gt;All supported devices require vast amounts of closed-source firmware&lt;/li&gt;
&lt;li&gt;No non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fairphone-open&#34;&gt;Fairphone Open&lt;/h2&gt;
&lt;p&gt;Fairphone is an OEM that tries to build ethical and long-lasting devices.
They have a great, vendor-friendly and forgiving &amp;ldquo;fanboy-style&amp;rdquo; community addicted to the honorable idea of the venture.
With &amp;ldquo;Fairphone Open&amp;rdquo;, they also offer an AOSP-based system as alternative
to their normal Vendor-modified Android distribution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only supported on the Fairphone 2&lt;/li&gt;
&lt;li&gt;Fully functional (but releases sometimes introduce regressions)&lt;/li&gt;
&lt;li&gt;Standard Android Security (not hardened), no root privileges for the user&lt;/li&gt;
&lt;li&gt;Verified boot not supported; using Fairphone Open requires unlocked bootloader, bootloader itself is closed-source&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on all supported devices (no proper modem isolation, if at all)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included&lt;/li&gt;
&lt;li&gt;Support period and updates used to be regular but are lacking behind meanwhile; seems like the OEM does not receive firmware updates from the SoC vendor either, as firmware is from April 2018 and not updated anymore; installing updates is easy for end-users&lt;/li&gt;
&lt;li&gt;around 180 MB of closed-source firmware required&lt;/li&gt;
&lt;li&gt;No non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lineageos&#34;&gt;LineageOS&lt;/h2&gt;
&lt;p&gt;A custom Android distribution based on AOSP but with heavy modifications. Developed by a large community of volunteers. LineageOS also backports security patches to Android versions that are not supported by Google anymore (but only for a limited time)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;broad device support, many devices that were EOL&amp;rsquo;d by their original vendors years ago are still supported&lt;/li&gt;
&lt;li&gt;mostly functional (functional support varies strongly among devices)&lt;/li&gt;
&lt;li&gt;includes some &amp;ldquo;privacy enhancements&amp;rdquo;, however, overall lower security than on standard Android due to userdebug builds&lt;/li&gt;
&lt;li&gt;no verified boot supported (can be done manually for some Nexus/Pixel devices but quite hard and not documented at all)&lt;/li&gt;
&lt;li&gt;Modem isolation varies among devices but typically non-existent&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included by default&lt;/li&gt;
&lt;li&gt;Support period and updates highly vary between devices; updates are frequent (even daily) but often delayed due to long review processes; updates often do not cover firmware and EOL periods are not announced beforehand (e .g.: I have one device from 2012 that still receives LineageOS updates, yet, its flawed firmware didn&amp;rsquo;t receive updates since 2014); updates are easy to apply for end-users&lt;/li&gt;
&lt;li&gt;I am not aware of any devices that do not require closed-source firmware (a few devices require &amp;ldquo;only a few megabytes&amp;rdquo; of non-free firmware, others require often around 100-200 MB)&lt;/li&gt;
&lt;li&gt;Usually, no non-free software required on your computer in order to flash the system to a device (there are exceptions though)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;omnirom&#34;&gt;OmniROM&lt;/h2&gt;
&lt;p&gt;A custom Android distribution based on AOSP with moderate modifications. Developed by a community of volunteers. Similar to Lineage OS with respect to the discussed properties&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;limited device support (about half as good as in LineageOS)&lt;/li&gt;
&lt;li&gt;mostly functional (functional support varies strongly among devices)&lt;/li&gt;
&lt;li&gt;not hardened for security but slightly more secure than LineageOS due to &amp;ldquo;eng&amp;rdquo; builds by default&lt;/li&gt;
&lt;li&gt;no verified boot supported (can be done manually for some Nexus/Pixel devices but quite hard and not documented at all)&lt;/li&gt;
&lt;li&gt;Modem isolation varies among devices but typically non-existent&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included by default&lt;/li&gt;
&lt;li&gt;Support period and updates comparable to LineageOS in theory, however, many devices are EOL&amp;rsquo;d much sooner as only the most recent Android branch receives updates&lt;/li&gt;
&lt;li&gt;I am not aware of any devices that do not require closed-source firmware (a few devices require &amp;ldquo;only a few megabytes&amp;rdquo; of non-free firmware, others require often around 100-200 MB)&lt;/li&gt;
&lt;li&gt;Usually, no non-free software required on your computer in order to flash the system to a device (there are exceptions though)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;replicant&#34;&gt;Replicant&lt;/h2&gt;
&lt;p&gt;A custom Android distribution based on LineageOS 13. Developed by a tiny number of developers but strongly backed by many friendly and helpful free software enthusiasts. Progressing slowly due to lack of active developers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;only few very old devices are supported; the newest ones were popular six to seven years ago and can be easily obtained second-hand (well, rather third-hand or worse I suppose)&lt;/li&gt;
&lt;li&gt;significantly degraded functionality; Features such as GPS, Bluetooth, GPU acceleration and Wifi are not available on any of the supported devices as no free drivers for them are available (wifi, bluetooth and gps can be used with the help of external devices via USB-OTG)&lt;/li&gt;
&lt;li&gt;not hardened for security, provides insecure userdebug-builds with full root access&lt;/li&gt;
&lt;li&gt;None of the supported devices support verified boot (all require an unlocked bootloader); Even with a locked bootloader, many of the supported devices have severe security issues (e.g. storage is directly accessible via the insecure odin protocol)&lt;/li&gt;
&lt;li&gt;all devices have good signs of proper modem isolation (the project defined this aspect as important device evaluation criteria)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included&lt;/li&gt;
&lt;li&gt;Irregular updates, security patches are often heavily delayed; firmware updates are irrelevant; if available, updates can be easily installed by end-users&lt;/li&gt;
&lt;li&gt;All supported devices run completely without closed-source firmware on the main processor; non-free firmware that runs on auxiliary baseband processors is required for cellular connectivity (present in the flash of the devices already, not shipped as part of the distribution)&lt;/li&gt;
&lt;li&gt;Factory-style images available but incomplete (they rely on closed-source bootloaders and firmware already present on the devices)&lt;/li&gt;
&lt;li&gt;no non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ubports&#34;&gt;UBPorts&lt;/h2&gt;
&lt;p&gt;Shortly after Canonical announced to discontinue their effort to port Ubuntu and its Unity desktop to their mobile OS named Ubuntu Phone, a community of volunteers emerged and created UBPorts to continue the project. The project uses only the lower layers of Android and builts a completely different UI on top (same approach as FirefoxOS has tried earlier).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;supports around 13 devices, most of them rather dated (but a bit newer than those supported by Replicant)&lt;/li&gt;
&lt;li&gt;slightly degraded functionality, most stuff seems to work&lt;/li&gt;
&lt;li&gt;not hardened for security but probably still better than Android since many of its components known for never-ending security nightmares (such as the media framework) are not included&lt;/li&gt;
&lt;li&gt;None of the supported devices supports verified boot (all require an unlocked bootloader)&lt;/li&gt;
&lt;li&gt;Modem and SoC glued together on all supported devices (no proper modem isolation, if at all)&lt;/li&gt;
&lt;li&gt;Google Apps and Services are not included (and not even supported)&lt;/li&gt;
&lt;li&gt;Updates are frequent and continuously provided, but firmware updates are lacking; easy to install for end-users&lt;/li&gt;
&lt;li&gt;I am not aware of any devices that do not require closed-source firmware (a few devices require less non-free firmware than others)&lt;/li&gt;
&lt;li&gt;No non-free software required on your computer in order to flash the system to a device&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;truly-alternative-non-android-operating-systems&#34;&gt;Truly alternative, non-Android Operating Systems&lt;/h1&gt;
&lt;p&gt;There are at least three operating systems being developed that are true alternatives to Android because they are not based on Android. This is very promising, as these systems do not suffer from many of Android&amp;rsquo;s horrible design decisions and UNIX principle violations.&lt;/p&gt;
&lt;h2 id=&#34;postmarketos&#34;&gt;postmarketOS&lt;/h2&gt;
&lt;p&gt;A classic Linux distribution initially targeted at legacy smartphones that are considered obsolete by its vendors. Developed by volunteeers. Based on Alpine Linux (very lightweight). Tries to focus on devices with mainline Linux support instead of running badly outdated stock Android kernels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nice and clear architectural design&lt;/li&gt;
&lt;li&gt;classic distro packages instead of app store, daily updates&lt;/li&gt;
&lt;li&gt;not really useable yet, under heavy development (but meanwhile a few devices have already limited support for calls and text messages)&lt;/li&gt;
&lt;li&gt;emerging &amp;ldquo;support&amp;rdquo; for a large number of devices&lt;/li&gt;
&lt;li&gt;choice between several UIs (most promising to me: Plasma Mobile), however, none of them seems Production-ready yet&lt;/li&gt;
&lt;li&gt;verified boot with locked closed-source bootloaders and user-supplied keys theoretically possible (only on Nexus/Pixel devices) but not implemented yet.&lt;/li&gt;
&lt;li&gt;all software available in the regular Alpine Linux repositories is available on postmarketOS as well.&lt;/li&gt;
&lt;li&gt;free from systemd&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;maemo-leste&#34;&gt;Maemo Leste&lt;/h2&gt;
&lt;p&gt;Maemo Leste is another classic Linux distro for smartphones. It is based on Devuan GNU/Linux, targets also devices with Linux mainline support and works best on devices with keyboards.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;supports only very old but still expensive devices such as the Nokia N900&lt;/li&gt;
&lt;li&gt;already quite useable, mostly limited due to the low specs of the outdated hardware it supports&lt;/li&gt;
&lt;li&gt;supports huge amounts of software because it is based on Devuan GNU/Linux which itself is based on Debian GNU/Linux (however, most of the available software was not designed for the tiny screens of the devices supported by Maemo Leste)&lt;/li&gt;
&lt;li&gt;free from systemd&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pureos&#34;&gt;pureOS&lt;/h2&gt;
&lt;p&gt;Another &amp;ldquo;classic&amp;rdquo; Linux distribution, obviously targeted at &amp;ldquo;Librem&amp;rdquo; devices by Purism. Afaik based on a mix between Debian stable and Debian testing.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convergence approach&lt;/li&gt;
&lt;li&gt;Under heavy development (no real existing phone on which it can run)&lt;/li&gt;
&lt;li&gt;Uses a homebrew app store named &amp;ldquo;PureOS Store&amp;rdquo;&lt;/li&gt;
&lt;li&gt;No information about planned support period available yet&lt;/li&gt;
&lt;li&gt;I haven&amp;rsquo;t read anything concrete about security features such as verified boot yet&lt;/li&gt;
&lt;li&gt;based on GNOME, requires systemd&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;promising-devices-announced-for-2019&#34;&gt;Promising devices announced for 2019&lt;/h1&gt;
&lt;p&gt;I know at least of three vendors that are trying to build devices that would offer great support for running non-Android mobile operating systems on them.&lt;/p&gt;
&lt;h2 id=&#34;librem-5&#34;&gt;Librem 5&lt;/h2&gt;
&lt;p&gt;Back in mid-2018, a US-based company named Purism launched a crowdfunding campaign in order to manufacture a mobile device that would run their pureOS system. Meanwhile they shipped a few devkits, but the project is heavily delayed by several months. Here are some quick facts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rather expensive (around 600 US dollars)&lt;/li&gt;
&lt;li&gt;medium to high-end specs, fairly up-to-date i.MX 8 chipset&lt;/li&gt;
&lt;li&gt;tries to use only libre-friendly hardware with good Linux mainline support (Vivante GPU, Atheros Wifi etc.)&lt;/li&gt;
&lt;li&gt;isolated modem, implemented as add-on card (but not clear if it is also properly separated on the bus via IOMMU or similar isolation techniques)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It must be said that there are many critical voices towards Purism out there. Personally, I really appreciate that they stepped up to make the Librem 5. However, I wish their marketing would be more honest and - given the delay of their Librem 5 project - they would invest all of their energy in this thing instead of developing questionable stuff such as the Librem.One service platform. Sure, they want to deliver a product with a good usability, but I think that building the device itself is hard enough and should be accomplished first before spending resources on yet another app store or service platform.&lt;/p&gt;
&lt;h2 id=&#34;pinephone&#34;&gt;Pinephone&lt;/h2&gt;
&lt;p&gt;Shortly before FOSDEM 2019, the chinese company named Pine64 (known for their SbCs and entry-level ARM laptops) announced to build a cheap low-end mobile phone. Their CEO showed off an impressive devkit at the booth and attracted a lot of developers. Meanwhile, the postmarketOS folks seem to have made great progress towards running their system on the devkit already.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rather expensive (around 150 US dollars)&lt;/li&gt;
&lt;li&gt;well-known, mainlined Allwinner-SoC&lt;/li&gt;
&lt;li&gt;isolated modem (but not sure yet)&lt;/li&gt;
&lt;li&gt;uses Mali GPU (free driver for mainline is making good progress over the last months)&lt;/li&gt;
&lt;li&gt;freedom-friendlieness of wifi (Realtek chip on devkit) and bluetooth devices unclear&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;necunos&#34;&gt;Necunos&lt;/h2&gt;
&lt;p&gt;A company named &amp;ldquo;Necunos Solutions&amp;rdquo; from Finland aims to build a no-compromises freedom-friendly mobile device. Their philisophy seems to be perfectly aligned with other die-hard FOSS enthusiasts like those driving the Replicant project. They made a pre-order campaign for a device named Necunos NC1 that promises to deliver a hardened device for journalists and activists.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;extremely pricey (&amp;gt; 1000 US dollars)&lt;/li&gt;
&lt;li&gt;medium-level specs, based on rather old i.MX 6 chipset&lt;/li&gt;
&lt;li&gt;no modem at all (yes - seriously!)&lt;/li&gt;
&lt;li&gt;promise to make no compromises in terms of freedom-friendlieness&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They recently posted an update regarding delivery delays of their device due to one of their partners backing down from providing them with the source code of some component (they didn&amp;rsquo;t name the component). Yet they hope to ship the device in summer 2019 to the people who pre-ordered them. Regarding the OS, they take a similar approach as Pine64, trying to convince one of the free projects (such as Replicant, postmarketOS or Maemo Leste) to support their device instead of reinventing the wheel.&lt;/p&gt;
&lt;h1 id=&#34;conclusion-and-recommendations&#34;&gt;Conclusion and recommendations&lt;/h1&gt;
&lt;p&gt;Given the current situation, providing clear recommendations is hard as it highly depends on a number of factors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;your willingness to run non-free software (esp. firmware)&lt;/li&gt;
&lt;li&gt;your trust in particular SoC vendors&lt;/li&gt;
&lt;li&gt;your threat perceptions (e.g. do you see more threats from local or from remote attackers?)&lt;/li&gt;
&lt;li&gt;your willingness to wait (2019 could be the breakthrough of truly free Linux phones!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My general recommendation is to find a temporary solution for now and to wait for one of the promising devices to become available instead of &amp;ldquo;inwasting&amp;rdquo; money in a recent Android device. Vote with your wallet and stop buying new Android devices full of non-free firmware that threatens your freedom and leads to an utterly low expected lifetime!&lt;/p&gt;
&lt;p&gt;So, what could be your options for the meantime (in random order)?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;get a used device supported by Replicant (Samsung Galaxy S2, Galaxy S3 or Galaxy Note 1), live with the degraded functionality and the devices&amp;rsquo; trivial local exploitability. If you can, support development towards newer LineageOS versions to get OS-level security updates with less delays in the future.&lt;/li&gt;
&lt;li&gt;get a used Pixel device and either build AOSP yourself every month for it or give GrapheneOS a try and donate money to the developer. You will be adequately secured from local and OS-level remote attacks by regular thieves etc. and you will get OS and firmware updates every month. However, you have to fully trust the SoC platform and its (non-isolated) baseband firmware. Hopefully, a real alternative will become available soon so you will not have to pollute the environment by switching to newer devices once your device runs out of support.&lt;/li&gt;
&lt;li&gt;get one of the devices that is supported best by either postmarketOS, Maemo Leste or UBPorts and try to live with the limitations.&lt;/li&gt;
&lt;li&gt;Recycle an old device and support postmarketOS and other free software projects to help growing a free alternative to Android.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am really thrilled to see if 2019 will be finally the year of security and freedom on smartphones and other mobiles devices!&lt;/p&gt;
&lt;h1 id=&#34;references&#34;&gt;References&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[1] Not available anymore, was: &lt;a href=&#34;https://github.com/copperhead/bugtracker/issues/451&#34;&gt;https://github.com/copperhead/bugtracker/issues/451&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;a href=&#34;https://www.fsf.org/blogs/community/replicant-developers-find-and-close-samsung-galaxy-backdoor&#34;&gt;https://www.fsf.org/blogs/community/replicant-developers-find-and-close-samsung-galaxy-backdoor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fosstodon.org/web/statuses/102082833624968737&#34;&gt;Join the discussion on Mastadon (external resource)&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Site relaunch</title>
      <link>/post/100-relaunch/</link>
      <pubDate>Tue, 30 Apr 2019 21:15:00 +0000</pubDate>
      
      <guid>/post/100-relaunch/</guid>
      <description>&lt;p&gt;Around three years ago, I started a blog using the FSFE&amp;rsquo;s member services. Last year in May, I took it down for various reasons. I am happy to announce that large parts of its content are now back online - in a fresh format!&lt;/p&gt;
&lt;h1 id=&#34;joined-indieweb&#34;&gt;Joined IndieWeb&lt;/h1&gt;
&lt;p&gt;One of the reasons to shut down my blog was my discontent with Wordpress, the technology used to enable FSFE&amp;rsquo;s supporters to share their thoughts.
I evaluated various alternatives, and, finally, decided to turn the blog into a website using hugo.
Apart from using different technology, a major goal for my new online presence was to become more independent by joining the IndieWeb &lt;a href=&#34;#indieweb&#34;&gt;[1]&lt;/a&gt; movement.&lt;/p&gt;
&lt;p&gt;I support the awesome IndieWeb idea because I think that it is utterly needed these days.
This phenomenon we used to know as &amp;ldquo;the web&amp;rdquo; was such a great achievement before it was ruined by the so-called walled gardens in the course of the last years.
Luckily, each one of us can work towards restoring it to its old glory.&lt;/p&gt;
&lt;h1 id=&#34;some-content-still-missing-due-to-outstanding-updates&#34;&gt;Some content still missing due to outstanding updates&lt;/h1&gt;
&lt;p&gt;Several articles are meanwhile outdated. Instead of reposting the archived versions of these articles, I decided to create major-updated versions for some of them and to re-post them as new articles (coming soon - stay tuned). This affects the following articles&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;KVM virtualization with Allwinner A20 on Debian: libre, low-power, low-cost&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;KVM-virtualization on ARM using the virt machine type&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Further securing Nexus devices running CopperheadOS by using separate Encryption/Lockscreen passphrases&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Looking for a secure smartphone running only free software? Good luck!&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;ongoing-styling&#34;&gt;Ongoing styling&lt;/h1&gt;
&lt;p&gt;I am still in the progress of fine-tuning the visuals. Some content (like tables) are not rendered nicely yet, but I hope to improve that soon.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://indieweb.org&#34;&gt;https://indieweb.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;comments&#34;&gt;Comments&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(Comment features are provided by external parties and are not monitored by me.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fosstodon.org/web/statuses/102016828724508368&#34;&gt;Join the discussion on Mastadon (external resource)&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How a single unprivileged app can brick the whole Android system</title>
      <link>/post/060-single-android-break/</link>
      <pubDate>Tue, 10 Oct 2017 01:00:00 +0000</pubDate>
      
      <guid>/post/060-single-android-break/</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article is highly subjective and only states the author&amp;rsquo;s opinion based on actual observations and &amp;ldquo;wild&amp;rdquo; assumptions. Unlike stated in the title, it might apply only to LineageOS and not to the original AOSP. Better explanations and corrections are warmly welcome!&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;motivation&#34;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;After updating an App from the F-Droid store (OpenCamera), my Android device was completely unusable. In this state, the only feasible option for a typical end-user  to recover the device (who does not know how to get to safe mode in order to remove or downgrade the app &lt;a href=&#34;#issue2&#34;&gt;[5]&lt;/a&gt;) would have been to wipe data in recovery, loosing all data.&lt;/p&gt;
&lt;p&gt;How can such a disaster happen? In this article, I argue why I have serious doubts about the memory management approach taken in Android.&lt;/p&gt;
&lt;h1 id=&#34;the-failure&#34;&gt;The failure&lt;/h1&gt;
&lt;p&gt;After updating the OpenCamera app to the recently released version 1.42, my Android device ran into a bootloop that was hard to recover from. I was able to repeatingly reproduce the failure on a different device, namely the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Device: Samsung Galaxy S3 (i9300)&lt;/li&gt;
&lt;li&gt;ROM: Lineage OS 13 (Android 6.0), freshly built from latest sources, commit 42f4b851c9b2d08709a065c3931f6370fd78b2b0 &lt;a href=&#34;#rom&#34;&gt;[1]&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;steps-to-reproduce&#34;&gt;Steps to reproduce:&lt;/h3&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h3 id=&#34;expected&#34;&gt;Expected:&lt;/h3&gt;
&lt;p&gt;The install completes and the app is available. If installation fails (for whatever reason), an error message is shown but the device is still working&lt;/p&gt;
&lt;h3 id=&#34;actual&#34;&gt;Actual:&lt;/h3&gt;
&lt;p&gt;The install freezes, the LineageOS splash screen appears and re-initializes all apps; this happens several times and after aprox 10-15 minutes the device is back &amp;ldquo;working&amp;rdquo;; when trying to start apps they crash or even the launcher (&amp;ldquo;Trebuchet&amp;rdquo;) crashes. After rebooting the device, it is stuck in an infinite loop initializing apps.&lt;/p&gt;
&lt;h1 id=&#34;the-fault-what-happens-under-the-hood&#34;&gt;The fault (what happens under the hood?)&lt;/h1&gt;
&lt;p&gt;When installing OpenCamera, the following is printed in the log:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;12-10 14:48:30.915  4034  5483 I ActivityManager: START u0 {act=org.fdroid.fdroid.installer.DefaultInstaller.action.INSTALL_PACKAGE dat=file:///data/user/0/org.fdroid.fdroid/files/Open Camera-1.42.apk cmp=org.fdroid.fdroid/.installer.DefaultInstallerActivity (has extras)} from uid 10070 on display 0
12-10 14:48:30.915  4034  5483 W ActivityManager: startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent { act=org.fdroid.fdroid.installer.DefaultInstaller.action.INSTALL_PACKAGE dat=file:///data/user/0/org.fdroid.fdroid/files/Open Camera-1.42.apk cmp=org.fdroid.fdroid/.installer.DefaultInstallerActivity (has extras) }
12-10 14:48:30.925  4034  5483 D lights  : set_light_buttons: 2
12-10 14:48:30.955  4034  5649 I ActivityManager: START u0 {act=android.intent.action.INSTALL_PACKAGE dat=file:///data/user/0/org.fdroid.fdroid/files/Open Camera-1.42.apk cmp=com.android.packageinstaller/.PackageInstallerActivity (has extras)} from uid 10070 on display 0
12-10 14:48:31.085  6740  6740 W ResourceType: Failure getting entry for 0x7f0c0001 (t=11 e=1) (error -75)
12-10 14:48:31.700  4034  4093 I ActivityManager: Displayed com.android.packageinstaller/.PackageInstallerActivity: +724ms (total +758ms)
12-10 14:48:36.770  4034  4362 D lights  : set_light_buttons: 1
12-10 14:48:36.840  4034  4938 I ActivityManager: START u0 {dat=file:///data/user/0/org.fdroid.fdroid/files/Open Camera-1.42.apk flg=0x2000000 cmp=com.android.packageinstaller/.InstallAppProgress (has extras)} from uid 10018 on display 0
12-10 14:48:36.850  3499  3895 D audio_hw_primary: select_output_device: AUDIO_DEVICE_OUT_SPEAKER
12-10 14:48:36.955  6863  6874 D DefContainer: Copying /data/user/0/org.fdroid.fdroid/files/Open Camera-1.42.apk to base.apk
12-10 14:48:37.100  4034  4093 I ActivityManager: Displayed com.android.packageinstaller/.InstallAppProgress: +251ms
12-10 14:48:37.155  6740  6753 D OpenGLRenderer: endAllStagingAnimators on 0x486226f0 (RippleDrawable) with handle 0x48604d28
12-10 14:48:37.170  4034  4100 W ResourceType: Failure getting entry for 0x7f0c0001 (t=11 e=1) (error -75)
12-10 14:48:37.465  4034  4100 I PackageManager.DexOptimizer: Running dexopt (dex2oat) on: /data/app/vmdl872450731.tmp/base.apk pkg=net.sourceforge.opencamera isa=arm vmSafeMode=false debuggable=false oatDir = /data/app/vmdl872450731.tmp/oat bootComplete=true
12-10 14:48:37.585  7205  7205 I dex2oat : Starting dex2oat.
12-10 14:48:37.585  7205  7205 E cutils-trace: Error opening trace file: No such file or directory (2)
12-10 14:48:42.405  7205  7205 I dex2oat : dex2oat took 4.815s (threads: 4) arena alloc=5MB java alloc=2023KB native alloc=13MB free=1122KB
12-10 14:48:42.415  4034  4100 D lights  : set_light_buttons: 2
12-10 14:48:42.680  4034  4100 V BackupManagerService: restoreAtInstall pkg=net.sourceforge.opencamera token=3 restoreSet=0
12-10 14:48:42.680  4034  4100 W BackupManagerService: Requested unavailable transport: com.google.android.gms/.backup.BackupTransportService
12-10 14:48:42.680  4034  4100 W BackupManagerService: No transport
12-10 14:48:42.680  4034  4100 V BackupManagerService: Finishing install immediately
12-10 14:48:42.705  4034  4100 W Settings: Setting install_non_market_apps has moved from android.provider.Settings.Global to android.provider.Settings.Secure, returning read-only value.
12-10 14:48:42.705  4034  4100 I art     : Starting a blocking GC Explicit
12-10 14:48:42.805  4034  4100 I art     : Explicit concurrent mark sweep GC freed 52637(2MB) AllocSpace objects, 20(424KB) LOS objects, 33% free, 14MB/21MB, paused 2.239ms total 96.416ms
12-10 14:48:42.835  4034  4363 I InputReader: Reconfiguring input devices.  changes=0x00000010
12-10 14:48:42.935  5420  5420 D CarrierServiceBindHelper: Receive action: android.intent.action.PACKAGE_ADDED
12-10 14:48:42.940  5420  5420 D CarrierServiceBindHelper: mHandler: 3
12-10 14:48:42.940  5420  5420 D CarrierConfigLoader: mHandler: 9 phoneId: 0
12-10 14:48:42.945  4034  4034 F libc    : invalid address or address of corrupt block 0x120 passed to dlfree
12-10 14:48:42.945  4034  4034 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 4034 (system_server)
12-10 14:48:42.950  3496  3496 I DEBUG   : property debug.db.uid not set; NOT waiting for gdb.
12-10 14:48:42.950  3496  3496 I DEBUG   : HINT: adb shell setprop debug.db.uid 100000
12-10 14:48:42.950  3496  3496 I DEBUG   : HINT: adb forward tcp:5039 tcp:5039
12-10 14:48:42.975  3496  3496 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
12-10 14:48:42.975  3496  3496 F DEBUG   : LineageOS Version: &#39;13.0-20171125-UNOFFICIAL-i9300&#39;
12-10 14:48:42.975  3496  3496 F DEBUG   : Build fingerprint: &#39;samsung/m0xx/m0:4.3/JSS15J/I9300XXUGMJ9:user/release-keys&#39;
12-10 14:48:42.975  3496  3496 F DEBUG   : Revision: &#39;0&#39;
12-10 14:48:42.975  3496  3496 F DEBUG   : ABI: &#39;arm&#39;
12-10 14:48:42.975  3496  3496 F DEBUG   : pid: 4034, tid: 4034, name: system_server  &amp;amp;gt;&amp;amp;gt;&amp;amp;gt; system_server &amp;amp;lt;&amp;amp;lt;&amp;amp;lt;
12-10 14:48:42.975  3496  3496 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad
12-10 14:48:43.030  3496  3496 F DEBUG   : Abort message: &#39;invalid address or address of corrupt block 0x120 passed to dlfree&#39;
12-10 14:48:43.030  3496  3496 F DEBUG   :     r0 00000000  r1 00000000  r2 00000000  r3 00000002
12-10 14:48:43.030  3496  3496 F DEBUG   :     r4 00000120  r5 deadbaad  r6 404e0f38  r7 40005000
12-10 14:48:43.030  3496  3496 F DEBUG   :     r8 00000128  r9 bee01b0c  sl 40358be3  fp 40358bec
12-10 14:48:43.030  3496  3496 F DEBUG   :     ip 404db5d8  sp bee019f8  lr 404abfab  pc 404abfaa  cpsr 60070030
12-10 14:48:43.045  3496  3496 F DEBUG   : 
12-10 14:48:43.045  3496  3496 F DEBUG   : backtrace:
12-10 14:48:43.045  3496  3496 F DEBUG   :     #00 pc 00030faa  /system/lib/libc.so (dlfree+1285)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #01 pc 000158df  /system/lib/libandroidfw.so (_ZN7android13ResStringPool6uninitEv+38)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #02 pc 0001662b  /system/lib/libandroidfw.so (_ZN7android10ResXMLTree6uninitEv+12)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #03 pc 00016649  /system/lib/libandroidfw.so (_ZN7android10ResXMLTreeD1Ev+4)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #04 pc 00013373  /system/lib/libandroidfw.so (_ZN7android12AssetManager10getPkgNameEPKc+258)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #05 pc 000133cf  /system/lib/libandroidfw.so (_ZN7android12AssetManager18getBasePackageNameEj+62)
12-10 14:48:43.045  3496  3496 F DEBUG   :     #06 pc 00088b33  /system/lib/libandroid_runtime.so
12-10 14:48:43.045  3496  3496 F DEBUG   :     #07 pc 72cb9011  /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x1f78000)
12-10 14:48:50.095  3496  3496 F DEBUG   : 
12-10 14:48:50.095  3496  3496 F DEBUG   : Tombstone written to: /data/tombstones/tombstone_00
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;statusbar&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;netstats&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;power&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;media_projection&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;network_management&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;window&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;consumer_ir&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;telecom&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;cmpartnerinterface&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;package&#39; died
12-10 14:48:50.185  1912  1912 I ServiceManager: service &#39;user&#39; died
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since Open Camera needs some background service and is started on bootup, I assume that after installation the system tries to restart this service. However, it appears that there is some memory issue with the app, as it requests so much memory that Android starts killing other apps to make this memory available. In case Android does not manage to provide this space, the device is rebooted. Since OpenCamera is started at bootup, it again tries to allocate (too much) memory and the device is stuck in an infinite loop.&lt;/p&gt;
&lt;h1 id=&#34;looking-at-androids-memory-management&#34;&gt;Looking at Android&amp;rsquo;s memory management&lt;/h1&gt;
&lt;p&gt;I expected that the following excerpt from the log above might lead to some useful hints:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;12-10 14:48:42.945  4034  4034 F libc    : invalid address or address of corrupt block 0x120 passed to dlfree
12-10 14:48:42.945  4034  4034 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 4034 (system_server)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After searching on the net, I found an interesting discussion &lt;a href=&#34;#stackoverflow&#34;&gt;[2]&lt;/a&gt; suggesting the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;A likely cause of this is that you have ran out of memory, maybe because a memory leak or simply used up all memory. This can be caused by a bug you are using in a plugin that uses native C/C++ code through NDK.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To rule out hardware issues, I also exchanged the storage (I run /data from sdcard) and compiled memtester &lt;a href=&#34;#memtester&#34;&gt;[3]&lt;/a&gt; to test the device&amp;rsquo;s RAM. When experimenting with memtester, I noticed a striking difference between running memtester on a regular GNU/Linux system and running it on Android/LineageOS. When giving memtester less memory than actually available, there is no difference. However, when giving memtester &lt;em&gt;more&lt;/em&gt; RAM than acutally available, the following happens on GNU/Linux:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# free -h
            total        used        free      shared  buff/cache   available
Mem:            28G        124M         28G        8.5M        219M         28G
Swap:            0B          0B          0B
# memtester 40G
memtester version 4.3.0 (64-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 40960MB (42949672960 bytes)
got  29075MB (30488387584 bytes), trying mlock ...Killed
# 
Killed
[1]+  Stopped                 sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While on Android the device suddenly reboots after trying to mlock the memory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@i9300:/ # free -h
                total        used        free      shared     buffers
Mem:             828M        754M         74M           0        1.3M
-/+ buffers/cache:           752M         75M
Swap:            400M         18M        382M

root@i9300:/ # /sbin/memtester 2G                                              
memtester version 4.3.0 (32-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffff000
want 2048MB (2147483648 bytes)
got  2008MB (2105921536 bytes), trying mlock ...&amp;lt;/pre&amp;gt;
This is what is printed to logcat:
&amp;lt;pre&amp;gt;01-01 01:10:29.485  4933  4933 D su      : su invoked.
01-01 01:10:29.485  4933  4933 E su      : SU from: shell
01-01 01:10:29.490  4933  4933 D su      : Allowing shell.
01-01 01:10:29.490  4933  4933 D su      : 2000 /system/bin/sh executing 0 /system/bin/sh using binary /system/bin/sh : sh
01-01 01:10:29.490  4933  4933 D su      : Waiting for pid 4934.
01-01 01:10:44.840  2478  3264 D LightsService: Excessive delay setting light: 81ms
01-01 01:10:44.925  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:45.010  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:45.090  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:45.175  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:45.260  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:45.340  2478  3264 D LightsService: Excessive delay setting light: 82ms
01-01 01:10:50.735  2478  2538 I PowerManagerService: Going to sleep due to screen timeout (uid 1000)...
01-01 01:10:50.785  2478  2538 E         : Device driver API match
01-01 01:10:50.785  2478  2538 E         : Device driver API version: 29
01-01 01:10:50.785  2478  2538 E         : User space API version: 29 
01-01 01:10:50.785  2478  2538 E         : mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Tue Aug 26 17:05:16 KST 2014 
01-01 01:10:52.000  2478  2538 V KeyguardServiceDelegate: onScreenTurnedOff()
01-01 01:10:52.040  2478  2538 E libEGL  : call to OpenGL ES API with no current context (logged once per thread)
01-01 01:10:52.045  2478  2536 I DisplayManagerService: Display device changed: DisplayDeviceInfo{&amp;quot;Integrierter Bildschirm&amp;quot;: uniqueId=&amp;quot;local:0&amp;quot;, 720 x 1280, modeId 1, defaultModeId 1, supportedModes [{id=1, width=720, height=1280, fps=60.002}], colorTransformId 1, defaultColorTransformId 1, supportedColorTransforms [{id=1, colorTransform=0}], density 320, 304.8 x 306.71698 dpi, appVsyncOff 0, presDeadline 17666111, touch INTERNAL, rotation 0, type BUILT_IN, state OFF, FLAG_DEFAULT_DISPLAY, FLAG_ROTATES_WITH_CONTENT, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}
01-01 01:10:52.060  1915  1915 D SurfaceFlinger: Set power mode=0, type=0 flinger=0x411dadf0
01-01 01:10:52.160  2478  2538 I PowerManagerService: Sleeping (uid 1000)...
01-01 01:10:52.165  2478  3231 D WifiConfigStore: Retrieve network priorities after PNO.
01-01 01:10:52.170  1938  3241 E bt_a2dp_hw: adev_set_parameters: ERROR: set param called even when stream out is null
01-01 01:10:52.170  2478  3231 E native  : do suspend false
01-01 01:10:52.175  2478  3231 D WifiConfigStore: No blacklist allowed without epno enabled
01-01 01:10:52.190  3846  4968 D NfcService: Discovery configuration equal, not updating.
01-01 01:10:52.435  2478  3231 D WifiConfigStore: Retrieve network priorities before PNO. Max priority: 0
01-01 01:10:52.435  1938  1938 E bt_a2dp_hw: adev_set_parameters: ERROR: set param called even when stream out is null
01-01 01:10:52.440  2478  3231 E WifiStateMachine:  Fail to set up pno, want true now false
01-01 01:10:52.440  2478  3231 E native  : do suspend true
01-01 01:10:52.670  2478  3231 D WifiStateMachine: Disconnected CMD_START_SCAN source -2 3, 4 -&amp;amp;gt; obsolete
01-01 01:10:54.160  2478  2538 W PowerManagerService: Sandman unresponsive, releasing suspend blocker
01-01 01:10:55.825  2478  3362 D CryptdConnector: SND -&amp;amp;gt; {3 cryptfs getpw}
01-01 01:10:55.825  1903  1999 D VoldCryptCmdListener: cryptfs getpw
01-01 01:10:55.825  1903  1999 I Ext4Crypt: ext4 crypto complete called on /data
01-01 01:10:55.825  1903  1999 I Ext4Crypt: No master key, so not ext4enc
01-01 01:10:55.830  1903  1999 I Ext4Crypt: ext4 crypto complete called on /data
01-01 01:10:55.830  1903  1999 I Ext4Crypt: No master key, so not ext4enc
01-01 01:10:55.830  2478  2798 D CryptdConnector: RCV  {4 cryptfs clearpw}
01-01 01:10:55.835  1903  1999 D VoldCryptCmdListener: cryptfs clearpw
01-01 01:10:55.835  1903  1999 I Ext4Crypt: ext4 crypto complete called on /data
01-01 01:10:55.835  1903  1999 I Ext4Crypt: No master key, so not ext4enc
01-01 01:10:55.835  2478  2798 D CryptdConnector: RCV &amp;amp;lt;- {200 4 0}
01-01 01:10:55.925  3417  3417 D PhoneStatusBar: disable: 
01-01 01:10:56.020  3417  3417 D PhoneStatusBar: disable: 
01-01 01:10:56.330  3417  3417 D PhoneStatusBar: disable: 
01-01 01:11:44.875  2478  4667 I ActivityManager: Process com.android.messaging (pid 4607) has died
01-01 01:11:44.920  2478  4667 D ActivityManager: cleanUpApplicationRecord -- 4607
01-01 01:11:45.860  2478  3356 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=0 for 907ms
01-01 01:11:45.890  2478  3356 I ActivityManager: Process org.cyanogenmod.profiles (pid 4593) has died
01-01 01:11:45.900  2478  3356 D ActivityManager: cleanUpApplicationRecord -- 4593
01-01 01:11:45.955  2478  2529 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=1 for 914ms
01-01 01:11:45.960  1913  1913 E lowmemorykiller: Error opening /proc/3662/oom_score_adj; errno=2
01-01 01:11:45.970  2478  2529 I ActivityManager: Process com.android.exchange (pid 3662) has died
01-01 01:11:45.970  2478  2529 D ActivityManager: cleanUpApplicationRecord -- 3662
01-01 01:11:45.985  2478  3943 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=2 for 611ms
01-01 01:11:45.995  2478  3943 I ActivityManager: Process com.android.calendar (pid 4415) has died
01-01 01:11:45.995  2478  3943 D ActivityManager: cleanUpApplicationRecord -- 4415
01-01 01:11:46.000  2478  2532 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=3 for 537ms
01-01 01:11:46.025  2478  3362 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=4 for 378ms
01-01 01:11:46.045  2478  3362 I ActivityManager: Process org.lineageos.updater (pid 4449) has died
01-01 01:11:46.045  2478  3362 D ActivityManager: cleanUpApplicationRecord -- 4449
01-01 01:11:46.045  1913  1913 E lowmemorykiller: Error writing /proc/3938/oom_score_adj; errno=22
01-01 01:11:46.050  2478  3413 W art     : Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied() from ActivityManagerService.java:1359 waiters=5 for 372ms
01-01 01:11:46.505  2478  3232 D WifiService: Client connection lost with reason: 4
01-01 01:11:47.165  2478  4666 D GraphicsStats: Buffer count: 3
01-01 01:11:47.400  2478  2532 W art     : Long monitor contention event with owner method=int com.android.server.am.ActivityManagerService.broadcastIntent(android.app.IApplicationThread, android.content.Intent, java.lang.String, android.content.IIntentReceiver, int, java.lang.String, android.os.Bundle, java.lang.String[], int, android.os.Bundle, boolean, boolean, int) from ActivityManagerService.java:17497 waiters=0 for 667ms
01-01 01:11:47.465  2478  4664 W art     : Long monitor contention event with owner method=int com.android.server.am.ActivityManagerService.broadcastIntent(android.app.IApplicationThread, android.content.Intent, java.lang.String, android.content.IIntentReceiver, int, java.lang.String, android.os.Bundle, java.lang.String[], int, android.os.Bundle, boolean, boolean, int) from ActivityManagerService.java:17497 waiters=1 for 858ms
01-01 01:11:47.465  2478  3412 W art     : Long monitor contention event with owner method=int com.android.server.am.ActivityManagerService.broadcastIntent(android.app.IApplicationThread, android.content.Intent, java.lang.String, android.content.IIntentReceiver, int, java.lang.String, android.os.Bundle, java.lang.String[], int, android.os.Bundle, boolean, boolean, int) from ActivityManagerService.java:17497 waiters=2 for 859ms
01-01 01:11:47.475  2478  4665 I ActivityManager: Process com.android.providers.calendar (pid 4434) has died
01-01 01:11:47.480  2478  4665 D ActivityManager: cleanUpApplicationRecord -- 4434
01-01 01:11:47.545  1913  1913 E lowmemorykiller: Error opening /proc/3938/oom_score_adj; errno=2
01-01 01:11:47.545  1913  1913 E lowmemorykiller: Error opening /proc/4014/oom_score_adj; errno=2
01-01 01:11:47.550  1913  1913 E lowmemorykiller: Error opening /proc/4542/oom_score_adj; errno=2
01-01 01:11:47.550  2478  3943 W art     : Long monitor contention event with owner method=int com.android.server.am.ActivityManagerService.broadcastIntent(android.app.IApplicationThread, android.content.Intent, java.lang.String, android.content.IIntentReceiver, int, java.lang.String, android.os.Bundle, java.lang.String[], int, android.os.Bundle, boolean, boolean, int) from ActivityManagerService.java:17497 waiters=3 for 894ms
01-01 01:11:47.560  2478  3943 I ActivityManager: Process org.cyanogenmod.themes.provider (pid 3497) has died
01-01 01:11:47.560  2478  3943 D ActivityManager: cleanUpApplicationRecord -- 3497
01-01 01:11:47.560  2478  2529 W art     : Long monitor contention event with owner method=int com.android.server.am.ActivityManagerService.broadcastIntent(android.app.IApplicationThread, android.content.Intent, java.lang.String, android.content.IIntentReceiver, int, java.lang.String, android.os.Bundle, java.lang.String[], int, android.os.Bundle, boolean, boolean, int) from ActivityManagerService.java:17497 waiters=4 for 673ms
01-01 01:11:47.570  2478  2529 I ActivityManager: Process com.svox.pico (pid 4014) has died
01-01 01:11:47.570  2478  2529 D ActivityManager: cleanUpApplicationRecord -- 4014
01-01 01:11:48.325  2478  2529 W ActivityManager: Scheduling restart of crashed service com.svox.pico/.PicoService in 1000ms
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;verdict&#34;&gt;Verdict&lt;/h1&gt;
&lt;p&gt;I wasted lots of time with this issue, but was finally able to reproduce it and to recover all of my data. At least, I have an explanation now for various random reboots I experienced in the past in similar low-memory conditions.&lt;/p&gt;
&lt;p&gt;Overall, I am really shocked that a simple, unprivileged Android app that is scheduled to start on bootup can ruin a working system so badly. Further research indicates that there are more apps known to cause such behavior &lt;a href=&#34;#issue1&#34;&gt;[4]&lt;/a&gt;. I hope that a device based on a GNU/Linux system instead of Android (such as the announced Librem5) will not suffer from such a severe flaw.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://review.lineageos.org/#/c/197305/&#34;&gt;https://review.lineageos.org/#/c/197305/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://stackoverflow.com/questions/25069186/invalid-address-passed-to-dlfree&#34;&gt;https://stackoverflow.com/questions/25069186/invalid-address-passed-to-dlfree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://github.com/royzhao/memtester4Android&#34;&gt;https://github.com/royzhao/memtester4Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://gitlab.com/fdroid/fdroiddata/issues/979&#34;&gt;https://gitlab.com/fdroid/fdroiddata/issues/979&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://gitlab.com/fdroid/fdroiddata/issues/979#note_48990149&#34;&gt;https://gitlab.com/fdroid/fdroiddata/issues/979#note_48990149&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Benchmarking microSD cards and more</title>
      <link>/post/055-benchmark-microsd/</link>
      <pubDate>Sat, 20 May 2017 01:00:00 +0000</pubDate>
      
      <guid>/post/055-benchmark-microsd/</guid>
      <description>&lt;h1 id=&#34;motivation&#34;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;If you ever tried using a flash drive (such a SD, microSD, USB drive or CF) for your root or home filesystem on a small computing device or smartphone, you probably have noticed that flash cards are in most cases &lt;!-- raw HTML omitted --&gt;a lot&lt;!-- raw HTML omitted --&gt; slower than integreted eMMC flash. Since most filesystems use 4k blocks, the random write/read performance using 4k blocks is what matters most in such scenarios. And while flash cards don&amp;rsquo;t come close to internal flash in these disciplines, there are &lt;!-- raw HTML omitted --&gt;significant&lt;!-- raw HTML omitted --&gt; differences between the models.&lt;/p&gt;
&lt;p&gt;Jeff Geerling &lt;a href=&#34;#pidramble&#34;&gt;[1]&lt;/a&gt; &lt;a href=&#34;#jeffgarling&#34;&gt;[2]&lt;/a&gt; has already benchmarked the performance of various microSD cards on different models of the &amp;ldquo;blobby&amp;rdquo; Raspberry Pi. I had a number of different microSD cards at hand and I tried to replicate his results on my sample. In addition, I extended the comparison to regular SD cards and USB drives.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is worth re-visiting this page as I am going to do more benchmarks and add more results over time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this article is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this article and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event the author will be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this article.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;environment-and-tools&#34;&gt;Environment and tools&lt;/h1&gt;
&lt;p&gt;I encourage every reader to replicate my benchmarks and share their results. Therefore, I first want to describe how the measures were taken.&lt;/p&gt;
&lt;h2 id=&#34;general-equipment&#34;&gt;General equipment&lt;/h2&gt;
&lt;p&gt;For the benchmarks, I used the following hardware on my workstation (listing only relevant parts):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03)&lt;/li&gt;
&lt;li&gt;Logilink CR0034A USB 3.0 card reader &lt;a href=&#34;#logilink2&#34;&gt;[5]&lt;/a&gt;, used for (m)SD cards&lt;/li&gt;
&lt;li&gt;Apacer ? USB 2.0 card reader, used for CF cards&lt;/li&gt;
&lt;li&gt;Debian 9 &amp;ldquo;Stretch&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the past, I also did iozone benchmarks using a Logilink CR0015 USB 2.0 (m)SD card reader &lt;a href=&#34;#logilink1&#34;&gt;[4]&lt;/a&gt; which are provided at the end of the article for reference.&lt;/p&gt;
&lt;h2 id=&#34;iozone-benchmarks&#34;&gt;iozone Benchmarks&lt;/h2&gt;
&lt;p&gt;For the first tests, Just like Jeff, I used the open source (but non-free) tool &amp;ldquo;iozone&amp;rdquo; &lt;a href=&#34;#iozone&#34;&gt;[3]&lt;/a&gt; in the current stable version that is available on Debian Stretch (3.429).&lt;/p&gt;
&lt;p&gt;I disabled caches and benchmarked on raw devices to avoid measuring filesystem overhead. Therefore, I used the following call to &lt;code&gt;iozone&lt;/code&gt; to run the benchmarks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ iozone -e -I -a -s 100M -r 4k -r 16M -i 0 -i 1 -i 2 -f /dev/sdX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(replacing &lt;code&gt;sdX&lt;/code&gt; by the actual device name)&lt;/p&gt;
&lt;h2 id=&#34;ddrescue-benchmarks&#34;&gt;ddrescue benchmarks&lt;/h2&gt;
&lt;p&gt;I used &lt;code&gt;GNU ddrescue&lt;/code&gt; (1.21) in synchronous mode to overwrite a device with zeroes and measured the performance there. For this purpose, I used the following call to do a write benchmark:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ddrescue -D --force /dev/zero /dev/sdX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(replacing &lt;code&gt;sdX&lt;/code&gt; by the actual device name)&lt;/p&gt;
&lt;p&gt;Similarly, to measure the read performance I used (for media &amp;gt; 50G the test was aborted when 50G were reached; tmp was mounted as tmpfs):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ddrescue -D --force /dev/sdX /tmp/foo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(replacing &lt;code&gt;sdX&lt;/code&gt; by the actual device name)&lt;/p&gt;
&lt;h1 id=&#34;results&#34;&gt;Results&lt;/h1&gt;
&lt;h2 id=&#34;iozone&#34;&gt;iozone&lt;/h2&gt;
&lt;p&gt;Here are the iozone results (new card reader):&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Manufacturer&lt;/th&gt;
          &lt;th&gt;Make/model&lt;/th&gt;
          &lt;th&gt;Type&lt;/th&gt;
          &lt;th&gt;Speed Class&lt;/th&gt;
          &lt;th&gt;Capacity&lt;/th&gt;
          &lt;th&gt;16M seq. read (MB/s)&lt;/th&gt;
          &lt;th&gt;16M seq. write (MB/s)&lt;/th&gt;
          &lt;th&gt;4K rand. read (MB/s)&lt;/th&gt;
          &lt;th&gt;4K rand. write (MB/s)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Sandisk&lt;/td&gt;
          &lt;td&gt;Ultra&lt;/td&gt;
          &lt;td&gt;mSDXC&lt;/td&gt;
          &lt;td&gt;A1&lt;/td&gt;
          &lt;td&gt;200 GB&lt;/td&gt;
          &lt;td&gt;42.75&lt;/td&gt;
          &lt;td&gt;36.80&lt;/td&gt;
          &lt;td&gt;8.54&lt;/td&gt;
          &lt;td&gt;5.13&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Sandisk&lt;/td&gt;
          &lt;td&gt;Extreme&lt;/td&gt;
          &lt;td&gt;mSDXC&lt;/td&gt;
          &lt;td&gt;A2&lt;/td&gt;
          &lt;td&gt;64 GB&lt;/td&gt;
          &lt;td&gt;92.58&lt;/td&gt;
          &lt;td&gt;64.01&lt;/td&gt;
          &lt;td&gt;4.97&lt;/td&gt;
          &lt;td&gt;3.05&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Sandisk&lt;/td&gt;
          &lt;td&gt;Ultra&lt;/td&gt;
          &lt;td&gt;mSDXC&lt;/td&gt;
          &lt;td&gt;A1&lt;/td&gt;
          &lt;td&gt;64 GB&lt;/td&gt;
          &lt;td&gt;93.26&lt;/td&gt;
          &lt;td&gt;31.88&lt;/td&gt;
          &lt;td&gt;7.67&lt;/td&gt;
          &lt;td&gt;2.84&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Samsung&lt;/td&gt;
          &lt;td&gt;Evo+&lt;/td&gt;
          &lt;td&gt;mSDHC&lt;/td&gt;
          &lt;td&gt;U1&lt;/td&gt;
          &lt;td&gt;32 GB&lt;/td&gt;
          &lt;td&gt;89.30&lt;/td&gt;
          &lt;td&gt;25.88&lt;/td&gt;
          &lt;td&gt;10.07&lt;/td&gt;
          &lt;td&gt;3.77&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Sandisk&lt;/td&gt;
          &lt;td&gt;Ultra&lt;/td&gt;
          &lt;td&gt;mSDHC&lt;/td&gt;
          &lt;td&gt;C10&lt;/td&gt;
          &lt;td&gt;64 GB&lt;/td&gt;
          &lt;td&gt;45.75&lt;/td&gt;
          &lt;td&gt;17.34&lt;/td&gt;
          &lt;td&gt;5.26&lt;/td&gt;
          &lt;td&gt;0.94&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Here are the iozone results (old card reader):&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Here are the results using the USB 3.0 card reader or the device directly (for usb drives):&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Previously, I ran the iozone benchmarks using the USB 2.0 card reader. They might be relevant, if you are looking for a storage device which you want to put in a computing device with a slow card reader:&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;I can confirm Jeff&amp;rsquo;s results about microSD cards and would also recommend the Evo+ (both the old and the 2017 model) which have the best 4K random write performance of the sample. On the other hand, I am &lt;!-- raw HTML omitted --&gt;very&lt;!-- raw HTML omitted --&gt; disappointed about the Toshiba Exceria card. Actually running a device on this card with a very sluggish performance was the reason why I took this benchmark initiative. And indeed, after switching to the Evo+, the device feels much snappier now.&lt;/p&gt;
&lt;p&gt;Of course, it would be worthwhile to add more cards and drives to this benchmark. Also, using fio instead of the non-free iozone might be interesting. Furthermore, doing the benchmarks internally on the device or using a other USB 3.0 card readers might be also interesting.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;http://www.pidramble.com/wiki/benchmarks/microsd-cards&#34;&gt;http://www.pidramble.com/wiki/benchmarks/microsd-cards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;http://www.jeffgeerling.com/blogs/jeff-geerling/raspberry-pi-microsd-card&#34;&gt;http://www.jeffgeerling.com/blogs/jeff-geerling/raspberry-pi-microsd-card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;http://www.iozone.org/&#34;&gt;http://www.iozone.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[4] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;http://www.logilink.eu/Products_LogiLink/Notebook-Computer_Accessories/Card_Reader/Cardreader_USB_20_Stick_external_for_SD-MMC_CR0015.htm&#34;&gt;http://www.logilink.eu/Products_LogiLink/Notebook-Computer_Accessories/Card_Reader/Cardreader_USB_20_Stick_external_for_SD-MMC_CR0015.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[5] &lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;http://www.logilink.org/Produkte_LogiLink/Notebook-Computerzubehoer/Kartenleser/Cardreader_USB_30_SD-SD-HC-Micro_SD-Micro_SD-HC_CR0034A.htm?seticlanguage=en&#34;&gt;http://www.logilink.org/Produkte_LogiLink/Notebook-Computerzubehoer/Kartenleser/Cardreader_USB_30_SD-SD-HC-Micro_SD-Micro_SD-HC_CR0034A.htm?seticlanguage=en&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Backing up and restoring data on Android devices directly via USB</title>
      <link>/post/050-android-backup-restore/</link>
      <pubDate>Wed, 02 Nov 2016 01:00:00 +0000</pubDate>
      
      <guid>/post/050-android-backup-restore/</guid>
      <description>&lt;h1 id=&#34;motivation&#34;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;I was looking for a simple way to backup data on rooted Android devices directly to a device running GNU/Linux connected over a USB cable (in my case, a desktop computer). In the following, I describe two ways how this can be accomplished.&lt;/p&gt;
&lt;p&gt;Is this really so unique that it&amp;rsquo;s worth writing a new article about it? Well, in my case, I did not want to buffer the data on any &amp;ldquo;intermediate&amp;rdquo; devices such as storage cards connected via microSD or USB-OTG. Also, I did not want to use any proprietary tools or formats. Instead, I wanted to store my backups in &amp;ldquo;oldschool&amp;rdquo; formats such as dd-images or tar archives. I did not find a comprehensive howto for that, so I decided to write this article.&lt;/p&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;All data and information provided in this article is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this article and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In no event the author we be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this article.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;
&lt;p&gt;This article describes two different approaches. Both have their pros and cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Block-level:&lt;/strong&gt; Doing 1:1 block-level backups (above the file system) is an imaging approach that corresponds to doing dd-style backups.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filesystem-level:&lt;/strong&gt; Doing filesystem-level backups (on the file system) corresponds to tar-style backups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An important factor when doing backups is also performance. Filesystem-level backups are usually faster on block devices which are only filled up to a small degree. However, due to the file system overhead they have a lower &amp;ldquo;raw&amp;rdquo; throughput rate &amp;mdash; especially when backing up data on flash media such as microSD cards. Here, typical filesystems such as ext4 or f2fs operating with a 4K block size are a major bottleneck as these media often have horrible 4k write/read performance.&lt;/p&gt;
&lt;p&gt;The following instructions for applying these approaches assume that you already have a &amp;ldquo;liberated&amp;rdquo; Android device which can boot into TWRP (a free Android recovery) or CWM. I am using the example of a Nexus-S running Replicant 4.2.0004 and TWRP 2.8.7.0, but the approaches also work with most other Android distributions and recoveries.&lt;/p&gt;
&lt;h1 id=&#34;getting-familiar-with-the-block-devices-on-your-android-device&#34;&gt;Getting familiar with the block devices on your Android device&lt;/h1&gt;
&lt;p&gt;First of all, you should know which block device you actually want to backup. The internal flash on Android devices is usually partitioned in about 15-25 partitions, depending on the device. To get a first overview, you can try the following (I am using adb shell on the desktop):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb shell cat /proc/partitions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;major minor  #blocks  name

  31        0       2048 mtdblock0
  31        1       1280 mtdblock1
  31        2       8192 mtdblock2
  31        3       8192 mtdblock3
  31        4     480768 mtdblock4
  31        5      13824 mtdblock5
  31        6       6912 mtdblock6
 179        0   15552512 mmcblk0
 179        1     524288 mmcblk0p1
 179        2    1048576 mmcblk0p2
 179        3   13978607 mmcblk0p3
 179       16       1024 mmcblk0boot1
 179        8       1024 mmcblk0boot0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To find out what the partitions are about you can inspect the directory &lt;code&gt;/dev/block/platform//by-Name/&lt;/code&gt; which contains symlinks to the actual partitions. In my case, the Nexus-S has two flash chips and I am listing the partitions of the one where the userdata-partition resides on:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb shell ls -l /dev/block/platform/s3c-sdhci.0/by-name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lrwxrwxrwx root     root              2016-11-02 19:51 media -&amp;gt; /dev/block/mmcblk0p3
lrwxrwxrwx root     root              2016-11-02 19:51 system -&amp;gt; /dev/block/mmcblk0p1
lrwxrwxrwx root     root              2016-11-02 19:51 userdata -&amp;gt; /dev/block/mmcblk0p2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please note that unlike the Nexus-S, most newer Android devices only have a single eMMC flash chip and don&amp;rsquo;t use MTD devices anymore.&lt;/p&gt;
&lt;h1 id=&#34;block-level-approach&#34;&gt;Block-level approach&lt;/h1&gt;
&lt;p&gt;Block-level backups take up a lot of space (without compression) and extracting single files is cumbersome (especially when talking about encrypted data partitions or backups of the whole flash). On the other hand, &amp;ldquo;just&amp;rdquo; restoring a full backup is easy.&lt;/p&gt;
&lt;h2 id=&#34;backing-up-a-single-partition&#34;&gt;Backing up a single partition&lt;/h2&gt;
&lt;p&gt;Now that you know which block devices you want to backup, you can directly create a 1:1 image via &lt;code&gt;adb pull&lt;/code&gt; as you would normally do by using &lt;code&gt;dd&lt;/code&gt;. In our case:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb pull /dev/block/platform/s3c-sdhci.0/by-name/userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;7942 KB/s (1073741824 bytes in 132.027s)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On your workstation, you will obtain a file named &lt;code&gt;userdata&lt;/code&gt; which contains the whole partition/filesystem as an image. If you didn&amp;rsquo;t enable encryption on your Android device, you can directly mount this file as loopback device and access its contents:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mount userdata /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;restoring-a-single-partition&#34;&gt;Restoring a single partition&lt;/h2&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;To restore your backup, you can simply use &lt;!-- raw HTML omitted --&gt;adb push&lt;!-- raw HTML omitted --&gt;. In my case:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb push userdata /dev/block/platform/s3c-sdhci.0/by-name/userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, since adb seems to put the file in RAM first before writing it to the target this only works if your partition fits in RAM. Otherwise, you are likely to get a message such as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;failed to copy &#39;userdata&#39; to &#39;/dev/block/platform/s3c-sdhci.0/by-name/userdata&#39;: No space left on device
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One way to fix this is by using netcat. First, run the following on the receiver side (the phone):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# busybox nc -lp 5555 &amp;gt; /dev/block/platform/s3c-sdhci.0/by-name/userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And on the machine where you have stored your backup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb forward tcp:4444 tcp:5555
$ cat userdata | nc -q 2 localhost 4444
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, you can also pipe the &lt;code&gt;nc&lt;/code&gt; command through &lt;code&gt;pv&lt;/code&gt; if you have this installed to get a nice progress bar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat userdata | pv | nc -q 2 localhost 4444
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;alternative-operating-on-the-whole-block-device&#34;&gt;Alternative: Operating on the whole block device&lt;/h2&gt;
&lt;p&gt;Instead of backing up just a single partition, it is also possible to backup the whole flash device including all partitions. Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb pull /dev/block/mmcblk0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remarks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On some devices, not all partitions are readable and, thus, cannot be backed up.&lt;/li&gt;
&lt;li&gt;Please be careful with restores!&lt;/li&gt;
&lt;li&gt;Accessing files inside this image is not straight-forward (but doable).&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;filesystem-level-approach&#34;&gt;Filesystem-level approach&lt;/h1&gt;
&lt;p&gt;Filesystem-level backups only work for single partitions, take up as much space as the files on the particular filesystem you backup and it is easy to access individual files in them. I am using a combination of &lt;code&gt;adb&lt;/code&gt;, &lt;!-- raw HTML omitted --&gt;netcat&lt;!-- raw HTML omitted --&gt; and &lt;code&gt;tar&lt;/code&gt; to create and restore these backups.&lt;/p&gt;
&lt;h2 id=&#34;backing-up-your-data&#34;&gt;Backing up your data&lt;/h2&gt;
&lt;p&gt;First, connect to your device via an adb shell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb shell
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, change to the directory from where you want to create your backup. If your device was not automatically mounted, you have to do it first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mount /dev/block/platform/s3c-sdhci.0/by-name /data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now change to this directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cd /data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, start the netcat process:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# tar -cvp . | busybox nc -lp 5555
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the receiver side (desktop), set up adb port forwarding:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb forward tcp:4444 tcp:5555
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, start the process to receive the tar file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nc -w 10 localhost 4444 &amp;gt; userdata.tar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see your files being packed up on the Android side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./
./lost+found/
./dontpanic/
./misc/
./misc/adb/
./misc/audit/
./misc/audit/audit.log
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now wait for the process to exit.&lt;/p&gt;
&lt;h2 id=&#34;restoring-your-data&#34;&gt;Restoring your data&lt;/h2&gt;
&lt;p&gt;Again, on your receiver side (Android device), mount &lt;!-- raw HTML omitted --&gt;/data&lt;!-- raw HTML omitted --&gt; if it was not mounted yet and change in there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mount /dev/block/platform/s3c-sdhci.0/by-name /data
# cd /data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, start the tar extraction process:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# busybox nc -lp 5555 | tar -xpvf -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the sender side (desktop), again, set up adb port forwarding:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ adb forward tcp:4444 tcp:5555
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And send the tar file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat userdata.tar | nc -q 2 localhost 4444
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you should be able to see your previously backed up files getting restored&amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;history--changelog&#34;&gt;History / Changelog&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;[2022-08-26] Add nc method to section about restoring single partitions so it works for larger partitions as well&lt;/li&gt;
&lt;li&gt;[2016-11-02] Initial version&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For the filesystem-level part of the article I used and adapted the following sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.screenage.de/blog/2007/12/30/using-netcat-and-tar-for-network-file-transfer/&#34;&gt;http://www.screenage.de/blog/2007/12/30/using-netcat-and-tar-for-network-file-transfer/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://stackoverflow.com/questions/15278587/pipe-into-adb-shell&#34;&gt;http://stackoverflow.com/questions/15278587/pipe-into-adb-shell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>About</title>
      <link>/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/about/</guid>
      <description>&lt;h1 id=&#34;this-website&#34;&gt;This website&lt;/h1&gt;
&lt;p&gt;The purpose of this personal website is to share thoughts and experience with family and friends.
Most content is related to technology and free software.&lt;/p&gt;
&lt;h1 id=&#34;contact&#34;&gt;Contact&lt;/h1&gt;
&lt;p&gt;The best way to contact me is to drop me an e-mail:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kuleszdl@posteo.org
GPG fingerprint 1CBC E794 81ED 51EC 49FC  C064 0ACA DAB3 8FB6 4240
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can obtain my public key &lt;a href=&#34;/pubkey.asc&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;technology-and-typography-used&#34;&gt;Technology and Typography used&lt;/h1&gt;
&lt;p&gt;This site was built using Hugo &lt;a href=&#34;#hugo&#34;&gt;[1]&lt;/a&gt; and the Indigo theme &lt;a href=&#34;#indigo&#34;&gt;[2]&lt;/a&gt; by Angelo Stavrow &lt;a href=&#34;#angelo&#34;&gt;[3]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It makes use of the following wonderful typefaces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fira Sans for heading text&lt;/li&gt;
&lt;li&gt;Charter for body text&lt;/li&gt;
&lt;li&gt;Fira Code for monospaced text&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Licenses are included in the Indigo theme’s static/fonts folder.&lt;/p&gt;
&lt;h1 id=&#34;external-references&#34;&gt;External References&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://gohugo.io/&#34;&gt;https://gohugo.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://github.com/AngeloStavrow/indigo&#34;&gt;https://github.com/AngeloStavrow/indigo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://angelostavrow.com&#34;&gt;https://angelostavrow.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Legal notice</title>
      <link>/legal-notice/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/legal-notice/</guid>
      <description>&lt;h1 id=&#34;audience-and-authorship&#34;&gt;Audience and authorship&lt;/h1&gt;
&lt;p&gt;This is a personal website that is adressed to family and friends of the author.
For the sake of convenience, access to it is not technically restricted.
The content was authored by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Daniel Kulesz
kuleszdl@posteo.org
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;trademarks-and-product-names&#34;&gt;Trademarks and product names&lt;/h1&gt;
&lt;p&gt;All product names and trademarks are the property of their respective owners, which are in no way associated or affiliated with this website. Product names are used solely for the purpose of identifying the specific products. Use of these names does not imply any co-operation or endorsement.&lt;/p&gt;
&lt;h1 id=&#34;liability-for-content&#34;&gt;Liability for content&lt;/h1&gt;
&lt;p&gt;The content on this website is not monitored permanently nor scanned for evidence that indicates illegal activities.
Illegal content can only be removed or blocked given the knowledge about a specific violation.
If you should encounter illegal content on this website, please use the contact information above to notify me.
Illegal content will be removed as soon as possible after I become aware of it.&lt;/p&gt;
&lt;h1 id=&#34;liability-for-links&#34;&gt;Liability for links&lt;/h1&gt;
&lt;p&gt;This website includes links to external websites and other content that is provided by third parties.
Since I have no influence on these external ressources, no warranty about them can be made.
Instead, the providers of these ressources are solely responsible for their content.&lt;/p&gt;
&lt;p&gt;All links to external ressources have been checked at the time of linking and no reasonable indications of illegal content were detected.
However, while it is impossible for me to monitor the content of these linked ressources, I will remove links to any illegal ressources as soon as possible once I become aware of them.&lt;/p&gt;
&lt;h1 id=&#34;license&#34;&gt;License&lt;/h1&gt;
&lt;p&gt;Unless stated otherwise, the textual content on kulesz.me created by the author is licensed under the &lt;a href=&#34;/license&#34;&gt;Creative Commons Attribution-ShareAlike 4.0 International Public License (CC-BY-SA 4.0)&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>License</title>
      <link>/license/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/license/</guid>
      <description>&lt;h3 id=&#34;creative-commons-attribution-sharealike-40-international-public-license&#34;&gt;Creative Commons Attribution-ShareAlike 4.0 International Public License&lt;/h3&gt;
&lt;p&gt;By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License (&amp;ldquo;Public License&amp;rdquo;). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Section 1 – Definitions.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Adapted Material&lt;/strong&gt; means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adapter&amp;rsquo;s License&lt;/strong&gt; means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BY-SA Compatible License&lt;/strong&gt; means a license listed at [ creativecommons.org/compatiblelicenses][4], approved by Creative Commons as essentially the equivalent of this Public License.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copyright and Similar Rights&lt;/strong&gt; means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Effective Technological Measures&lt;/strong&gt; means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exceptions and Limitations&lt;/strong&gt; means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;License Elements&lt;/strong&gt; means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licensed Material&lt;/strong&gt; means the artistic or literary work, database, or other material to which the Licensor applied this Public License.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licensed Rights&lt;/strong&gt; means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licensor&lt;/strong&gt; means the individual(s) or entity(ies) granting rights under this Public License.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Share&lt;/strong&gt; means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sui Generis Database Rights&lt;/strong&gt; means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You&lt;/strong&gt; means the individual or entity exercising the Licensed Rights under this Public License. &lt;strong&gt;Your&lt;/strong&gt; has a corresponding meaning.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 2 – Scope.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;License grant&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;reproduce and Share the Licensed Material, in whole or in part; and&lt;/li&gt;
&lt;li&gt;produce, reproduce, and Share Adapted Material.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Term. The term of this Public License is specified in Section 6(a).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Downstream recipients.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.&lt;/li&gt;
&lt;li&gt;Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter&amp;rsquo;s License You apply.&lt;/li&gt;
&lt;li&gt;No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Other rights&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.&lt;/li&gt;
&lt;li&gt;Patent and trademark rights are not licensed under this Public License.&lt;/li&gt;
&lt;li&gt;To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 3 – License Conditions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Your exercise of the Licensed Rights is expressly made subject to the following conditions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Attribution&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If You Share the Licensed Material (including in modified form), You must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;retain the following if it is supplied by the Licensor with the Licensed Material:
&lt;ol&gt;
&lt;li&gt;identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);&lt;/li&gt;
&lt;li&gt;a copyright notice;&lt;/li&gt;
&lt;li&gt;a notice that refers to this Public License;&lt;/li&gt;
&lt;li&gt;a notice that refers to the disclaimer of warranties;&lt;/li&gt;
&lt;li&gt;a URI or hyperlink to the Licensed Material to the extent reasonably practicable;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;indicate if You modified the Licensed Material and retain an indication of any previous modifications; and&lt;/li&gt;
&lt;li&gt;indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ShareAlike&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. The Adapter&#39;s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the Adapter&#39;s License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter&#39;s License You apply.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Section 4 – Sui Generis Database Rights.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;&lt;/li&gt;
&lt;li&gt;if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and&lt;/li&gt;
&lt;li&gt;You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 5 – Disclaimer of Warranties and Limitation of Liability.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 6 – Term and Termination.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or&lt;/li&gt;
&lt;li&gt;upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sections 1, 5, 6, 7, and 8 survive termination of this Public License.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 7 – Other Terms and Conditions.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.&lt;/li&gt;
&lt;li&gt;Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Section 8 – Interpretation.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.&lt;/li&gt;
&lt;li&gt;To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.&lt;/li&gt;
&lt;li&gt;No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.&lt;/li&gt;
&lt;li&gt;Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;The text of this license has been obtained from &lt;a href=&#34;#origin&#34;&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;external-resources&#34;&gt;External Resources&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;(The providers of these resources are solely responsible for them - see &lt;a href=&#34;/legal-notice&#34;&gt;legal notice&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt; &lt;a href=&#34;https://creativecommons.org/licenses/by-sa/4.0/legalcode&#34;&gt;https://creativecommons.org/licenses/by-sa/4.0/legalcode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Privacy Policy</title>
      <link>/privacy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/privacy/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;PLEASE NOTE: Unlike other content on this website, the following text is &lt;strong&gt;NOT&lt;/strong&gt; licensed under the CC-BY-SA 4.0 license!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;
&lt;p&gt;The following gives a simple overview about what happens to personal information (any data that could be used to personally identify you) that is transmitted when you visit my website.&lt;/p&gt;
&lt;h1 id=&#34;party-responsible-for-this-website&#34;&gt;Party responsible for this website&lt;/h1&gt;
&lt;p&gt;The party responsible for processing data on this website is (me):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Daniel Kulesz
kuleszdl@posteo.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am the natural person who alone or jointly with others decides on the purpose and means of processing personal data (names, email addresses, etc.).&lt;/p&gt;
&lt;h1 id=&#34;general&#34;&gt;General&lt;/h1&gt;
&lt;p&gt;As the operator of this website, I take the protection of your personal data seriously.
Thus, all personal data is used in accordance to applicable data protection regulations and this privacy policy.&lt;/p&gt;
&lt;p&gt;Please note that data transmitted over the internet (e.g. between your device and this website or via e-mail) may be subject to security breaches.
Complete protection of your data from third-party access is impossible.&lt;/p&gt;
&lt;p&gt;If you access this website, you transfer data to my web server via your client (typically your web browser).
The following data is recorded whilst a connection is established:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IP address of the accessing computer&lt;/li&gt;
&lt;li&gt;Date and time of the access&lt;/li&gt;
&lt;li&gt;Name, URL and transferred data quantity of the accessed file&lt;/li&gt;
&lt;li&gt;Access status (requested file transferred, not found etc.)&lt;/li&gt;
&lt;li&gt;Browser type and operating system (only if not turned off in your web browser)&lt;/li&gt;
&lt;li&gt;Website from which the access took place (if transferred by your web browser)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The temporary storage of the IP address in the memory of my webserver is necessary in order to deliver the website to your device.
This storage is automatically emptied once the session has expired.&lt;/p&gt;
&lt;p&gt;The webserver also logs all accesses in a permanent logfile to ensure the security of the IT systems that I operate to provide this website.
The data stored in the log files is anonymized after seven days by shortening the IP addresses.&lt;/p&gt;
&lt;p&gt;The processing of the data in this log file takes place as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The log entries are randomly evaluated in order to recognize attacks against the web server.&lt;/li&gt;
&lt;li&gt;In individual cases, i.e. in case of reported disruptions, errors and security breaches, a manual analysis is conducted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IP addresses contained in the log entries are not combined with other data inventories unless required by law, i.e. if relevant authorities and/or courts make valid inquiries to which I am obliged to respond.
Also, I reserve the right to share the log files with investigative bodies of the state (for example the police, criminal prosecution authorities) in case attacks on my IT systems are detected.&lt;/p&gt;
&lt;p&gt;The legal basis is Article 6 Paragraph 1 Letter f) GDPR.&lt;/p&gt;
&lt;h1 id=&#34;ssltls-encryption&#34;&gt;SSL/TLS encryption&lt;/h1&gt;
&lt;p&gt;To enhance security and privacy, this website is only reachable using SSL or TLS encryption.
This makes it harder - but not necessarily impossible - for unauthorized third parties to read the data that is transmitted between this website and your device.&lt;/p&gt;
&lt;h1 id=&#34;no-use-of-cookies&#34;&gt;No use of Cookies&lt;/h1&gt;
&lt;p&gt;This website does not use cookies.&lt;/p&gt;
&lt;h1 id=&#34;no-use-of-plugins&#34;&gt;No use of Plugins&lt;/h1&gt;
&lt;p&gt;This website uses only HTML, CSS and JavaScript and does not require the use of any browser plugins.&lt;/p&gt;
&lt;h1 id=&#34;no-use-of-external-data-analytics-or-other-third-party-services&#34;&gt;No use of external Data Analytics or other third party services&lt;/h1&gt;
&lt;p&gt;The data transmitted to this website is not shared with third parties such as external data analytics providers.
Instead, all data analytics of log files are conducted on devices that are operated by the author.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>