<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Allgemein &#8211; Flugphase</title>
	<atom:link href="https://blog.reauktion.de/category/allgemein/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.reauktion.de</link>
	<description>Die Gedanken sind frei</description>
	<lastBuildDate>Mon, 25 May 2026 20:13:36 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>Vulkan on Mali-G52 — limited Panfrost / panvk-bifrost in Brave</title>
		<link>https://blog.reauktion.de/vulkan-on-mali-g52-limited-panfrost-panvk-bifrost-in-brave-the-unfiltered-version/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Mon, 25 May 2026 19:55:37 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/vulkan-on-mali-g52-limited-panfrost-panvk-bifrost-in-brave-the-unfiltered-version/</guid>

					<description><![CDATA[Announcing mesa-panvk-bifrost: a downstream-patched Mesa 26.0.6 Vulkan ICD that gets Brave Vulkan GPU process running on Mali-G52 (Bifrost) hardware — non-certified, limited to Bifrost, distributed via the marfrit ALARM repo.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><code>panvk</code> — the Mesa Vulkan driver for Arm Mali GPUs — supports the modern <em>Valhall</em> generation upstream. The older <em>Bifrost</em> generation (Mali-G31, G51, G52, G72, G76) is implemented far enough to enumerate adapters but Mesa keeps it behind an explicit opt-out: <code>PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1</code>. That name is not subtle. It is the upstream maintainers stating, accurately, that this code path is not a Khronos-conformant Vulkan implementation.</p>



<p class="wp-block-paragraph">This post announces a downstream package, <code>mesa-panvk-bifrost</code>, that takes that opt-out path and turns it into something specific: <strong>good enough to host Brave&#8217;s Vulkan GPU process on Mali-G52 hardware</strong>. Not good enough for general-purpose Vulkan, not conformant, not upstream-bound.</p>



<h2 class="wp-block-heading">What ships</h2>



<p class="wp-block-paragraph"><code>mesa-panvk-bifrost</code> is a downstream-patched Mesa 26.0.6 Vulkan ICD, co-installed at <code>/usr/lib/panvk-bifrost/</code> alongside the system Mesa. It does not replace anything. Opt-in is per-process, either via <code>VK_ICD_FILENAMES</code> or via the <code>brave-vulkan</code> launcher that ships with the package.</p>



<p class="wp-block-paragraph">Available as an Arch Linux ARM package from the marfrit repo (<a href="https://packages.reauktion.de/">packages.reauktion.de</a>):</p>



<pre class="wp-block-code"><code>pacman -S mesa-panvk-bifrost</code></pre>



<p class="wp-block-paragraph">On a PineTab2 (RK3566, Mali-G52 r1 MC1): Brave&#8217;s <code>chrome://gpu</code> reports <em>&#8222;Vulkan backend — Mali-G52 r1 MC1&#8220;</em> under Integrated GPU.</p>



<h2 class="wp-block-heading">What &#8222;limited and non-certified&#8220; actually means here</h2>



<p class="wp-block-paragraph"><strong>Non-certified.</strong> <code>PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1</code> still has to be set; the launcher (brave-vulkan) sets it for you, but the label is accurate. For context only: a full <code>dEQP-VK 1.3.10.0</code> sweep against r5 ran 2.26 million tests at a 97.65% runnable-pass rate — shape, not credentials. Not a Khronos submission, not a conformance claim.</p>



<p class="wp-block-paragraph"><strong>Limited.</strong> Bifrost only. Primary target is Mali-G52 r1 MC1 (Bifrost gen-2, <code>PAN_ARCH 7</code>) in RK3566 — PineTab2, PineNote, Quartz64-B, ODROID-M1S. Same code path expected to work on G31, G72, G76; none hands-on-validated here. <em>Valhall</em> hardware (Mali-G610 etc.) is served by upstream <code>panvk</code> directly — this package is not for those.</p>



<p class="wp-block-paragraph"><strong>Downstream.</strong> These patches are not being upstreamed. They live in the <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/mesa-panvk-bifrost">marfrit-packages</a> overlay and ship via the ALARM repo above.</p>



<h2 class="wp-block-heading">Lineage</h2>



<ul class="wp-block-list">
<li><strong>r1–r4</strong> — extension enablement (<code>VK_KHR_robustness2</code>, <code>VK_EXT_transform_feedback</code>) plus a NIR pass that decomposes XFB primitives into shapes Bifrost can emit.</li>



<li><strong>r5</strong> — <code>fragmentStoresAndAtomics = true</code> (Chromium Dawn gate). +32 atomic-operations CTS tests, zero regressions.</li>



<li><strong>r6</strong> — <code>VK_EXT_legacy_dithering</code> advertised. Five-line backport from Mesa main.</li>



<li><strong>r7</strong> — XFB packed-varying channel-extract SIGSEGV fix.</li>



<li><strong>r9</strong> — <code>maxImageDimension3D</code> bumped 512 → 2048. The revision that actually unblocked Dawn adapter acceptance. (r8 hit a CTS version-skew issue and was abandoned mid-Phase-3.)</li>
</ul>



<h2 class="wp-block-heading">Where the code lives</h2>



<ul class="wp-block-list">
<li><strong>Driver patches and PKGBUILD:</strong> <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/mesa-panvk-bifrost">git.reauktion.de/marfrit/marfrit-packages — arch/mesa-panvk-bifrost</a></li>



<li><strong>Campaign tracking</strong> (phase docs, CTS scoreboards, decision history): <a href="https://git.reauktion.de/marfrit/panvk-bifrost">git.reauktion.de/marfrit/panvk-bifrost</a></li>



<li><strong>Package:</strong> <code>pacman -S mesa-panvk-bifrost</code> from <a href="https://packages.reauktion.de/">packages.reauktion.de</a></li>
</ul>



<p class="wp-block-paragraph">If your machine is one of the Bifrost SBCs above and you want the Chromium GPU process running on real Vulkan rather than llvmpipe, this is now an option.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Eight ARM cores were doing video decode. Then they stopped.</title>
		<link>https://blog.reauktion.de/eight-arm-cores-were-doing-video-decode-then-they-stopped/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Tue, 19 May 2026 09:39:55 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2867</guid>

					<description><![CDATA[A status note on getting the dedicated video decoder silicon on the Rockchip + Pi 5 fleet to do its job. CPU before/after, packages shipped, scope-outs annotated. Today (2026-05-18) bridged the last gap: AV1 on RK3588 now ships as linux-ampere-fourier kafr2.]]></description>
										<content:encoded><![CDATA[<p>Every modern ARM SoC ships with a dedicated video decoder block sitting next to the CPU cores. On the Rockchip side: <code>rkvdec</code> (RK3399 — H.264, HEVC, VP9), plus <code>hantro-vpu</code> (RK3399 / RK3568 / RK3588 — MPEG-2, VP8, plus a separate RK3588 instance for AV1). On the Broadcom side: a small HEVC decoder block behind <a href="https://patchwork.kernel.org/project/linux-media/cover/20250707115431.55603-1-jonas@kwiboo.se/"><code>rpi-hevc-dec</code></a>on the Pi 5 / CM5. None of these are exciting silicon. They&#8217;re 2018-vintage fixed-function pipelines mostly bought for the box checking. But they&#8217;re <em>there</em>, they cost a tenth of a watt to wake up, and they decode video.</p>
<p>For about six months our fleet shipped with them mostly <em>idle</em>. The ARM cores chewed software decode and overheated for the privilege.</p>
<p>This is a status note on getting them to do their job.</p>
<h2>The current state, eight hours into a session</h2>
<table>
<thead>
<tr>
<th>Device</th>
<th>SoC</th>
<th>What the silicon decodes today</th>
<th>How</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pinebook Pro</td>
<td>RK3399</td>
<td>H.264, HEVC, VP8, VP9, MPEG-2 — including H.264 Hi10P + HEVC Main10</td>
<td>rkvdec + hantro via <a href="https://git.reauktion.de/marfrit/libva-v4l2-request-fourier"><code>libva-v4l2-request-fourier</code></a></td>
</tr>
<tr>
<td>CoolPi CM5 GenBook</td>
<td>RK3588</td>
<td>H.264, HEVC, VP8, VP9, MPEG-2, <strong>AV1</strong></td>
<td>rkvdec (VDPU381 H.264/HEVC/VP9) + hantro (legacy + dedicated AV1 instance)</td>
</tr>
<tr>
<td>PineTab2</td>
<td>RK3566</td>
<td>H.264, MPEG-2, VP8</td>
<td>hantro</td>
</tr>
<tr>
<td>Pi 5 CM5 portable</td>
<td>BCM2712</td>
<td>HEVC</td>
<td>rpi-hevc-dec (kernel side at v4 since July 2025, still not in mainline as of May 2026)</td>
</tr>
</tbody>
</table>
<p>Each cell required either a kernel patch, a userspace plumbing fix, or both. Some still don&#8217;t work and probably never will. Two stories from today&#8217;s iteration:</p>
<h2>Story one: H.264 Hi10P on the RK3399 silicon &#8222;didn&#8217;t decode&#8220;</h2>
<p>The Pinebook Pro&#8217;s RK3399 advertises Hi10P (10-bit H.264) in its kernel ctrl table. Decode-empirically, it produced uniform-black frames. The phase-7 close note said &#8222;kernel advertisement is aspirational&#8220; — possibly the silicon doesn&#8217;t actually do this, possibly Rockchip&#8217;s marketing got ahead of the hardware.</p>
<p>Today&#8217;s empirical retest: the first five frames of the test fixture are a <em>fade-in</em>. The decode was correct; it was decoding correctly to <em>black</em>, because the source was black. Seek past frame six and the silicon produces bit-exact-correct decoded frames.</p>
<p>Lesson learned: Do not use Big Buck Bunny intro frames for bit-exactness verification. Future contributors are encouraged to verify they are not testing the title card.</p>
<p>The actual bug was elsewhere. FFmpeg&#8217;s <a href="https://github.com/Kwiboo/FFmpeg/tree/v4l2-request-n8.1">Kwiboo n8.1 V4L2 hwaccel </a>maps the RK3399 10-bit NV15 capture format to <code>AV_PIX_FMT_YUV420P10</code> but then deliberately blanks the transfer-format list — the author expected consumers to call <code>av_hwframe_map</code> and chain a swscale unpack, but <code>hwdownload</code> doesn&#8217;t do that chaining. Result: kernel decodes fine, userspace never sees the bytes.</p>
<p>The fix is sixty lines: implement NV15→P010 unpack inside <code>v4l2request_transfer_data_from</code>, advertise P010 in <code>transfer_get_formats</code>.<br />
Shipped as patch 0002 on <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/ffmpeg-v4l2-request-fourier"><code>ffmpeg-v4l2-request-fourier</code></a> pkgrel=5. Twenty-frame mid-fixture decode is now byte-identical to libavcodec software reference. The Phase 5 reviewer suggested a hardening guard for malformed callers, which is now also in.</p>
<p>If you have an anime fansub collection from 2014, the Pinebook Pro now decodes it in hardware. We assume this is a niche use case.</p>
<h2>Story two: VP9 on RK3588 took eight months of upstream review</h2>
<p>VP9 hardware decode on the RK3588&#8217;s <code>VDPU381</code> block was implemented by Detlev Casanova and the Collabora team; the kernel side merged into Linux 7.0 mainline in February 2026. AV1 support followed in the same window. The actual <em>RK3588 H.264 + HEVC + AV1</em> path is mainline as of this writing.</p>
<p>VP9 — different story. Same hardware, same block; AV1 had to land first apparently for political reasons we won&#8217;t pretend to understand. As of May 2026 the VP9-on-VDPU381 work is on an <a href="https://github.com/dvab-sarma/android_kernel_rk_opi/tree/add-rkvdec-vdpu381-vp9-v8">out-of-tree fork</a> maintained by D.V.A.B. Sarma. Collabora&#8217;s own blog post says &#8222;we hope to send a v1 to linux-media soon.&#8220; It is currently v8. v1 has not been sent.</p>
<p>We grabbed the three patches as <a href="https://git.reauktion.de/marfrit/kernel-agent"><code>kernel-agent</code></a>scope-tagged additions to<br />
<a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/fleet/ampere.yaml"><code>fleet/ampere.yaml</code></a>, rebuilt the kernel package, and verified: twenty-frame VP9 decode via the rkvdec block is byte-identical to the software reference.</p>
<p>The new <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/linux-ampere-fourier"><code>linux-ampere-fourier-7.0rc3.kafr2-1</code></a> kernel package ships with these patches integrated. Available now at <code>packages.reauktion.de/arch/aarch64/</code> for any RK3588 host on the <code>[marfrit]</code> repo.</p>
<h2>What the numbers actually look like</h2>
<table>
<thead>
<tr>
<th>Workload</th>
<th style="text-align: right;">CPU on ARM cores (software decode)</th>
<th style="text-align: right;">CPU on ARM cores (VPU-offloaded)</th>
<th style="text-align: right;">CPU freed</th>
</tr>
</thead>
<tbody>
<tr>
<td>1080p30 H.264, RK3399 (2×A72+4×A53)</td>
<td style="text-align: right;">60–80% on a single fast core</td>
<td style="text-align: right;">~5% (mostly demux + audio)</td>
<td style="text-align: right;">One A72 core&#8217;s worth</td>
</tr>
<tr>
<td>1080p30 VP9, RK3588 (4×A76+4×A55)</td>
<td style="text-align: right;">25–45% spread across cores</td>
<td style="text-align: right;">~3%</td>
<td style="text-align: right;">~one A76 core, fanning out</td>
</tr>
<tr>
<td>1080p24 AV1, RK3588</td>
<td style="text-align: right;">30–60% (8-core spread, dav1d)</td>
<td style="text-align: right;">&#8222;speed=1.36x&#8220; through <code>hwdownload</code>, fanless</td>
<td style="text-align: right;">Several A76 + A55 cores</td>
</tr>
<tr>
<td>4K HEVC, RK3399</td>
<td style="text-align: right;">basically doesn&#8217;t</td>
<td style="text-align: right;">bit-exact, fanless</td>
<td style="text-align: right;">All eight cores&#8216; worth in the limit</td>
</tr>
</tbody>
</table>
<p>The watt numbers are the same shape. Software VP9 at 1080p draws roughly four to seven watts of CPU on the Pi 5 / RK3588 class of SoC, sustained. Hardware decode of the same content draws under one watt. For a battery-powered ARM laptop that&#8217;s a three-to-five-times session-time improvement; for the global Pi 5 install base it&#8217;s electrons that were being spent on YouTube reviews of Apple products and are now not.</p>
<p>Whether that matters depends on your stance on YouTube reviews of Apple products.</p>
<h2>What&#8217;s still software-decoded, on purpose</h2>
<p>A few codec/host combinations are scoped out and we recommend they stay scoped out:</p>
<ul>
<li><strong>HEVC on RK3588.</strong> Fixable in principle — there&#8217;s a kernel oops in <code>rkvdec_hevc_prepare_hw_st_rps</code> from an uninitialized stack variable that has a one-line fix; the libva side needs another small patch to populate the EXT_SPS_RPS controls. We have all three issues filed, all three closed <code>EWONTFIX</code>. Reason: the fleet doesn&#8217;t use HEVC for anything we haven&#8217;t already covered. YouTube doesn&#8217;t serve HEVC. Netflix serves HEVC but only behind Widevine L1, which we don&#8217;t have on ARM, and the<br />
silicon for the <em>one</em> HEVC use case we have (archive playback on the RK3399 laptop) already works.</li>
<li><strong>H.264 Hi10P on the libva path (RK3588).</strong> Decode-side libva ctrl-submission is byte-different from ffmpeg&#8217;s; the kernel rejects with <code>V4L2_BUF_FLAG_ERROR</code>. Fixable with a two-to-four-hour debug session. The kdirect (<code>ffmpeg -hwaccel v4l2request</code>) path works bit-exact. Anyone who needs Hi10P decode through a browser-side libva consumer on RK3588 can speak up; nobody has. The use case for ten-bit H.264 is currently anime fansubs. The use case for <em>libva-routed</em> ten-bit H.264 anime fansubs is even narrower.</li>
<li><strong>HEVC on the Raspberry Pi 5.</strong> Kernel side is ready — Jonas Karlman&#8217;s <a href="https://patchwork.kernel.org/project/linux-media/cover/20250707115431.55603-1-jonas@kwiboo.se/"><code>rpi-hevc-dec</code></a>driver has been on the linux-media patchwork at v4 since July 2025. It is still not merged. The V4L2 stateless HEVC controls don&#8217;t carry enough of the bitstream&#8217;s syntax fields for our backend to populate them losslessly; the strict driver rejects what the lenient drivers accept. We forked a userspace path called <a href="https://git.reauktion.de/marfrit/daedalus-fourier"><code>daedalus-fourier</code></a> that toys with running codec firmware on the VideoCore VII programmable cores (the QPUs Broadcom marketed as a GPU but never shipped vendor codec firmware for, possibly because the licensing math at scale stopped making sense). Wax-and-feathers research-track. Don&#8217;t hold your breath.</li>
</ul>
<h2>Architecturally</h2>
<p>A working hardware decode stack on the Rockchip / Pi 5 fleet has the following layers:</p>
<pre><code>                ┌─────────────────────┐
                │  firefox / chromium │  ← VAAPI consumer
                │   /  mpv vaapi /    │     (browser does the demux,
                │   ffmpeg-vaapi      │     hands a frame at a time)
                └──────────┬──────────┘
                           │ libva ABI
                ┌──────────▼──────────────────┐
                │ libva-v4l2-request-fourier  │  ← us
                │  (our libva backend)        │
                └──────────┬──────────────────┘
                           │ V4L2 Request API
                ┌──────────▼──────────────────┐
                │  rkvdec / hantro-vpu /      │  ← Rockchip kernel driver
                │  rpi-hevc-dec               │
                └──────────┬──────────────────┘
                           │ register pokes
                ┌──────────▼──────────────────┐
                │ Silicon: VDPU381 / VEPU121  │  ← The 2018 fixed
                │  / hantro G1 / VideoCore    │     function block
                └─────────────────────────────┘
</code></pre>
<p>Each layer required a separate fork. Each fork is shipped as a package in <a href="https://git.reauktion.de/marfrit/marfrit-packages"><code>marfrit-packages</code></a>.<br />
The kernels are <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/linux-fresnel-fourier"><code>linux-fresnel-fourier</code></a>(RK3399) / <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/linux-ampere-fourier"><code>linux-ampere-fourier</code></a>(RK3588); the userspace side ships as <a href="https://git.reauktion.de/marfrit/libva-v4l2-request-fourier"><code>libva-v4l2-request-fourier</code></a>+ <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/ffmpeg-v4l2-request-fourier"><code>ffmpeg-v4l2-request-fourier</code></a>+ <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/mpv-fourier"><code>mpv-fourier</code></a>+ <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/firefox-fourier"><code>firefox-fourier</code></a>+ <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/chromium-fourier"><code>chromium-fourier</code></a>. None of these forks would be necessary if upstream landed faster. We did not say upstream is unmotivated. We are saying we wanted hardware decode in 2024 and have hardware decode in 2026.</p>
<h2>Install</h2>
<pre><code class="language-sh"># Arch / ALARM with the marfrit overlay enabled:
sudo pacman -Syu linux-ampere-fourier            # RK3588 (CoolPi GenBook)
sudo pacman -Syu linux-fresnel-fourier            # RK3399 (Pinebook Pro)
sudo pacman -Syu ffmpeg-v4l2-request-fourier      # any RK
sudo pacman -Syu libva-v4l2-request-fourier       # any RK
sudo pacman -Syu firefox-fourier mpv-fourier      # consumers
</code></pre>
<p>Browser-side, set <code>LIBVA_DRIVER_NAME=v4l2_request</code> in the environment, set the three patched-in <code>media.*</code> prefs in <code>about:config</code> (or just install <a href="https://git.reauktion.de/marfrit/marfrit-packages/src/branch/main/arch/firefox-fourier"><code>firefox-fourier</code></a>which has them baked).</p>
<p>Repo setup at <code>packages.reauktion.de</code>; pacman config snippets in the <a href="https://git.reauktion.de/marfrit/marfrit-packages"><code>marfrit-packages</code></a>README.</p>
<h2>&#8230; done.</h2>
<p>The fleet now decodes everything it usefully consumes in hardware. The Cortex-A76 cores can go back to compiling kernels, running language models, or doing nothing — they&#8217;re rated for it. The electrons formerly used for software video decode are now available for tasks of marginally greater social value, like playing back nerd reviews of overpriced laptops.</p>
<p>Hardware acceleration is supposed to be a solved problem. It mostly isn&#8217;t. But it&#8217;s a little more solved than it was this morning.</p>
<hr />
<p><em>If you&#8217;re running Rockchip silicon on Linux and want hardware decode that actually works, the packages above are public. File issues at the relevant <a href="https://git.reauktion.de/marfrit"><code>git.reauktion.de/marfrit/*</code></a> repo.<br />
Patches welcome; preferably for the codecs we said we don&#8217;t need.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The BESser patches: seven days of staging-prep for the PineTab2 Wi-Fi driver</title>
		<link>https://blog.reauktion.de/the-besser-patches-seven-months-of-staging-prep-for-the-pinetab2-wi-fi-driver/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Mon, 18 May 2026 14:27:54 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2864</guid>

					<description><![CDATA[Tour through a bes2600 patch series — from a self-healing disconnect handler to a factory-calibration cleanup, with a firmware-RE footnote.]]></description>
										<content:encoded><![CDATA[<p><!-- title: The BESser patches: seven months of staging-prep for the PineTab2 Wi-Fi driver --></p>
<p>
The Pine64 PineTab2 ships with a Bestechnic BES2600WM combo chip for Wi-Fi and Bluetooth. The Linux driver for it lives at <code>drivers/staging/bes2600/</code> in the <a href="https://codeberg.org/DanctNIX/linux-pinetab2">DanctNIX linux-pinetab2 fork</a>, and as a DKMS package in <a href="https://salsa.debian.org/Mobian-team/bes2600-dkms">Mobian&#8217;s bes2600-dkms</a>. Both descend from the same out-of-tree drop Bestechnic published in 2022 and which, to date, has not been upstreamed.
</p>
<p>
The driver works. It mostly works. It works in the way that any 2010s-vintage out-of-tree SDIO Wi-Fi driver works: well enough for the chip to associate, exchange frames, and reach the internet, and badly enough that you eventually start reading the source. What follows is a tour of the patch series that came out of that reading, in the rough order the issues surfaced. Patches live in <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600"><code>marfrit/kernel-agent/patches/driver/bes2600/</code></a>. Each subdirectory ships in two flavors: a <code>-danctnix</code> suffix for the in-tree build and a non-suffixed one for the Mobian DKMS variant, because the two trees disagree about timer APIs and a few function signatures.
</p>
<h2>Stage 1: the random disconnect</h2>
<p>
The entry point was a Wi-Fi connection that would simply die every once in a while and not come back without a <code>rmmod bes2600 && modprobe bes2600</code>. Logs showed <code>bes2600_bh_lmac_active_monitor</code> declaring &#8222;link break between lmac and host&#8220; — the firmware watchdog noticed that the LMAC had stopped acknowledging host pointers. So far, so reasonable. What it then did about that was less reasonable.
</p>
<p>
The recovery path called <code>bes2600_chrdev_wifi_force_close()</code>, which scheduled <code>sdio_scan_work</code>, which on the PineTab2 is a literal one-line stub:
</p>
<pre><code>
bes_warn("...this function does nothing\n");
</code></pre>
<p>
The companion <code>bes2600_sdio_on()</code> path then toggled <code>pdata->powerup</code>, which is <code>NULL</code> on this board because the Wi-Fi reset GPIO is owned by <code>sdio_pwrseq</code> and not by the bes2600 device-tree node. (The DT file&#8217;s own comment notes that the pin &#8222;is claimed by sdio_mmcseq, It is better to move it to U-Boot so the OS can use it.&#8220; Future work, presumably.)
</p>
<p>
Net result: the chip is never actually reset, the SDIO core never finds out the card is gone, and a subsequent <code>rmmod</code> leaves the SDIO function objects dangling. The recovery handler was, in effect, a no-op with logging.
</p>
<p>
<a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/lmac-recover-via-mmc-hw-reset"><code>lmac-recover-via-mmc-hw-reset</code></a> calls <code>mmc_hw_reset()</code> on the SDIO function instead. The MMC core re-probes, the driver re-binds, and the firmware re-loads. Disconnect events that previously required a manual <code>modprobe</code> now self-heal in about three seconds.
</p>
<h2>Stage 2: the scan-defer logic that didn&#8217;t defer</h2>
<p>
While instrumenting the disconnect, a second symptom appeared: bursts of failed scans during roaming. The firmware would <code>WSM_REQUIRED_CONFIRM</code> on a scan, the driver would log a warning, and mac80211 would retry roughly every 12 seconds. The kernel had a backoff guard in place — <code>BES2600_SCAN_BACKOFF_JIFFIES = 10 * HZ</code> — but the retry cadence was just outside that window, so every retry slipped through, the firmware rejected again, and the cycle continued until mac80211 gave up and sent <code>DEAUTH_LEAVING reason=3</code>.
</p>
<p>
<a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/scan-defer-on-reject"><code>scan-defer-on-reject</code></a> softens the WARN and introduces a reject counter so that the third in-window reject trips a real defer. <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/scan-defer-backoff-tune"><code>scan-defer-backoff-tune</code></a> widens the window from 10 s to 30 s — enough to catch the 12 s mac80211 cadence — and decays the counter on quiet periods so a slow trickle of legitimate failures doesn&#8217;t permanently lock out scans.
</p>
<p>
These two together turned roam-burst disconnects from &#8222;user-visible WiFi outage&#8220; into &#8222;two log lines and a slightly later association.&#8220;
</p>
<h2>Stage 3: the DMA out-of-bounds read</h2>
<p>
With KFENCE enabled in the kernel config, a different symptom showed up: a clean panic on heavy TCP transfer.
</p>
<pre><code>
BUG: KFENCE: out-of-bounds read in __pi_memcpy_generic
Out-of-bounds read at ... (704B right of kfence-#...):
  swiotlb_tbl_map_single
  ...
  bes_sdio_memcpy_to_io_helper [bes2600]
  sdio_tx_work [bes2600]
</code></pre>
<p>
The TX path rounds the DMA transfer length up to the host&#8217;s block size and passes the rounded length to <code>sg_set_buf()</code>. The <code>tx_buffer->buf</code> pointer, however, aliases an <code>skb</code> whose actual allocation matches the unrounded length. The DMA engine then reads up to one block past the end of the buffer. On boards without KFENCE this is invisible — the read is harmless padding — but the bug is real and would trip any future sanitizer. <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/tx-sdio-dma-oob"><code>tx-sdio-dma-oob</code></a> routes oversized transfers through a bounce buffer of the rounded length.
</p>
<h2>Stage 4: the power-management arc</h2>
<p>
Power management on the bes2600 is a small theatre of state machines that occasionally lose track of each other. Five patches address overlapping symptoms:
</p>
<ul>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/pm-state-resync"><code>pm-state-resync</code></a> — fixes lost wake events when the firmware ACK arrives out of order with the host state update.</li>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/pm-timeout-silence"><code>pm-timeout-silence</code></a> — replaces a deeply nested 30-second timeout WARN with a single rate-limited info-level log line. The timeout was a known, recoverable condition; logging it as <code>WARN_ON</code> was just generating noise.</li>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/pm-wake-consume-state"><code>pm-wake-consume-state</code></a> — ensures the wake-handler actually consumes the pending wake state instead of leaving it set, which previously caused phantom re-wakes.</li>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/pm-gate-on-handshake"><code>pm-gate-on-handshake</code></a> — gates LP-mode entry on a successful per-device handshake rather than firing it unconditionally.</li>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/pm-detect-firmware-unsupported"><code>pm-detect-firmware-unsupported</code></a> — detects when the loaded firmware does not actually implement the PM protocol and disables PM gracefully rather than wedging.</li>
</ul>
<p>
None of these are individually exciting; together they cut the PM-related kernel log noise by about 90% and stopped two specific suspend/resume hangs.
</p>
<h2>Stage 5: the factory-calibration cleanup</h2>
<p>
The driver loads per-device calibration data from a 30-field text file. Upstream-wise this is also where things get embarrassing: the original code path was <code>filp_open()</code> plus <code>kernel_read()</code> against a hard-coded <code>/lib/firmware/bes2600_factory.txt</code>, which is a kernel-mainline anti-pattern dating back to before <code>request_firmware()</code> was ubiquitous. Worse, the path was being constructed against <code>NULL</code> device contexts, which generated the boot-time spam <code>(NULL device *): read and check /lib/firmware/bes2600_factory.txt error</code> on every probe.
</p>
<p>
The <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/factory-series"><code>factory-series</code></a>, <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/factory-thread-dev"><code>factory-thread-dev</code></a>, and <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/factory-drop-kernel-write"><code>factory-drop-kernel-write</code></a> patches route the read through <code>request_firmware()</code>, rename the file to match <code>firmware-class</code> conventions (<code>bes2600/bes2600_factory.txt</code>), and thread a real <code>struct device *</code> through so the firmware loader has somewhere to log. A companion patch flips <code>STANDARD_FACTORY_EFUSE_FLAG</code> from default-on to default-off, because the file that the PineTab2 actually ships has 30 fields and the parser was expecting 31 (with the missing <code>##select_efuse_flag</code> section generating a parse error on every load — which the driver, naturally, swallowed silently).
</p>
<p>
<a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/drop-dpd-file-paths"><code>drop-dpd-file-paths</code></a> and <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/drop-orphan-file-io"><code>drop-orphan-file-io</code></a> remove the remaining <code>filp_open()</code> call sites elsewhere in the tree.
</p>
<h2>Stage 6: the housekeeping</h2>
<p>
Two upstreaming-prep changes round out the series:
</p>
<ul>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/remove-chardev-user-interface"><code>remove-chardev-user-interface</code></a> — drops the <code>/dev/bes2600</code> character device. It exposed a small ad-hoc ioctl surface that no userspace ever stabilised against, and which would block the driver from leaving <code>staging/</code>. Anyone who needs the equivalent can use <code>nl80211</code> debug attributes.</li>
<li><a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/enable-testmode"><code>enable-testmode</code></a> — sets <code>CONFIG_BES2600_TESTMODE=y</code> by default for in-tree builds, because the test hooks were already compiled in for DKMS but not for danctnix.</li>
</ul>
<p>
Plus one trivial <a href="https://git.reauktion.de/marfrit/kernel-agent/src/branch/main/patches/driver/bes2600/debian-copyright-fsf-address"><code>debian-copyright-fsf-address</code></a> update so <code>lintian</code> stops complaining, which matters only if you build the Debian DKMS package.
</p>
<h2>Genealogy footnote</h2>
<p>
The bes2600 driver is, at the source level, a fork of the ST-Ericsson CW1200 (<code>drivers/net/wireless/st/cw1200/</code>): same author (Dmitry Tarnyagin), same WSM host/firmware protocol, same SDIO bus backend, and surviving Kconfig markers (<code>CONFIG_BES2600_USE_STE_EXTENSIONS</code>, <code>CONFIG_BES2600_WSM_DEBUG</code>) that read as ST-Ericsson archaeology. ST-Ericsson wound down in 2013; Bestechnic was founded in 2015. The IP lineage is presumably a license or an asset purchase, but no <code>linux-wireless</code> RFC has ever connected the two trees, and the bes2600 maintainers have not commented on it.
</p>
<h2>What was left out: firmware reverse-engineering</h2>
<p>
Everything above is host-side. The bes2600 firmware itself — the blob the host downloads onto the chip&#8217;s internal MCU at probe time — is opaque, undocumented, and almost certainly the source of more than one of the symptoms the host-side patches work around. (The &#8222;link break between lmac and host&#8220; condition, for instance, would be far more cheaply diagnosed if the LMAC side were inspectable.)
</p>
<p>
Reverse-engineering it is a legitimate next step. The firmware images are roughly 600 KB, fit on a single SDIO download, and the chip&#8217;s MCU is documented to be a single Cortex-M class core. None of that work has been done here, on the grounds that the host-side cleanup is already a self-contained body of work and the firmware RE would dwarf it by an order of magnitude. Parked for a future hacking weekend that we will all enthusiastically agree should happen sooner rather than later, and then will not happen for another year.
</p>
<p>
In the meantime the host-side patches are upstreamable, individually testable, and bisectable. The full series applies cleanly against <code>linux-pinetab2 6.19.10-danctnix1-1</code> and a representative subset has been validated on Mobian DKMS via the <code>-danctnix</code>/non-suffixed variants. Mirrored in <a href="https://git.reauktion.de/marfrit/kernel-agent"><code>marfrit/kernel-agent</code></a>; the original umbrella issue thread is at <a href="https://git.reauktion.de/marfrit/besser"><code>marfrit/besser</code></a> for anyone who enjoys reading commits in reverse.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Eurotronic Comet WiFi: Ditching the Cloud for Local Home Assistant Control</title>
		<link>https://blog.reauktion.de/eurotronic-comet-wifi-local-home-assistant/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 10:14:22 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2860</guid>

					<description><![CDATA[How to integrate Eurotronic Comet WiFi thermostats into Home Assistant using DNS redirect and local MQTT — no cloud, no subscription, no custom firmware.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I have three Eurotronic Comet WiFi thermostats. They work fine. The app works fine. But every morning I&#8217;d watch my Home Assistant logs fill up with connection attempts going out to some <code>mqtt3.eurotronic.io</code> endpoint and think: this is not how I want my heating to work. My radiators should not depend on a server somewhere in Germany staying online. So I fixed it.</p>



<p class="wp-block-paragraph">This post is the writeup I wish existed when I started. It took a weekend of packet sniffing, failed HACS integrations, and one very satisfying Pi-hole rule to get here.</p>



<h2 class="wp-block-heading">What&#8217;s Actually Inside These Things</h2>



<p class="wp-block-paragraph">The Comet WiFi runs on a Dialog Semiconductor DA16200 WiFi chip. That&#8217;s important because it immediately rules out a few popular options: no Tuya compatibility, no custom firmware path, nothing in ESPHome. The DA16200 is not an ESP8266. You&#8217;re not flashing this thing.</p>



<p class="wp-block-paragraph">What the thermostat <em>does</em> do is speak MQTT — and only MQTT — to a fixed set of cloud hostnames: <code>mqtt.eurotronic.io</code>, <code>mqtt1.eurotronic.io</code> through <code>mqtt5.eurotronic.io</code>. No local API. No mDNS. No REST endpoint. Just MQTT, pointed permanently at the cloud.</p>



<p class="wp-block-paragraph">The moment I confirmed this with Wireshark I knew exactly what to do.</p>



<h2 class="wp-block-heading">The Interception: Pi-hole + Local Mosquitto</h2>



<p class="wp-block-paragraph">The plan is elegant: intercept the DNS queries for those cloud hostnames and point them at your own Mosquitto broker. The thermostats never know the difference. They connect, authenticate, and start chattering away — just to <em>your</em> broker instead of Eurotronic&#8217;s.</p>



<p class="wp-block-paragraph">In Pi-hole, add custom DNS records for every variant:</p>



<pre class="wp-block-code"><code>mqtt.eurotronic.io   → 192.168.0.10
mqtt1.eurotronic.io  → 192.168.0.10
mqtt2.eurotronic.io  → 192.168.0.10
mqtt3.eurotronic.io  → 192.168.0.10
mqtt4.eurotronic.io  → 192.168.0.10
mqtt5.eurotronic.io  → 192.168.0.10</code></pre>



<p class="wp-block-paragraph">Replace <code>192.168.0.10</code> with whatever IP your Mosquitto instance is running on. Don&#8217;t skip any of the numbered variants — the firmware will try several of them before giving up, and you want all paths leading home.</p>



<p class="wp-block-paragraph">On the Mosquitto side, since all devices in a single Eurotronic installation share the same MQTT username and password (yes, really — one credential set for all your thermostats), and since you now own the broker, you can simply enable anonymous access:</p>



<pre class="wp-block-code"><code>allow_anonymous true
listener 1883</code></pre>



<p class="wp-block-paragraph">Counterintuitively, this is actually <em>more</em> secure than the cloud setup. Before, your thermostat data was transiting someone else&#8217;s infrastructure. Now it never leaves your LAN.</p>



<h2 class="wp-block-heading">The MQTT Protocol</h2>



<p class="wp-block-paragraph">Once the thermostats are talking to your broker, subscribe to <code>#</code> and watch the traffic. You&#8217;ll see topics structured like this:</p>



<pre class="wp-block-code"><code>02/PREFIX/MAC/V/A0   ← values coming FROM the device
02/PREFIX/MAC/S/A0   ← commands going TO the device</code></pre>



<p class="wp-block-paragraph">The <code>PREFIX</code> and <code>MAC</code> are device-specific — just watch the broker traffic after your thermostats connect and you&#8217;ll spot them immediately. The registers you actually care about:</p>



<ul class="wp-block-list"><li><strong>A0</strong> — target temperature (setpoint)</li><li><strong>A1</strong> — current measured temperature</li><li><strong>A5</strong> — window open detection</li><li><strong>A6</strong> — battery level</li></ul>



<p class="wp-block-paragraph">Temperature values are encoded as hex, prefixed with <code>#</code>, where the hex value equals temperature × 2. So 21.0°C becomes <code>#2a</code> (42 in decimal, 0x2a in hex). 18.5°C is <code>#25</code>. Weird encoding, but consistent.</p>



<p class="wp-block-paragraph">For polling, publish to the <code>S/AF</code> topic. Two useful payloads:</p>



<ul class="wp-block-list"><li><code>#01000000</code> — returns the current active setpoint cleanly</li><li><code>#02000000</code> — triggers an immediate current temperature report</li></ul>



<p class="wp-block-paragraph">You might find documentation elsewhere suggesting <code>#0b</code> on <code>S/A0</code> for polling. I did too. It&#8217;s slow, unreliable, and sometimes returns schedule data mixed in with the current value. Avoid it. The <code>AF</code> approach is much cleaner.</p>



<p class="wp-block-paragraph">One critical rule: <strong>never use the retain flag</strong> on any messages you publish. Retained messages get replayed to the thermostat every time it reconnects — which means your retained setpoint command will constantly override whatever the device&#8217;s internal heating schedule is trying to do. It&#8217;s a subtle bug that&#8217;ll have you wondering why your thermostat is ignoring its schedule.</p>



<h2 class="wp-block-heading">Home Assistant Integration — Skip the HACS Plugin</h2>



<p class="wp-block-paragraph">There&#8217;s a HACS integration called <code>comet_wifi_integration</code>. I tried it. It has bugs, and more critically it uses QoS 2 for MQTT delivery, which HA&#8217;s MQTT client handles poorly. Messages get dropped, entities get stuck, it&#8217;s frustrating.</p>



<p class="wp-block-paragraph">The better approach: use Home Assistant&#8217;s built-in MQTT climate entity via YAML. It&#8217;s rock solid and gives you full control.</p>



<p class="wp-block-paragraph">In your <code>mqtt.yaml</code>:</p>



<pre class="wp-block-code"><code>climate:
  - name: Wohnzimmer
    temperature_command_topic: "02/PREFIX/MAC/S/A0"
    temperature_command_template: >-
      {{ "#%02x" % ((value | float * 2) | int) }}
    temperature_state_topic: "02/PREFIX/MAC/V/A0"
    temperature_state_template: "{{ int(value[1:3],base=16)/2 }}"
    current_temperature_topic: "02/PREFIX/MAC/V/A1"
    current_temperature_template: "{{ int(value[1:3],base=16)/2 }}"</code></pre>



<p class="wp-block-paragraph">The templates handle the hex encoding automatically. The command template converts a float like <code>21.0</code> into <code>#2a</code>. The state templates do the reverse. Swap <code>PREFIX</code> and <code>MAC</code> with your actual device values, repeat for each thermostat.</p>



<p class="wp-block-paragraph">For polling, add an automation that fires every 15 minutes:</p>



<pre class="wp-block-code"><code>alias: Poll Comet WiFi Thermostats
trigger:
  - platform: time_pattern
    minutes: "/15"
action:
  - service: mqtt.publish
    data:
      topic: "02/PREFIX/MAC/S/AF"
      payload: "#01000000"
  - service: mqtt.publish
    data:
      topic: "02/PREFIX/MAC/S/AF"
      payload: "#02000000"</code></pre>



<p class="wp-block-paragraph">Battery and window sensors follow the same pattern using MQTT <code>sensor</code> and <code>binary_sensor</code> entities — same topic structure, same hex decoding.</p>



<h2 class="wp-block-heading">One Thing to Keep in Mind</h2>



<p class="wp-block-paragraph">The Comet WiFi has an internal heating schedule that runs independently of anything you do via MQTT. If you set a temperature through Home Assistant, it&#8217;ll hold — until the thermostat&#8217;s next scheduled time slot kicks in and overrides it. This is the same behavior you&#8217;d get with the official app. It&#8217;s not a bug in your setup; it&#8217;s just how the device works. Plan your automations around it, or accept that the schedule has the final word.</p>



<h2 class="wp-block-heading">The Result</h2>



<p class="wp-block-paragraph">Three thermostats, fully local. Real-time temperature readings in Home Assistant. Target temperature control. Battery monitoring. Window-open detection. Zero cloud dependency. The whole setup survives internet outages without a hiccup.</p>




<h2 class="wp-block-heading">How We Got Here</h2>



<p class="wp-block-paragraph">Full disclosure: I built this integration in a pair-programming session with Claude Code, Anthropic&#8217;s CLI coding assistant. Claude handled the broker setup, DNS configuration, and initial HA integration code — but the existing community documentation and the HACS plugin both had gaps that only showed up during real-world testing. The <code>#0b</code> polling command that everyone recommends? Unreliable. The QoS 2 MQTT subscriptions in the custom integration? Silently broken in HA. The retain flag? A landmine waiting to blow up your heating schedule.</p>



<p class="wp-block-paragraph">Each of these issues required hands-on debugging — me watching thermostat displays, checking if temperatures actually changed, opening windows to test sensors — while Claude analyzed the MQTT broker logs and iterated on the configuration. The <code>S/AF</code> polling commands and the distinction between <code>#01000000</code> and <code>#02000000</code> came from sniffing what the official Eurotronic app actually sends, which turned out to be completely different from what the community had documented.</p>



<p class="wp-block-paragraph">It took more reverse engineering than it should have — Eurotronic publishes nothing about this protocol — but once you have the DNS intercept in place and understand the hex encoding, the rest falls into place quickly. If you&#8217;re sitting on a pile of Comet WiFi thermostats wondering why there&#8217;s no clean local integration, this is your path forward.</p>



<h2 class="wp-block-heading">P.S. — The Jinja2 Trap</h2>



<p class="wp-block-paragraph">If your battery sensors show suspiciously low values, check your template. In Python, <code>int("3C", 16)</code> means &#8222;parse as base 16&#8220; and returns 60. In Jinja2, the same syntax means &#8222;use 16 as the default if parsing fails.&#8220; The correct Jinja2 for hex conversion is <code>{{ value[1:] | int(base=16) }}</code>, not <code>{{ int(value[1:], 16) }}</code>. This applies to battery values but not temperatures — the temperature registers happen to use only digits 0-9 in their hex encoding at typical room temperatures, so the bug is invisible until a value contains A-F.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Markus &#038; Claude</title>
		<link>https://blog.reauktion.de/markus-claude/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Sat, 28 Mar 2026 12:52:16 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2855</guid>

					<description><![CDATA[Successfully used @AnthropicAI Claude Code to develop mainline Linux kernel patches for the CoolPi CM5 GenBook (RK3588)! 🎉Patches available at: https://github.com/marfrit/misc_patches Now tackling the Radxa Rock 5 ITX+ — dual 4K display support on mainline is next. Huge thanks to @Collabora for their incredible upstream RK3588 work 🙏 And suspend for the GenBook is next...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Successfully used @AnthropicAI Claude Code to develop mainline Linux kernel patches for the CoolPi CM5 GenBook (RK3588)! 🎉Patches available at: https://github.com/marfrit/misc_patches</p>



<p class="wp-block-paragraph">Now tackling the Radxa Rock 5 ITX+ — dual 4K display support on mainline is next. Huge thanks to @Collabora for their incredible upstream RK3588 work 🙏</p>



<p class="wp-block-paragraph">And suspend for the GenBook is next as soon as an appropriate UART cable arrives&#8230;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>coolpi loader</title>
		<link>https://blog.reauktion.de/coolpi-loader/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Sat, 24 Jan 2026 23:52:07 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2853</guid>

					<description><![CDATA[Das Mysterium des GenBook Boots ist gelöst: das OEM image ist eines für unterschiedliche Geräte des Herstellers. Der Bootloader des Herstellers ist Gerätespezifisch und ändert extlinux.conf so, dass der richtige Device Tree geladen wird. Gewöhnungsbedürftiger Hack!]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Das Mysterium des GenBook Boots ist gelöst: das OEM image ist eines für unterschiedliche Geräte des Herstellers. Der Bootloader des Herstellers ist Gerätespezifisch und ändert extlinux.conf so, dass der richtige Device Tree geladen wird. Gewöhnungsbedürftiger Hack!</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>cool-pi GenBook</title>
		<link>https://blog.reauktion.de/cool-pi-genbook/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Fri, 23 Jan 2026 11:51:45 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2849</guid>

					<description><![CDATA[[ &#160;&#160;&#160;0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050][ &#160;&#160;&#160;0.000000] Linux version 6.18.6-1-aarch64-ARCH (builduser@arch-nspawn-106937) (aarch64-unknown-linux-gnu-gcc (GCC) 15.2.120251112, GNU ld (GNU Binutils) 2.45.1) #1 SMP PREEMPT_DYNAMIC Mon Jan 19 13:22:47 UTC 2026[ &#160;&#160;&#160;0.000000] random: crng init done[ &#160;&#160;&#160;0.000000] Machine model: CoolPi CM5 GenBook Something strange &#8211; the original boot loader seems to overwrite extlinux.conf first 27...]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><code>[ &nbsp;&nbsp;&nbsp;0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050]<br>[ &nbsp;&nbsp;&nbsp;0.000000] Linux version 6.18.6-1-aarch64-ARCH (builduser@arch-nspawn-106937) (aarch64-unknown-linux-gnu-gcc (GCC) 15.2.1<br>20251112, GNU ld (GNU Binutils) 2.45.1) #1 SMP PREEMPT_DYNAMIC Mon Jan 19 13:22:47 UTC 2026<br>[ &nbsp;&nbsp;&nbsp;0.000000] random: crng init done<br>[ &nbsp;&nbsp;&nbsp;0.000000] Machine model: CoolPi CM5 GenBook<br></code></p>



<p class="wp-block-paragraph">Something strange &#8211; the original boot loader seems to overwrite extlinux.conf first 27 bytes with </p>



<p class="wp-block-paragraph"><code>default coolpi_rk3588_gbook</code></p>



<p class="wp-block-paragraph">but extlinux treats the following line </p>



<p class="wp-block-paragraph"><code>default arch</code></p>



<p class="wp-block-paragraph">as the one being evaluated.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Network-Manager: Wifi found, no connection</title>
		<link>https://blog.reauktion.de/network-manager-wifi-found-no-connection/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Tue, 28 Sep 2021 11:32:23 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[network-manager]]></category>
		<category><![CDATA[reason=40]]></category>
		<category><![CDATA[secret]]></category>
		<category><![CDATA[wifi]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2826</guid>

					<description><![CDATA[I had a problem with my Centrino-Wifi not connecting to my WLAN. Turns out, Network-Manager defaults to WPA-PERSONAL-3, which my wifi card was not capable of. Changing that to WPA-PERSONAL-2 allow the connection to be established.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I had a problem with my Centrino-Wifi not connecting to my WLAN. Turns out, Network-Manager defaults to WPA-PERSONAL-3, which my wifi card was not capable of. Changing that to WPA-PERSONAL-2 allow the connection to be established. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hasu USB to USB Controller Converter » 1upkeyboards</title>
		<link>https://blog.reauktion.de/hasu-usb-to-usb-controller-converter-1upkeyboards/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Thu, 20 Aug 2020 13:44:32 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[qmk]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2813</guid>

					<description><![CDATA[  Turn almost any USB keyboard into a programmable keyboard! This converter, created by Hasu, allows you to change the keymap and add functions through TMK firmware. NO soldering required. Externally attached. Add up to 7 layers and up to 32 Fn keys. Supports 6KRO (or NKRO keyboards that will work in 6KRO mode). Media/System...]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.1upkeyboards.com/shop/controllers/usb-to-usb-converter/"><img decoding="async" class="alignnone size-full" src="https://blog.reauktion.de/wp-content/uploads/2020/08/3-wbLjV6J.jpg" alt="" /></a></p>
<blockquote><p>  Turn almost any USB keyboard into a programmable keyboard! This converter, created by Hasu, allows you to change the keymap and add functions through TMK firmware. NO soldering required. Externally attached. Add up to 7 layers and up to 32 Fn keys. Supports 6KRO (or NKRO keyboards that will work in 6KRO mode). Media/System control keys and ‘Fn’ key are not recognized by the converter, but will still function as originally programmed on the board.   Please check Hasu’s geekhack thread below for the current list of compatible and incompatible keyboards as well as additional information.</p></blockquote>
<p>Quelle: <em><a href="https://www.1upkeyboards.com/shop/controllers/usb-to-usb-converter/">Hasu USB to USB Controller Converter » 1upkeyboards</a></em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Proxy error in discover and pkcon</title>
		<link>https://blog.reauktion.de/proxy-error-in-discover-and-pkcon/</link>
		
		<dc:creator><![CDATA[Markus Fritsche]]></dc:creator>
		<pubDate>Wed, 12 Aug 2020 21:09:01 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[discover]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[PackageKit]]></category>
		<category><![CDATA[plasma]]></category>
		<guid isPermaLink="false">https://blog.reauktion.de/?p=2809</guid>

					<description><![CDATA[Finally found a solution to my problem of discover not working correctly after changing my KDE proxy settings: sudo rm /var/lib/PackageKit/transactions.dbsudo systemctl restart packagekit.service Source]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Finally found a solution to my problem of discover not working correctly after changing my KDE proxy settings: </p>



<p class="wp-block-paragraph"><code>sudo rm /var/lib/PackageKit/transactions.db</code><br><code>sudo systemctl restart packagekit.service</code></p>



<p class="wp-block-paragraph"><a href="https://github.com/hughsie/PackageKit/issues/392">Source</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
