u/cristian_dc

Image 1 — I turned an old Redmi Note 9 Pro into a native Linux server: postmarketOS, Ethernet + PD, and a custom display dashboard
Image 2 — I turned an old Redmi Note 9 Pro into a native Linux server: postmarketOS, Ethernet + PD, and a custom display dashboard
▲ 134 r/homelab

I turned an old Redmi Note 9 Pro into a native Linux server: postmarketOS, Ethernet + PD, and a custom display dashboard

A friend of mine wanted something to mess with and actually learn from, but buying another SBC just for that felt a bit stupid.
Then I remembered he still had his old Redmi Note 9 Pro somewhere.
My first thought was: fine, let's put Debian in a VM on Android and call it a day.
Then I thought about it for more than five minutes and realized that was boring.
I checked postmarketOS support, found out miatoll was still being maintained, and at that point the obvious bad idea became: why keep Android at all?
So we removed it.

A few days later the phone was booting native postmarketOS, accessible over SSH, with a 128 GB microSD for extra storage.
At that point we already had a perfectly usable little ARM server.
We could have stopped there.
Obviously we didn't.

The phone still had a 1080x2400 display, touchscreen, ambient light sensor, accelerometer, battery, USB-C...
Basically a bunch of hardware that would have just sat there doing nothing.
So I started wondering how much of it we could actually reuse.

The kernel didn't have framebuffer console rotation enabled, so instead of going down the kernel rebuild rabbit hole just to rotate a TTY, we ended up rendering our own dashboard with Pillow and writing it directly to /dev/fb0.
Then, since things were already getting stupid, we added:
• system, network and service stats on the built-in display
• automatic brightness using the ambient light sensor
• automatic landscape orientation using the accelerometer
• display off from 00:00 to 08:00
• touch to wake for 30 seconds
• persistent microSD storage

And again, we could have stopped there.

The next day I started thinking that Wi-Fi was still a pointless bottleneck for something sitting literally on top of the router, especially if he eventually wanted to play with WireGuard, NetBird, remote services, file transfers, whatever.
So we bought a USB-C hub with Gigabit Ethernet and PD passthrough.
Ethernet worked almost immediately.
Great.
Then we connected power.

Linux started throwing kernel Oopses and the network died.
The phone itself stayed on, but networking would completely shit itself and the display started filling with kernel logs.
So we started digging.

We found a missing Realtek firmware package, installed it, rebooted, tested again, and... nope.
Still broken.
Eventually the interesting part turned out to be the device tree.

The sm7125-xiaomi Type-C connector was described as:
power-role = "source";

Which is not exactly ideal when you want the phone to stay USB host for Ethernet while also receiving power through the same port.
So we patched the DTB to use a dual role with sink preference and 5 V sink PDOs.

Of course that wasn't the end of it.
Simply putting the patched DTB in /boot/dtbs did absolutely nothing because U-Boot was not loading it the way we expected.
After another round of debugging, we finally got the correct override into the boot entry.

At that point we had:
• native postmarketOS
• Gigabit Ethernet on eth0
• USB-C PD at 5 V / 2 A
• Wi-Fi disabled
• custom local dashboard
• automatic brightness and orientation
• touchscreen and sensors still doing something useful instead of being dead weight

Then we spent a completely unreasonable amount of time testing chargers and cables because some combinations worked and others absolutely did not.
The funny part is that the 20 W PD charger we bought specifically for this thing looked like one of the broken ones for half the afternoon.
Then we tried it again with its original USB-C cable.
And it worked.

So yes, after all of that, the final setup is actually running Ethernet and power through the same USB-C hub.

We documented the DTB fix, the reapply script and the crash logs here:
https://github.com/MarcoBllfr/miatoll-usb-pd-ethernet-fix

The repo now belongs to my friend Marco since this is his machine, and we're hoping to use this whole mess as an excuse to learn how contributing something upstream actually works.
No PR yet.
That's the next rabbit hole.

AI disclosure because I know this sub understandably cares about it:
I used a coding agent heavily during the whole thing for checking commands, digging through logs, writing the dashboard and scripts, and helping investigate the DTB and USB problem.
I was the one driving the process, testing every change on the actual hardware and deciding what to try next, but I definitely did not become a Linux kernel developer in one afternoon.
Half of the fun for me was exactly that.
I was poking at stuff I've heard about for years without pretending I suddenly understand all of it.

I wrote the full story here, with all the photos and the parts where things went wrong:
https://okazakee.dev/en/blog/19/why-buy-a-raspberry-when-you-have-a-redmi

Main takeaway for me: we leave an absurd amount of perfectly usable ARM hardware sitting in drawers just because the vendor stopped expecting us to use it.
This thing has a decent SoC, RAM, storage, a battery, a display, sensors, USB-C and now native Linux.
And yes, buying a Raspberry Pi would have been way easier.

u/cristian_dc — 4 days ago
▲ 1 r/webdev

I built blurkit, a universal image placeholder library for Node, Bun, Deno, browser, edge, and Cloudflare

Every image placeholder solution I found either tied you to a specific framework, needed multiple libs for combined operations and I was just not understanding why nobody wrapped everything together.

So I built blurkit. It takes an image input and returns a ready-to-use dataURL plus the hash and metadata, with explicit runtime entrypoints so bundlers never accidentally pull in the wrong code.

import { encode } from 'blurkit/node'

const result = await encode('./public/hero.jpg')
console.log(result.dataURL) // ready to drop into <img placeholder="...">
console.log(result.hash)    // blurhash or thumbhash string

What it supports:

  • BlurHash and ThumbHash
  • Explicit imports: blurkit/node, blurkit/browser, blurkit/edge, blurkit/cloudflare, blurkit/wasm, blurkit/deno
  • Batch encoding with encodeMany() and encodeManySettled() for fail-fast vs partial success workflows
  • CLI for single images and folder manifests
  • Cache interface with memory, filesystem, and Cloudflare Worker helpers

Install:

npm install blurkit

Minimal working examples for Next.js and Astro are in the repo. It's at v0.1.x so feedback is very welcome, especially if something breaks in your runtime.

Live demo: https://blurkit.okazakee.dev GitHub: https://github.com/Okazakee/blurkit

u/cristian_dc — 5 months ago