<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on SROEMER</title>
    <link>/posts/</link>
    <description>Recent content in Posts on SROEMER</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>Stefan Römer</copyright>
    <lastBuildDate>Mon, 13 Jan 2025 01:00:00 +0700</lastBuildDate><atom:link href="/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Building a custom firmware for the Banana Pi BPI-F3</title>
      <link>/posts/2025/01/bpi-f3_fw_build/</link>
      <pubDate>Mon, 13 Jan 2025 01:00:00 +0700</pubDate>
      
      <guid>/posts/2025/01/bpi-f3_fw_build/</guid>
      <description>&lt;p&gt;I started building the firmware components for booting the &lt;code&gt;BPI-F3&lt;/code&gt; myself. While &lt;code&gt;SpacemiT&lt;/code&gt; provides the source code
of the different components the official firmware is built from forks of older versions and without the
commit history. In my attempt to build a custom firmware I will use mainline versions where possible and
otherwise create my own forks from mainline sources and merge necessary changes into it.&lt;/p&gt;
&lt;p&gt;Contents:
&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&#34;#status&#34;&gt;Status&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#bootinfo&#34;&gt;Bootinfo&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#fsbl-u-boot-spl&#34;&gt;FSBL (U-Boot SPL)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#opensbi&#34;&gt;OpenSBI&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#u-boot&#34;&gt;U-Boot&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;&lt;/p&gt;</description>
      <content>&lt;p&gt;I started building the firmware components for booting the &lt;code&gt;BPI-F3&lt;/code&gt; myself. While &lt;code&gt;SpacemiT&lt;/code&gt; provides the source code
of the different components the official firmware is built from forks of older versions and without the
commit history. In my attempt to build a custom firmware I will use mainline versions where possible and
otherwise create my own forks from mainline sources and merge necessary changes into it.&lt;/p&gt;
&lt;p&gt;Contents:
&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&#34;#status&#34;&gt;Status&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#bootinfo&#34;&gt;Bootinfo&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#fsbl-u-boot-spl&#34;&gt;FSBL (U-Boot SPL)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#opensbi&#34;&gt;OpenSBI&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#u-boot&#34;&gt;U-Boot&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;&lt;/p&gt;
&lt;h1 id=&#34;status&#34;&gt;Status&lt;/h1&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;name&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;build&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;test&lt;/th&gt;
          &lt;th&gt;comment&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;bootinfo&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;✅&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;✅&lt;/td&gt;
          &lt;td&gt;generated files are identical to vendor files&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;fsbl&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;❌&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;❌&lt;/td&gt;
          &lt;td&gt;no build yet&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;opensbi&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;✅&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;✅&lt;/td&gt;
          &lt;td&gt;boot ok (opensbi messages shown in console)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;u-boot&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;✅&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;❌&lt;/td&gt;
          &lt;td&gt;doesn&amp;rsquo;t boot linux and only detects 4GB RAM&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id=&#34;bootinfo&#34;&gt;Bootinfo&lt;/h1&gt;
&lt;p&gt;The first part of the boot process we have control of is the &lt;code&gt;bootinfo&lt;/code&gt; binary. In the &lt;code&gt;SpacemiT&lt;/code&gt; &lt;code&gt;BSP&lt;/code&gt;
&lt;a href=&#34;https://gitee.com/bianbu-linux&#34;&gt;Bianbu Linux&lt;/a&gt; the &lt;code&gt;bootinfo&lt;/code&gt; is generated by a Python script during
the build of &lt;a href=&#34;https://gitee.com/bianbu-linux/uboot-2022.10&#34;&gt;u-boot&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With &lt;a href=&#34;https://github.com/sroemer/bpif3_gen_binary&#34;&gt;bpif3_gen_binary&lt;/a&gt; I extracted and slightly modified this
script and according configuration files to be used independent from the &lt;code&gt;u-boot&lt;/code&gt; source tree.&lt;/p&gt;
&lt;p&gt;The content of the generated &lt;code&gt;bootinfo&lt;/code&gt; is specified in a &lt;code&gt;JSON&lt;/code&gt; file and could be modified.
However, currently I do not see a need for that.&lt;/p&gt;
&lt;h1 id=&#34;fsbl-u-boot-spl&#34;&gt;FSBL (U-Boot SPL)&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;FSBL&lt;/code&gt; (First Stage Boot Loader) is generated by the same script as the &lt;code&gt;bootinfo&lt;/code&gt; but requires &lt;code&gt;u-boot-spl.bin&lt;/code&gt; at a path
specified in the according &lt;code&gt;JSON&lt;/code&gt; configuration file.&lt;/p&gt;
&lt;p&gt;While mainline &lt;code&gt;u-boot&lt;/code&gt; already has support for the &lt;code&gt;BPI-F3&lt;/code&gt;, it only generates a &lt;code&gt;u-boot proper&lt;/code&gt; stage
but not a &lt;code&gt;u-boot spl&lt;/code&gt; stage.&lt;/p&gt;
&lt;h1 id=&#34;opensbi&#34;&gt;OpenSBI&lt;/h1&gt;
&lt;p&gt;Mainline &lt;a href=&#34;https://github.com/riscv-software-src/opensbi&#34;&gt;OpenSBI&lt;/a&gt; does not have support for the &lt;code&gt;SpacemiT K1&lt;/code&gt; (yet).
Luckily &lt;a href=&#34;https://github.com/cyyself&#34;&gt;cyyself&lt;/a&gt; already merged support for the &lt;code&gt;SoC&lt;/code&gt; into a clean fork of &lt;code&gt;OpenSBI&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With &lt;a href=&#34;https://github.com/sroemer/bpif3_opensbi&#34;&gt;bpif3_opensbi&lt;/a&gt; I merged &lt;a href=&#34;https://github.com/cyyself/opensbi/tree/k1-opensbi&#34;&gt;his work&lt;/a&gt;
on to the latest version of mainline &lt;code&gt;OpenSBI&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;u-boot&#34;&gt;U-Boot&lt;/h1&gt;
&lt;p&gt;Mainline &lt;a href=&#34;https://github.com/u-boot/u-boot&#34;&gt;u-boot&lt;/a&gt; has support for the &lt;code&gt;BPI-F3&lt;/code&gt;. It lacks support for the &lt;code&gt;u-boot spl&lt;/code&gt;
stage but builds the &lt;code&gt;u-boot proper&lt;/code&gt; main stage.&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Getting started with the Banana Pi BPI-F3</title>
      <link>/posts/2025/01/bpi-f3/</link>
      <pubDate>Fri, 10 Jan 2025 00:20:00 +0700</pubDate>
      
      <guid>/posts/2025/01/bpi-f3/</guid>
      <description>&lt;p&gt;I recently bought an &lt;a href=&#34;https://docs.banana-pi.org/en/BPI-F3/BananaPi_BPI-F3&#34;&gt;Banana Pi BPI-F3&lt;/a&gt;.
The BPI-F3 is a development board based on an
&lt;a href=&#34;https://docs.banana-pi.org/en/BPI-F3/SpacemiT_K1_datasheet&#34;&gt;SpacemiT K1&lt;/a&gt; 8-core RISC-V chip.&lt;/p&gt;
&lt;p&gt;Here I will write up how I get it up and running. My plan is to build a custom Gentoo linux
image for it - but that&amp;rsquo;s a long way to go. At first I will connect everything and use an
existing image.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BPI-F3&lt;/li&gt;
&lt;li&gt;12V Power Supply&lt;/li&gt;
&lt;li&gt;USB to serial adapter (3.3V TTL)&lt;/li&gt;
&lt;li&gt;USB-C to USB-A cable for connecting the BPI-F3 to the host&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Contents:
&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&#34;#serial-console&#34;&gt;1 - Serial console&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href=&#34;#11-connecting-a-usb-to-serial-adapter&#34;&gt;1.1 Connecting a USB to serial adapter&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#12-output-with-empty-emmc-and-no-sd-card-inserted&#34;&gt;1.2 Output with empty eMMC and no SD card inserted&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#install-image&#34;&gt;2 - Installing an image&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href=&#34;#boot-select&#34;&gt;2.1 - Boot selection settings&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#download-mode&#34;&gt;2.2 - Enter download mode&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#fastboot-mode&#34;&gt;2.3 - Enter U-Boot fastboot mode&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#flash-emmc&#34;&gt;2.4 - Flash eMMC&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#3---what-to-do-next&#34;&gt;3 - What to do next?&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;&lt;/p&gt;</description>
      <content>&lt;p&gt;I recently bought an &lt;a href=&#34;https://docs.banana-pi.org/en/BPI-F3/BananaPi_BPI-F3&#34;&gt;Banana Pi BPI-F3&lt;/a&gt;.
The BPI-F3 is a development board based on an
&lt;a href=&#34;https://docs.banana-pi.org/en/BPI-F3/SpacemiT_K1_datasheet&#34;&gt;SpacemiT K1&lt;/a&gt; 8-core RISC-V chip.&lt;/p&gt;
&lt;p&gt;Here I will write up how I get it up and running. My plan is to build a custom Gentoo linux
image for it - but that&amp;rsquo;s a long way to go. At first I will connect everything and use an
existing image.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BPI-F3&lt;/li&gt;
&lt;li&gt;12V Power Supply&lt;/li&gt;
&lt;li&gt;USB to serial adapter (3.3V TTL)&lt;/li&gt;
&lt;li&gt;USB-C to USB-A cable for connecting the BPI-F3 to the host&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Contents:
&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&#34;#serial-console&#34;&gt;1 - Serial console&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href=&#34;#11-connecting-a-usb-to-serial-adapter&#34;&gt;1.1 Connecting a USB to serial adapter&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#12-output-with-empty-emmc-and-no-sd-card-inserted&#34;&gt;1.2 Output with empty eMMC and no SD card inserted&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#install-image&#34;&gt;2 - Installing an image&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href=&#34;#boot-select&#34;&gt;2.1 - Boot selection settings&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#download-mode&#34;&gt;2.2 - Enter download mode&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#fastboot-mode&#34;&gt;2.3 - Enter U-Boot fastboot mode&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#flash-emmc&#34;&gt;2.4 - Flash eMMC&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#3---what-to-do-next&#34;&gt;3 - What to do next?&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;&lt;/p&gt;
&lt;h1 id=&#34;serial-console&#34;&gt;1 - Serial console&lt;/h1&gt;
&lt;h2 id=&#34;11-connecting-a-usb-to-serial-adapter&#34;&gt;1.1 Connecting a USB to serial adapter&lt;/h2&gt;
&lt;p&gt;Connect GND, RX and TX of the &lt;code&gt;UART0 Debug&lt;/code&gt; connector to an USB serial adapter (3.3V TTL).
Once connected a terminal can be used to connect with the following settings:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;baud rate: 115200
data bits: 8
parity   : none
stop bits: 1
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;12-output-with-empty-emmc-and-no-sd-card-inserted&#34;&gt;1.2 Output with empty eMMC and no SD card inserted&lt;/h2&gt;
&lt;p&gt;In the default configuration the BPI-F3 tries to boot from SD card first and falls back to booting
from eMMC. However, on a new BPI-F3 the eMMC doesn&amp;rsquo;t contain any data and therefore without an SD card the
output looks as shown below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;␀sys: 0x0
try sd...
bm:3
ERROR:   CMD8
ERROR:   sd f! l:76
bm:0
ERROR:   emmc: invalid bootinfo magic code:0x0
ERROR:   invalid bootinfo image.
ERROR:   entering download mode.
ROM: usb download handler
usb2d_initialize : enter
Controller Run
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So in the next step we need to prepare an SD card and/or write an image to the eMMC.&lt;/p&gt;
&lt;h1 id=&#34;install-image&#34;&gt;2 - Installing an image&lt;/h1&gt;
&lt;p&gt;I initially planned to start with &lt;a href=&#34;http://archive.spacemit.com/image/k1/version/bianbu/&#34;&gt;Bianbu Linux&lt;/a&gt;
installed on an SD card, but for some reason this was not booting. The image was written correctly to the SD
card and I could not figure out the problem yet. A &lt;a href=&#34;https://dev.gentoo.org/~lu_zero/riscv/&#34;&gt;Gentoo Linux image&lt;/a&gt;
however booted scuccessfully after sorting out one old SD card which corrupted the image on my first attempt.
I therefore went on and installed Bianbu linux on eMMC.&lt;/p&gt;
&lt;h2 id=&#34;boot-select&#34;&gt;2.1 - Boot selection settings&lt;/h2&gt;
&lt;p&gt;For booting from eMMC the DIP switches must be set correctly. In the factory default settings all 4 switches
are set to &lt;code&gt;off&lt;/code&gt;. Switch 1 and 2 are used for selecting the boot device and the factory default already
selects eMMC as we want it.&lt;/p&gt;
&lt;p&gt;Here some details about the DIP switch functions (see BPI-F3 schematic from the BananaPi Docs):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# BPI-F3 SW1 functions

-------------
|   off   on |
| 1 -o------ | - boot select 1 (QSPI_DATA0)
| 2 -o------ | - boot select 2 (QSPI_DATA1)
| 3 -o------ | - not connected
| 4 -o------ | - not connected
-------------
     ^---------- factory defaults (all 4 switches set to off)

Boot select:
     1  |  2  | function
    ====|=====|====================
    off | off | TF card -&amp;gt; eMMC (factory default)
    off | on  | TF card -&amp;gt; SPI NAND
    on  | off | TF card -&amp;gt; SPI NOR
    on  | on  | TF card only
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;download-mode&#34;&gt;2.2 - Enter download mode&lt;/h2&gt;
&lt;p&gt;To enter &lt;code&gt;download&lt;/code&gt; mode on the BPI-F3 hold down the &lt;code&gt;FDL&lt;/code&gt; button and then reset the device.
Under some circumstances the device also enters &lt;code&gt;download&lt;/code&gt; mode automatically. This for example
is the case on a failed boot attempt with an empty eMMC.&lt;/p&gt;
&lt;p&gt;Once the device is in &lt;code&gt;download&lt;/code&gt; mode it shows following messages on the serial debug console:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ROM: usb download handler
usb2d_initialize : enter
Controller Run
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After connecting the &lt;code&gt;PD12V&lt;/code&gt; USB port of the BPI-F3 to the host a &lt;code&gt;fastboot devices&lt;/code&gt; command
should show the device as shown below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ fastboot devices
dfu-device	 DFU download
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can continue to install the image with &lt;code&gt;fastboot&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;fastboot-mode&#34;&gt;2.3 - Enter U-Boot fastboot mode&lt;/h2&gt;
&lt;p&gt;At the current state we only have a simple download mode provided by the boot ROM running.
Now we need to upload the &lt;code&gt;FSBL&lt;/code&gt; (First Stage Boot Loader) which in case of the BPI-F3 is the
&lt;code&gt;U-Boot SPL&lt;/code&gt; stage (U-Boot Secondary Program Loader - second after the code from the boot ROM).
After this we also can upload the main &lt;code&gt;U-Boot&lt;/code&gt; binary (a.k.a. &lt;code&gt;U-Boot proper&lt;/code&gt;) which then provides
the &lt;code&gt;fastboot&lt;/code&gt; mode we use for flashing the firmware.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://bianbu-linux.spacemit.com/en/device/boot/&#34;&gt;Boot Development Guide&lt;/a&gt; in the
&lt;a href=&#34;https://bianbu-linux.spacemit.com/en/&#34;&gt;Bianbu Linux Docs&lt;/a&gt; describes this and provides
additional information about the boot process of the &lt;code&gt;SpacemiT K1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For entering the &lt;code&gt;U-Boot&lt;/code&gt; &lt;code&gt;fastboot&lt;/code&gt; mode run the following commands:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;fastboot stage factory/FSBL.bin
fastboot continue

# wait some time to ensure u-boot is ready
sleep 1

fastboot stage u-boot.itb
fastboot continue
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The required files can be found in the &lt;code&gt;zip&lt;/code&gt; files available for &lt;a href=&#34;http://archive.spacemit.com/image/k1/version/bianbu/&#34;&gt;download&lt;/a&gt;
on the &lt;code&gt;SpacemiT&lt;/code&gt; server. Downloads ending in &lt;code&gt;img.zip&lt;/code&gt; contain an image to be written onto an SD card. On the other hand
downloads ending in only &lt;code&gt;zip&lt;/code&gt; contain separate files we can use to upload the firmware via fastboot - that&amp;rsquo;s what we need.&lt;/p&gt;
&lt;p&gt;-&amp;gt; Here the file for &lt;a href=&#34;http://archive.spacemit.com/image/k1/version/bianbu/v2.0.4/bianbu-24.04-minimal-k1-v2.0.4-release-20241205234138.zip&#34;&gt;Bianbu Linux v2.0.4&lt;/a&gt; (minimal variant for K1)&lt;/p&gt;
&lt;h2 id=&#34;flash-emmc&#34;&gt;2.4 - Flash eMMC&lt;/h2&gt;
&lt;p&gt;Once the transition to the &lt;code&gt;U-Boot&lt;/code&gt; &lt;code&gt;fastboot&lt;/code&gt; mode is performed we can create the required partitions and
write the firmware to the eMMC. All required files are included in the &lt;code&gt;zip&lt;/code&gt; file we already downloaded.&lt;/p&gt;
&lt;p&gt;For creating the partitions and writing the firmware run following commands:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;fastboot flash gpt partition_universal.json
fastboot flash bootinfo factory/bootinfo_emmc.bin
fastboot flash fsbl factory/FSBL.bin
fastboot flash env env.bin
fastboot flash opensbi fw_dynamic.itb
fastboot flash uboot u-boot.itb
fastboot flash bootfs bootfs.ext4
fastboot flash rootfs rootfs.ext4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now a reset should result in the &lt;code&gt;BPI-F3&lt;/code&gt; booting up the installed &lt;code&gt;Linux&lt;/code&gt;.
The boot process can be watched on the serial debug console.&lt;/p&gt;
&lt;h1 id=&#34;3---what-to-do-next&#34;&gt;3 - What to do next?&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Play around with the device&lt;/li&gt;
&lt;li&gt;Understand the boot process etc.&lt;/li&gt;
&lt;li&gt;Investigate why the SD card images of Bianbu Linux did not boot&lt;/li&gt;
&lt;li&gt;Custom builds of OpenSBI, U-Boot and Linux&lt;/li&gt;
&lt;li&gt;and maybe more &amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>DANE-SMTP enabled</title>
      <link>/posts/2024/10/dane-smtp/</link>
      <pubDate>Tue, 01 Oct 2024 14:27:00 +0700</pubDate>
      
      <guid>/posts/2024/10/dane-smtp/</guid>
      <description>&lt;p&gt;After setting up my mail server I already set up &lt;code&gt;SPF&lt;/code&gt;, &lt;code&gt;DKIM&lt;/code&gt;, &lt;code&gt;DMARC&lt;/code&gt; and &lt;code&gt;MTA-STS&lt;/code&gt; but was not yet sure about how to
deal with &lt;a href=&#34;https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities&#34;&gt;DANE&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DANE&lt;/code&gt; uses a &lt;code&gt;TLSA&lt;/code&gt; entry on the &lt;code&gt;DNS&lt;/code&gt; server to publish a services certificate or key. This means that a client can
verify that it is talking to the correct server without relying on any kind of CA. All this is based on
&lt;a href=&#34;https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions&#34;&gt;DNSSEC&lt;/a&gt; which ensures the authenticity and data
integrity of the &lt;code&gt;DNS&lt;/code&gt; entries.&lt;/p&gt;</description>
      <content>&lt;p&gt;After setting up my mail server I already set up &lt;code&gt;SPF&lt;/code&gt;, &lt;code&gt;DKIM&lt;/code&gt;, &lt;code&gt;DMARC&lt;/code&gt; and &lt;code&gt;MTA-STS&lt;/code&gt; but was not yet sure about how to
deal with &lt;a href=&#34;https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities&#34;&gt;DANE&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DANE&lt;/code&gt; uses a &lt;code&gt;TLSA&lt;/code&gt; entry on the &lt;code&gt;DNS&lt;/code&gt; server to publish a services certificate or key. This means that a client can
verify that it is talking to the correct server without relying on any kind of CA. All this is based on
&lt;a href=&#34;https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions&#34;&gt;DNSSEC&lt;/a&gt; which ensures the authenticity and data
integrity of the &lt;code&gt;DNS&lt;/code&gt; entries.&lt;/p&gt;
&lt;p&gt;While this concept in general is pretty neat, it has the requirement of &lt;code&gt;DNS&lt;/code&gt; entries to be updated when a certificate or
key changes. Additionally just simply updating an entry will no be enough, since other &lt;code&gt;DNS&lt;/code&gt; servers still might have the
old key cached. Therefore a more sophisticated rollover mechanism would be required. Due to the short life of
&lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; certificates this is even more relevant.&lt;/p&gt;
&lt;p&gt;Luckily &lt;a href=&#34;https://certbot.eff.org/&#34;&gt;Certbot&lt;/a&gt; provides the option &lt;code&gt;--reuse-key&lt;/code&gt; to circumvent the requirement of updating
the &lt;code&gt;DNS&lt;/code&gt; entries by reusing the existing key. Therefore a &lt;code&gt;TLSA&lt;/code&gt; entry can be generated from the current public key and
will not require updating as well since the key does not change.&lt;/p&gt;
&lt;p&gt;For generation of an according &lt;code&gt;TLSA&lt;/code&gt; entry &lt;a href=&#34;https://www.huque.com/&#34;&gt;Shumon Huque&lt;/a&gt; has a very handy
&lt;a href=&#34;https://www.huque.com/bin/gen_tlsa&#34;&gt;TLSA Record Generator&lt;/a&gt; on his website.
The entry in this case must be for usage &lt;code&gt;DANE-EE&lt;/code&gt; with selector &lt;code&gt;1 - SPKI&lt;/code&gt;. I use a &lt;code&gt;SHA-256&lt;/code&gt; hash and got following
result:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_25._tcp.vs.senvang.org. IN TLSA 3 1 1 (
                  5634d5e1ce5f1e4a8ab25cd8335c97ab76e1215e09c157568e5c9a3dc39a
                  a491
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively you can generate the hash with &lt;code&gt;openssl&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;openssl x509 -in cert.pem -pubkey -noout | openssl ec -pubin --outform der | sha256sum
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Obviously this does not resolve the need for a clean rollover when a key change happens, but it massively reduces the
frequency and therefore the risk and it gives me time to think about how to get this automated.&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Theme update</title>
      <link>/posts/2024/09/theme_update/</link>
      <pubDate>Mon, 30 Sep 2024 02:19:00 +0700</pubDate>
      
      <guid>/posts/2024/09/theme_update/</guid>
      <description>&lt;p&gt;I use the static site generator &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; to create this website and chose the
&lt;a href=&#34;https://github.com/panr/hugo-theme-terminal&#34;&gt;Terminal&lt;/a&gt; theme originally created by the Github
user &lt;a href=&#34;https://github.com/panr&#34;&gt;panr&lt;/a&gt;. Here I use my own &lt;a href=&#34;https://github.com/senvang/hugo-theme-terminal&#34;&gt;branch&lt;/a&gt; which replaces the font &lt;code&gt;FiraCode&lt;/code&gt; with &lt;code&gt;FiraMono&lt;/code&gt; to get rid of the ligatures.&lt;/p&gt;
&lt;p&gt;Today I found out that &lt;code&gt;panr&lt;/code&gt; continued development on his theme after he actually stopped a
while ago. A happy surprise! So I just merged his latest version into my branch and updated
the website. He actually introduced some major changes by now relying on his new project
&lt;a href=&#34;https://github.com/panr/terminal-css&#34;&gt;Terminal.css&lt;/a&gt; which simply separates the style from
the theme to allow people to use it independently.&lt;/p&gt;</description>
      <content>&lt;p&gt;I use the static site generator &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; to create this website and chose the
&lt;a href=&#34;https://github.com/panr/hugo-theme-terminal&#34;&gt;Terminal&lt;/a&gt; theme originally created by the Github
user &lt;a href=&#34;https://github.com/panr&#34;&gt;panr&lt;/a&gt;. Here I use my own &lt;a href=&#34;https://github.com/senvang/hugo-theme-terminal&#34;&gt;branch&lt;/a&gt; which replaces the font &lt;code&gt;FiraCode&lt;/code&gt; with &lt;code&gt;FiraMono&lt;/code&gt; to get rid of the ligatures.&lt;/p&gt;
&lt;p&gt;Today I found out that &lt;code&gt;panr&lt;/code&gt; continued development on his theme after he actually stopped a
while ago. A happy surprise! So I just merged his latest version into my branch and updated
the website. He actually introduced some major changes by now relying on his new project
&lt;a href=&#34;https://github.com/panr/terminal-css&#34;&gt;Terminal.css&lt;/a&gt; which simply separates the style from
the theme to allow people to use it independently.&lt;/p&gt;
&lt;p&gt;This now also easily allows the &lt;a href=&#34;https://panr.github.io/terminal-css/&#34;&gt;creation&lt;/a&gt; of custom
color schemes (compared to having just a set of fixed colors before). I used this to slightly
adapt the colors to my company logo.&lt;/p&gt;
&lt;p&gt;Besides this there should be no changes here. Thanks &lt;code&gt;panr&lt;/code&gt; &amp;hellip;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>A quick update</title>
      <link>/posts/2024/09/a_quick_update/</link>
      <pubDate>Thu, 26 Sep 2024 23:05:00 +0700</pubDate>
      
      <guid>/posts/2024/09/a_quick_update/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s a long time since I wrote something here so in this time things happened in the background.
Here a quick update:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I moved the server to a more powerful one (VPS 1000) - still from &lt;a href=&#34;https://www.netcup.de/&#34;&gt;Netcup&lt;/a&gt;.
The main reason for this upgrade was my decision to switch to &lt;a href=&#34;https://www.gentoo.org/&#34;&gt;Gentoo Linux&lt;/a&gt;
on the server as well after my desktop computer is running flawlessly with it since years now and I
wanted to make this switch before I started setting up a mail server.&lt;/p&gt;</description>
      <content>&lt;p&gt;It&amp;rsquo;s a long time since I wrote something here so in this time things happened in the background.
Here a quick update:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I moved the server to a more powerful one (VPS 1000) - still from &lt;a href=&#34;https://www.netcup.de/&#34;&gt;Netcup&lt;/a&gt;.
The main reason for this upgrade was my decision to switch to &lt;a href=&#34;https://www.gentoo.org/&#34;&gt;Gentoo Linux&lt;/a&gt;
on the server as well after my desktop computer is running flawlessly with it since years now and I
wanted to make this switch before I started setting up a mail server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I got following services running on Gentoo now:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Certbot to get certificates from &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nginx.org/&#34;&gt;Nginx&lt;/a&gt; as web server / proxy&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://radicale.org/&#34;&gt;Radicale&lt;/a&gt; as CalDAV / CardDAV server&lt;/li&gt;
&lt;li&gt;Git via ssh access (I keep it simple and do not run &lt;a href=&#34;https:/gitea.com&#34;&gt;Gitea&lt;/a&gt; anymore)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.postfix.org/&#34;&gt;Postfix&lt;/a&gt; / &lt;a href=&#34;https://www.dovecot.org/&#34;&gt;Dovecot&lt;/a&gt; as mail server&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wireguard.com/&#34;&gt;Wireguard&lt;/a&gt; as VPN server&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The mail server is setup with &lt;a href=&#34;https://en.wikipedia.org/wiki/Sender_Policy_Framework&#34;&gt;SPF&lt;/a&gt;,
&lt;a href=&#34;https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail&#34;&gt;DKIM&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/DMARC&#34;&gt;DMARC&lt;/a&gt;
and &lt;a href=&#34;https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#SMTP_MTA_Strict_Transport_Security&#34;&gt;MTA-STS&lt;/a&gt;.
Regarding &lt;a href=&#34;https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities&#34;&gt;DANE&lt;/a&gt; I am still investigating
if I can/want to set this up with the frequently changing Let&amp;rsquo;s Encrypt certificates.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what the heck is all that? Here in short:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SPF: Specifies the mail servers allowed to send mail for the domain by publishing an entry in the DNS&lt;/li&gt;
&lt;li&gt;DKIM: Sign outgoing mail and publish the public key in the DNS, so the receipient can verify the signature&lt;/li&gt;
&lt;li&gt;DMARC: Publish a DMARC DNS entry with instructions on how to handle mail which doesn&amp;rsquo;t pass SPF/DKIM checks&lt;/li&gt;
&lt;li&gt;MTA-STS: A combination of DNS and HTTPS to instruct SMTP servers to encrypt communication and verify the used certificate&lt;/li&gt;
&lt;li&gt;DANE: A DNS entry containing the server certificate (usually just a hash of it) and therefore allowing the communication
partner to compare the servers certificate against the one published in DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s what happened on here in the last months. More to come &amp;hellip;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Reverse engineering a BLE body fat scale protocol</title>
      <link>/posts/2024/09/scale_interface/</link>
      <pubDate>Sat, 14 Sep 2024 22:19:00 +0700</pubDate>
      
      <guid>/posts/2024/09/scale_interface/</guid>
      <description>&lt;p&gt;I recently bought the &amp;lsquo;&lt;em&gt;smart&lt;/em&gt;&amp;rsquo; body fat scale &lt;em&gt;Crénot Gofit S2&lt;/em&gt;. As many of those modern &amp;lsquo;&lt;em&gt;smart&lt;/em&gt;&amp;rsquo; devices it uses
&lt;code&gt;Bluetooth Low Energy&lt;/code&gt; (&lt;code&gt;BLE&lt;/code&gt;) and an App on the phone to connect to it. Due to privacy concerns I do not want to use this
cloud based App and share my fitness / health data.&lt;/p&gt;
&lt;p&gt;Instead I found &lt;a href=&#34;https://github.com/oliexdev/openScale&#34;&gt;openScale&lt;/a&gt;. An open source App which would give me the same
functionality while storing all data locally on my phone. Sadly it did not support my scale so I started investigating
if I can add support for it.&lt;/p&gt;</description>
      <content>&lt;p&gt;I recently bought the &amp;lsquo;&lt;em&gt;smart&lt;/em&gt;&amp;rsquo; body fat scale &lt;em&gt;Crénot Gofit S2&lt;/em&gt;. As many of those modern &amp;lsquo;&lt;em&gt;smart&lt;/em&gt;&amp;rsquo; devices it uses
&lt;code&gt;Bluetooth Low Energy&lt;/code&gt; (&lt;code&gt;BLE&lt;/code&gt;) and an App on the phone to connect to it. Due to privacy concerns I do not want to use this
cloud based App and share my fitness / health data.&lt;/p&gt;
&lt;p&gt;Instead I found &lt;a href=&#34;https://github.com/oliexdev/openScale&#34;&gt;openScale&lt;/a&gt;. An open source App which would give me the same
functionality while storing all data locally on my phone. Sadly it did not support my scale so I started investigating
if I can add support for it.&lt;/p&gt;
&lt;p&gt;Initially I read the &lt;a href=&#34;https://github.com/oliexdev/openScale/wiki/How-to-reverse-engineer-a-Bluetooth-4.x-scale&#34;&gt;How to reverse engineer a Bluetooth 4.x scale&lt;/a&gt;
notes on the openScale Github page and also created a Bluetooth HCI snoop log as described there, but then ended up
following a different approach and wrote a small client in Python by using &lt;a href=&#34;https://pypi.org/project/bleak/&#34;&gt;Bleak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;BLE devices use the &lt;code&gt;Generic Attribute Profile&lt;/code&gt; (&lt;code&gt;GATT&lt;/code&gt;) and provide services with different characteristics.
The &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner&#34;&gt;BLE scanner&lt;/a&gt; App mentioned in the notes
became handy to gather information about the scales provided services and characteristics.&lt;/p&gt;
&lt;p&gt;With this information I quickly was able to reliably get the weight value from the scale but did not figure out yet how other
values - like body fat percentage for example -  are transferred.&lt;/p&gt;
&lt;p&gt;My client can be found in my &lt;a href=&#34;https://github.com/sroemer/scale-communication&#34;&gt;scale-communication&lt;/a&gt; repo on Github and
with knowing the basic communication protocol it also will be possible to implement this in openScale. I also did not
give up yet on getting the missing values from my scale - but that&amp;rsquo;s for another time.&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Radicale installation on Devuan Daedalus 5.0</title>
      <link>/posts/2024/05/radicale_installation/</link>
      <pubDate>Thu, 30 May 2024 23:31:00 +0700</pubDate>
      
      <guid>/posts/2024/05/radicale_installation/</guid>
      <description>&lt;p&gt;Since years I am running my own CalDAV / CardDAV server to synchronize my calendars and address books.
I use &lt;a href=&#34;https://radicale.org&#34;&gt;Radicale&lt;/a&gt; for this and on my Uberspace it was installed via Python&amp;rsquo;s &lt;code&gt;pip&lt;/code&gt;,
but now it was time to move this to my own server too and I chose to install the package directly from
the Devuan repository via &lt;code&gt;apt-get install radicale&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The installation via &lt;code&gt;apt-get&lt;/code&gt; just does the installation but some additional configuration was needed
to set everything up.&lt;/p&gt;</description>
      <content>&lt;p&gt;Since years I am running my own CalDAV / CardDAV server to synchronize my calendars and address books.
I use &lt;a href=&#34;https://radicale.org&#34;&gt;Radicale&lt;/a&gt; for this and on my Uberspace it was installed via Python&amp;rsquo;s &lt;code&gt;pip&lt;/code&gt;,
but now it was time to move this to my own server too and I chose to install the package directly from
the Devuan repository via &lt;code&gt;apt-get install radicale&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The installation via &lt;code&gt;apt-get&lt;/code&gt; just does the installation but some additional configuration was needed
to set everything up.&lt;/p&gt;
&lt;p&gt;At first I modified the configuration file &lt;code&gt;/etc/radicale/config&lt;/code&gt; and did set&lt;br&gt;
&lt;code&gt;type = htpasswd&lt;/code&gt; and &lt;code&gt;htpasswd_encryption = bcrypt&lt;/code&gt; (both in the &lt;code&gt;[auth]&lt;/code&gt; section).&lt;/p&gt;
&lt;p&gt;Then I created a new htpasswd file with my user:&lt;br&gt;
&lt;code&gt;htpasswd -c -B /etc/radicale/users &amp;lt;user&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Finally I started the service and enabled it to be started automatically:&lt;br&gt;
&lt;code&gt;/etc/init.d/radicale start&lt;/code&gt;&lt;br&gt;
&lt;code&gt;update-rc.d radicale enable&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After this the radicale server is bound to localhost and listening on port 5232.
For being accessible from the outside the following configuration must be added to the Nginx configuration (and Nginx being restarted once):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;location /radicale/ { # The trailing / is important!
      proxy_pass        http://localhost:5232/; # The / is important!
      proxy_set_header  X-Script-Name /radicale;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header  Host $http_host;
      proxy_pass_header Authorization;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I only had to copy contact and calendar entries from my Uberspace instance. Done!&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Linux Containers (LXC) on Devuan Daedalus 5.0</title>
      <link>/posts/2023/10/lxc_on_devuan_linux/</link>
      <pubDate>Tue, 31 Oct 2023 16:38:00 +0700</pubDate>
      
      <guid>/posts/2023/10/lxc_on_devuan_linux/</guid>
      <description>&lt;p&gt;I started some investigation about how to run Linux Containers on Devuan Linux 5.0
(Daedalus), as I run it on my server. For this I first did set up a local VM which
replicates my virtual server. I use qemu for this and created a script called
&lt;a href=&#34;https://github.com/sroemer/dotfiles/blob/main/.local/bin/vm-netcup&#34;&gt;vm‑netcup&lt;/a&gt;
which is part of my &lt;a href=&#34;https://github.com/sroemer/dotfiles/&#34;&gt;dotfiles&lt;/a&gt; repository and
sets qemu parameters accordingly.&lt;/p&gt;
&lt;p&gt;Installation via &lt;code&gt;apt-get install lxc&lt;/code&gt; works as expected. So far so good - but things
should not go that smoothly for much longer.&lt;/p&gt;</description>
      <content>&lt;p&gt;I started some investigation about how to run Linux Containers on Devuan Linux 5.0
(Daedalus), as I run it on my server. For this I first did set up a local VM which
replicates my virtual server. I use qemu for this and created a script called
&lt;a href=&#34;https://github.com/sroemer/dotfiles/blob/main/.local/bin/vm-netcup&#34;&gt;vm‑netcup&lt;/a&gt;
which is part of my &lt;a href=&#34;https://github.com/sroemer/dotfiles/&#34;&gt;dotfiles&lt;/a&gt; repository and
sets qemu parameters accordingly.&lt;/p&gt;
&lt;p&gt;Installation via &lt;code&gt;apt-get install lxc&lt;/code&gt; works as expected. So far so good - but things
should not go that smoothly for much longer.&lt;/p&gt;
&lt;h4 id=&#34;cgroups&#34;&gt;cgroups&lt;/h4&gt;
&lt;p&gt;LXC relies on cgroups, a Linux kernel feature for isolation, limitation and accounting of
resource usage of processes. On distributions using systemd this is set up by systemd,
but with Devuan I chose to not use systemd.&lt;/p&gt;
&lt;p&gt;You guessed it: &lt;code&gt;lxc-checkconfig&lt;/code&gt; and &lt;code&gt;ls /sys/fs/cgroup&lt;/code&gt; show that cgroups are not set up
by default (at least not with my minimal installation). LXC can work with cgroups v1 but
cgroups v2 provide a cleaner, unified hierarchy and therefore are my preferred way.&lt;/p&gt;
&lt;p&gt;To mount the cgroup v2 filesystem at boot time, I simply created an additional entry in
the &lt;code&gt;/etc/fstab&lt;/code&gt; file:&lt;br&gt;
&lt;code&gt;none    /sys/fs/cgroup    cgroup2    defaults    0 0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In case you want to use cgroups v1 you can install the &lt;code&gt;cgroupfs-mount&lt;/code&gt; package which
installs a service to perform the required mounts at boot time.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all that is required to set up cgroups for LXC.&lt;/p&gt;
&lt;h4 id=&#34;unpriviledged-vs-priviledged-containers&#34;&gt;unpriviledged vs. priviledged containers&lt;/h4&gt;
&lt;p&gt;In short: We want unpriviledged containers whenever possible. Those map user ids inside the
container to a different range on the host and therefore are the safest option. For example
user id 0 (root) in an unpriviledged container would be mapped to user id 100000 on the host.
A user id 0 (root) on a priviledged container on the other hand also would be root on the
host.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/subuid&lt;/code&gt; and &lt;code&gt;/etc/subgid&lt;/code&gt; contain the ranges for mapping uid and gid on the host,
but those values also need to be reflected in the lxc configuration as described below.&lt;/p&gt;
&lt;h4 id=&#34;configuration&#34;&gt;configuration&lt;/h4&gt;
&lt;p&gt;For configuration LXC distinguishes between system and container configuration. See the
according man pages lxc.container.conf and lxc.system.conf for further information.&lt;/p&gt;
&lt;p&gt;By default LXC on my system used &lt;code&gt;~/.local/share/lxc/&lt;/code&gt; for container storage. This resulted
in LXC complaining about the users home directory not having x permission for the root user
of the container and starting the container failed.&lt;/p&gt;
&lt;p&gt;Therefore I decided to move the container storage to &lt;code&gt;/var/lib/lxc/&amp;lt;user&amp;gt;&lt;/code&gt;. This
directory needs to be created as root and owernship as well as permissions need to be set
as follows:&lt;br&gt;
&lt;code&gt;chown &amp;lt;user&amp;gt;:&amp;lt;group&amp;gt; /var/lib/lxc/&amp;lt;user&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;chmod 711 /var/lib/lxc/&amp;lt;user&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once this is done we can continue as regular user. We create a file &lt;code&gt;.config/lxc/lxc.conf&lt;/code&gt;
and configure the container storage path in it:&lt;br&gt;
&lt;code&gt;lxc.lxcpath = /var/lib/lxc/&amp;lt;user&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/lxc/default.conf&lt;/code&gt; contains the system wide container default configuration. We copy
this file to &lt;code&gt;~/.config/lxc/default.conf&lt;/code&gt; and modify it to create our user specific defaults.&lt;/p&gt;
&lt;p&gt;Be aware that this file only contains the default configuration used during creation of a
new container. Once created every container has its own configuration file in its according
folder within the container storage path.&lt;/p&gt;
&lt;p&gt;We now add the following lines for configuration of the uid and gid mapping. The values used
here must match the values defined in &lt;code&gt;/etc/subuid&lt;/code&gt; and &lt;code&gt;/etc/subgid&lt;/code&gt; for the according user:&lt;br&gt;
&lt;code&gt;lxc.idmap = u 0 100000 65536&lt;/code&gt;&lt;br&gt;
&lt;code&gt;lxc.idmap = g 0 100000 65536&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Additionaly we change the AppArmor profile as follows:&lt;br&gt;
&lt;code&gt;lxc.apparmor.profile = unconfined&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;creating-a-new-container&#34;&gt;creating a new container&lt;/h5&gt;
&lt;p&gt;For creation of a new container we use the &lt;code&gt;lxc-create&lt;/code&gt; command. &lt;code&gt;lxc-create -t download -n &amp;lt;container-name&amp;gt;&lt;/code&gt;
is a good start and provides an interactive way to create a new container. In my case I want to
install the &lt;code&gt;3.18&lt;/code&gt; release for the &lt;code&gt;amd64&lt;/code&gt; architecture of the &lt;code&gt;alpine&lt;/code&gt; distribution.&lt;/p&gt;
&lt;p&gt;This all also can be packed into the command directly:&lt;br&gt;
&lt;code&gt;lxc-create -t download -n &amp;lt;container-name&amp;gt; -- --dist alpine --release 3.18 --arch amd64&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;network&#34;&gt;network&lt;/h5&gt;
&lt;p&gt;With all this set up the container still fails to start because it cannot set up its network.
By default unprivileged containers cannot use any networking. We need to create an additional
configuration file &lt;code&gt;/etc/lxc/lxc-usernet&lt;/code&gt; as root. This file must have an entry to allow the
user to add veth devices - up to 16 in in my case - to the lxcbr0 bridge:&lt;br&gt;
&lt;code&gt;&amp;lt;user&amp;gt; veth lxcbr0 16&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;using-the-container&#34;&gt;using the container&lt;/h5&gt;
&lt;p&gt;To start an already existing container the command &lt;code&gt;lxc-start -n &amp;lt;container-name&amp;gt;&lt;/code&gt; is used.
With everything I described above done the container does start without issues. Previously
appearing &lt;code&gt;tmpfs: Bad value for &#39;uid&#39;&lt;/code&gt; error message were related to the Devuan container
image used. The errors disappeared after I switched to using the Alpine Linux image.&lt;/p&gt;
&lt;p&gt;Once the container is running we can start a process in the container with &lt;code&gt;lxc-attach&lt;/code&gt;.
For example &lt;code&gt;lxc-attach -n &amp;lt;container-name&amp;gt; bash&lt;/code&gt; will provide shell access to the container.&lt;/p&gt;
&lt;p&gt;For stopping the container again we use &lt;code&gt;lxc-stop -n &amp;lt;container-name&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In case the container isn&amp;rsquo;t running we directly can run a command in it with &lt;code&gt;lxc-execute&lt;/code&gt;.
For example &lt;code&gt;lxc-execute -n &amp;lt;container-name&amp;gt; bash&lt;/code&gt; will provide shell access as before.&lt;/p&gt;
&lt;h4 id=&#34;conclusion&#34;&gt;conclusion&lt;/h4&gt;
&lt;p&gt;I am not done with this topic yet but for now this is a good foundation and a playground to
further investigate if I want to run containers on the server. I might update this post at
some point if I have any points worth mentioning.&lt;/p&gt;
&lt;p&gt;Especially the network setup was barely touched here and could be a topic for a separate post
at some point. For now that&amp;rsquo;s it &amp;hellip;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>I ordered a new virtual server</title>
      <link>/posts/2023/10/a_new_virtual_server/</link>
      <pubDate>Sat, 14 Oct 2023 00:00:00 +0700</pubDate>
      
      <guid>/posts/2023/10/a_new_virtual_server/</guid>
      <description>&lt;p&gt;After running my own server for some years in the past I did move on to using an &lt;a href=&#34;https://uberspace.de/&#34;&gt;Uberspace&lt;/a&gt;.
Uberspace as a hoster is great and offers a lot of flexibility but it has its limitations anyway (for example it is not
possible to run a VPN server). I am planning to run a VPN server and also like the admin work overall. So I ordered a
small virtual server (VPS 200 G10s) from &lt;a href=&#34;https://www.netcup.de/&#34;&gt;Netcup&lt;/a&gt; again.&lt;/p&gt;</description>
      <content>&lt;p&gt;After running my own server for some years in the past I did move on to using an &lt;a href=&#34;https://uberspace.de/&#34;&gt;Uberspace&lt;/a&gt;.
Uberspace as a hoster is great and offers a lot of flexibility but it has its limitations anyway (for example it is not
possible to run a VPN server). I am planning to run a VPN server and also like the admin work overall. So I ordered a
small virtual server (VPS 200 G10s) from &lt;a href=&#34;https://www.netcup.de/&#34;&gt;Netcup&lt;/a&gt; again.&lt;/p&gt;
&lt;h4 id=&#34;why-did-i-choose-netcup&#34;&gt;Why did I choose Netcup?&lt;/h4&gt;
&lt;p&gt;The answer to that is easy. It&amp;rsquo;s cheap and I did have some good experience with it already.
For 3.25 Euro/month I get a VPS with 2vCPUs, 2GB RAM and 40GB SSD. For the virtualization they use KVM and via the
web interface I can mount any ISO file and install whatever OS I like. The drawback of their cheap virtual servers
is the quite low minimum availability of just 99.6% but for my use case that&amp;rsquo;s not an issue.&lt;/p&gt;
&lt;h4 id=&#34;which-os-did-i-install&#34;&gt;Which OS did I install?&lt;/h4&gt;
&lt;p&gt;After initially even considering &lt;a href=&#34;https://www.gentoo.org/&#34;&gt;Gentoo&lt;/a&gt; Linux I quickly dropped that idea due to the
limitations of the virtual hardware. I then - after some research - did a kind of test installation of Alpine Linux.
It was the first time ever I used &lt;a href=&#34;https://www.alpinelinux.org/&#34;&gt;Alpine&lt;/a&gt; and I must say that I am pretty impressed
with it - especially due to its low footprint. Anyway I decided to stick with something I know better and trust a bit
more in the long term.&lt;/p&gt;
&lt;p&gt;I installed &lt;a href=&#34;https://www.devuan.org&#34;&gt;Devuan&lt;/a&gt; Linux - Devuan Daedalus 5.0.
For those who are not aware, Devuan is a fork of &lt;a href=&#34;https://www.debian.org&#34;&gt;Debian&lt;/a&gt; Linux which does not use systemd and
therfore I can count on the great selection of software available for Debian while still using the good old sysvinit.&lt;/p&gt;
&lt;p&gt;As always I did a minimal installation and add what is required for my needs from there. My base installation with
&lt;a href=&#34;https://nginx.org/&#34;&gt;Nginx&lt;/a&gt;, &lt;a href=&#34;https://certbot.eff.org/&#34;&gt;Certbot&lt;/a&gt; and unattended upgrades uses about 60MB of RAM.
A nice small footprint as well even if its not as small as Alpine Linux (but that&amp;rsquo;s expected).&lt;/p&gt;
&lt;h4 id=&#34;further-plans&#34;&gt;Further plans?&lt;/h4&gt;
&lt;p&gt;With Nginx and Certbot up and running I already moved the website on to the new server.
Additionally I want to install the following components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitea.com/&#34;&gt;Gitea&lt;/a&gt; git server, bug tracker, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://radicale.org/&#34;&gt;Radicale&lt;/a&gt; CalDAV and CardDAV server&lt;/li&gt;
&lt;li&gt;Mail server (probably &lt;a href=&#34;https://www.postfix.org/&#34;&gt;Postfix&lt;/a&gt; and &lt;a href=&#34;https://www.dovecot.org/&#34;&gt;Dovecot&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wireguard.com/&#34;&gt;WireGuard&lt;/a&gt; VPN server&lt;/li&gt;
&lt;li&gt;&amp;hellip; and eventually more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regarding all this I am not in a hurry. For now I am using the Uberspace and my virtual server in parallel and before
installing any of those components I want to do some research about &lt;a href=&#34;https://linuxcontainers.org/&#34;&gt;Linux Containers&lt;/a&gt;.
So far I do not have experience with containers of any kind and I am not a huge fan of Docker and its approach of
isolating single applications. Linux Containers on the other hand are available on any Linux system, are OS-level
virtualization and do not rely on infrastructure controlled by a single company.
So my idea is to isolate some parts of my installation into Linux Containers (probably using Devuan images as well).
Therefore I should gain some flexibility when updating the main server OS and be able to move and update some parts
independently.&lt;/p&gt;
&lt;p&gt;In any case containers are an interesting topic and digging deeper into it will be worth it &amp;hellip;&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
