A proof-of-concept Linux kernel driver which continuously collects kernel messages (kmsg) and during a panic, dumps it all from the beginning in batches. This provides a debugging solution when only Simple Framebuffer is available, and things like PSTORE, USB or UART are unavailable.
Simply download the zip/git clone this repo and place it in drivers/misc, or wherever you want, ensuring to add the dir in Makefile and Kconfig of misc. i.e source "drivers/misc/qrcon/Kconfig"
and obj-y += qrcon/
Note: Only tested on 6.14 and 6.1. >4.19 requires additional modifications
Some important settings to adjust depending on your screen size are:
static int qr_position = QRPOS_CENTER;
static int qr_x_offset = 0;
static int qr_y_offset = 0;
static int qr_size_percent = 100;
static int qr_border = 5;
note: if you have a larger screen you can place a small version in the corner to see both console and qrcodes!
static int qr_version = 20; // around ~842 bytes (1-40)
static int qr_refresh_delay = 700; // give you enough time to scan the qrcode
static int recent_only = 0; // optionally show only recent messages for panic
static int reboot_to_bootloader = 0; // optionally reboot to bootloader if supported
The qrcode generation batch will automatically trigger after a panic. It likely won't survive a catostrophic panic, but it has not been tested.
Download the Binary Eye app on Android and enable continuous scanning. (optionally enable qrcode only mode)
Usage:
./decode.py # On Termux: Monitor Binary Eye DB for QR codes and log decoded kernel messages.
./decode.py <filename> # Read hex data or JSON from the specified file, decode, and print.
./decode.py -h | --help # Show this help message.
- Root is required
- Setup ssh to your device, i.e
ssh u0_a129@192.168.8.XXX -p 8022
- Enter
tsu
- Run
python3 decode.py &
- Read logs using
cat logs/1.log
, etc, this can be adjusted in the code
- After scanning go to history, select everything, export as JSON, and share with localsend/termux, etc.
- Use decode.py "json" to decode with color like dmesg :D
You can use panic=1
for panic auto-reboot.
Note: The final qrcode may look strange, that is normal, it's simply padding to ensure a fixed size.
It is only really useful in a niche set of circumstances, specifically when mainlining Android devices, Just early enough that only simple-framebuffer works. Usually this would be enough on its own, but you won't see any kernel messages before simple-framebuffer and framebuffer console was initialized, hence why I created this.
An example on how you can use this with initramfs for debugging usb, ufs, clk, can be found here
- This was hacked up in a couple of days, and largely written by AI as a proof of concept, if you couldn't tell from the code quality... but it miraculously works.
- Expect horrendous bugs
The QR code library originally came from drm_panic_qr, but was "re-written" from Rust to C for the following reasons:
- I am too much of a novice to understand it
- Rust is incompatible on older Linux/Android kernel versions, i.e, >4.19 >6.1
- I have no clue how Claude managed to one-shot this, I am in fear
Clean up AI slop basically
- Find a better solution instead of expensive binary search?
- Remove 2.5% numeric overhead calculation in qr_max_data_size since we dont use it?