Libreboot’ing an X200 using a CH341a based programmer
Jun 4th, 2019 by miki

Here’s a preliminary HOWTO from my recent external flashing of the BIOS ROM on a Lenovo X200 thinkpad (Wikipedia). The particular firmware flashed was a Libreboot build for this machine (instructions for X200 and details of the external flashing procedure) but anything goes (but anything may not be useful, though).

I’ll amend this HOWTO with more detailed instructions and pictures in the following days (warning: a prediction) to hopefully make it more complete and useful for the vary inhabitants of LibreBootLand.

Some parts

A programmer kit was bought on AliExpress for $4.20 containing a USB programmer board and an SOIC-8 clip which ended up not being used as the particular X200 had a SOIC-16 chip so a separately ordered SOIC-16 chip ($3.11)  was used.

“MinProgramment” aka. CH341a Programmer

Buy: @ $4.20

The programmer is based on the WCH CH341a chip which is an USB <-> seriel/parallel/uart interface. The manufacturer WCH being  WinChipHead aka. WCH (Nanjing QinHeng Electronics Co.,Ltd) (maybe also aka. WCH-IC (Jiangsu Qinheng Co., Ltd)). There are lots of options for buying board varieties based on the CH341a chip, to get you started here is a BangGood search and an AliExpress search.

Boards like this has also been described by others including a deduced schematic, EEVblog critique of the I/O pin power on similar boards (not yet confirmed whether that is true for this programmer too, I guess so, but at least one flashing done without damage) and a mention on hackaday of other board types.

There are a bunch of downloads from the WCH site regarding the chip including  a Chinese datasheet, no English language documentation seems to be available from the manufacturer however. There are some English editions of the datasheet to be found, of unknown origin. They seem plausible enough to use, though. Somebody has attempted to collect documentation about the chip in a Git repository.

The SOIC-16 Clip (aka. Pomona 5252)

Buy: @ $3.11

To attach physically to the Macronix MX25L6405D flash memory chip in a SOIC-16 package present on the X200 in question (words are that this is the norm although the board can be populated with a SOIC-8 too) a clip that matches the pins of the SOIC-16 package is needed. I bought the one mentioned above for $3.11 at random from AliExpress and this worked fine. In the pictures the wiring is hooked up correctly to the programmer to allow for flashing as described below.


WARNING: Below is still a draft made from mental notes! Ask me if you need more information or check back soon (I promise).


6405 <-> CH341a

MISO<->MIOS (label error, should be MISO)



CS <-> SS


First tried driving the the flash chip from VDD on ch341a but this was unsuccessful, no chip could be found, so the 6405 was hooked up to external 3.3v power supply with supply GND connected to GND on CH341a to align the ground potential between ch341a I/O supply and 6405 supply (important!).


Machine being flashed

Update Embedded Controller

To get the latest ECP (Embedded Controller Program) from Lenovo (no free alternative exists) containing software for the MCU controlling low level hardware like battery charging/keyboard/backlight stuff you need to update the BIOS which also updates the ECP. Most recent version for X200 is “BIOS: 3.22 / ECP: 1.07“. This is not needed if you already have these versions on the machine, check current versions by pressing ThinkVantage during boot and choosing “Enter Setup”.

If your system has a Windows installation download and run the “BIOS Update Utility“executeable. Else you’ll need to get the “BIOS Update Bootable CD” and somehow get it on a CD and find a CD-ROM drive. Alternatively on a Linux system the CD file system can be extracted and added to Grub to be directly bootable. Below was done on an Ubuntu 16.04 system:

$ sudo apt install genisoimage syslinux
$ wget -q
$ geteltorito 6duj48us.iso > 6duj48us.img
Booting catalog starts at sector: 20
Manufacturer of CD: NERO BURNING ROM
Image architecture: x86
Boot media type is: harddisk
El Torito image starts at sector 27 and has 75776 sector(s) of 512 Bytes
Image has been written to stdout ….
$ sudo cp /boot
$ sudo cp /usr/lib/syslinux/memdisk /boot
$ sudo nano /etc/grub.d/40_custom
<add lines below to the end of file, preserve the “exec tail…” line>
menuentry “BIOS Update” {
linux16 /memdisk
initrd16 /
$ sudo update-grub

Reboot, press <left shift> key while booting to access Grub, choose BIOS Update menu entry and follow the Lenovo update procedure. To start flashing it requires both a connected power supply and also a working, non-exhausted battery (!) mounted in the machine. This is tiresome for owners of worn out batteries…

Some notes about the flashing process can be found in the documentation of a patch set for the Lenovo BIOS.

Machine doing the programming

Install Flashrom

sudo apt install flashrom

ch341a support in flashrom



Download the stable LibreBoot firmware:

The brave will of course want to compile it themselves.

$ cd
$ wget
--2019-06-07 07:35:21--
Resolving (, 2001:630:341:12::184
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1632800 (1,6M) [application/x-xz]
Saving to: ‘libreboot_r20160907_grub_x200_8mb.tar.xz’

libreboot_r20160907_grub_x200_8mb.tar.xz 100%[================================================================================>]   1,56M  --.-KB/s    in 0,1s    

2019-06-07 07:35:21 (13,9 MB/s) - ‘libreboot_r20160907_grub_x200_8mb.tar.xz’ saved [1632800/1632800]
$ tar tf libreboot_r20160907_grub_x200_8mb.tar.xz 

Customise MAC address

As the MAC address of the ethnernet PHY is stored in the flash, yo have your X200 ethernet MAC address correspond to the sticker on the back of the machine, and also avoid a potential but improbable DHCP/ARP conflict, the MAC address from the label/ifconfig from the existing system must be embedded into the flash file that we are going to program into the flash chip.

For this a tool called ich9gen is needed, this is a part of the libreboot repository and we need to build it ourselves.

Build ich9gen

$ git clone
Cloning into 'libreboot'...
remote: Counting objects: 29080, done.
remote: Compressing objects: 100% (9855/9855), done.
remote: Total 29080 (delta 18748), reused 27899 (delta 18057)
Receiving objects: 100% (29080/29080), 63.90 MiB | 11.13 MiB/s, done.
Resolving deltas: 100% (18748/18748), done.
Checking connectivity... done.
$ cd libreboot/projects/ich9gen/sources
$ make
gcc -I. -Wall -Wextra -g -std=c99 -c src/ich9deblob.c -o obj/ich9deblob.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/common/descriptor_gbe.c -o obj/common/descriptor_gbe.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/descriptor/descriptor.c -o obj/descriptor/descriptor.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/gbe/gbe.c -o obj/gbe/gbe.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/common/x86compatibility.c -o obj/common/x86compatibility.o
gcc -I. -Wall -Wextra -g -std=c99 obj/ich9deblob.o obj/common/descriptor_gbe.o \
	obj/common/x86compatibility.o obj/descriptor/descriptor.o obj/gbe/gbe.o \
	 -o ich9deblob
gcc -I. -Wall -Wextra -g -std=c99 -c src/ich9gen.c -o obj/ich9gen.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/ich9gen/mkdescriptor.c -o obj/ich9gen/mkdescriptor.o
gcc -I. -Wall -Wextra -g -std=c99 -c src/ich9gen/mkgbe.c -o obj/ich9gen/mkgbe.o
gcc -I. -Wall -Wextra -g -std=c99 obj/ich9gen.o obj/ich9gen/mkdescriptor.o obj/ich9gen/mkgbe.o \
 obj/common/descriptor_gbe.o \
	obj/common/x86compatibility.o obj/descriptor/descriptor.o obj/gbe/gbe.o \
	 -o ich9gen
gcc -I. -Wall -Wextra -g -std=c99 -c src/demefactory.c -o obj/demefactory.o
gcc -I. -Wall -Wextra -g -std=c99 obj/demefactory.o obj/common/descriptor_gbe.o \
	obj/common/x86compatibility.o obj/descriptor/descriptor.o obj/gbe/gbe.o \
	 -o demefactory

Run ich9gen

Running ich9gen itself generates the flash descriptor (fd) header including possible configuration section where the MAC address is stored for the gigabit ethernet (gbe) PHY onboard the ICH9 chipset. When run six 12 KiB files for respectively 4, 8 and 16 MiB binary images and chipsets including (gbe) and excluding (nogbe) gigabit ethernet PHY are generated.

“aa:bb:cc:dd:ee:ff” in the commandline should be replaced with the actual 12 hex digits from the label on the machine or by running ifconfig on the machine using the existing Lenovo BIOS.

$ cd ~/libreboot_r20160907_grub_x200_8mb/
$ ~/libreboot/projects/ich9gen/sources/ich9gen --macaddress aa:bb:cc:dd:ee:ff
You selected to change the MAC address in the Gbe section. This has been done.

The modified gbe region has also been dumped as src files: mkgbe.c, mkgbe.h
To use these in ich9gen, place them in src/ich9gen/ and re-build ich9gen.

descriptor and gbe successfully written to the file: ich9fdgbe_4m.bin
Now do: dd if=ich9fdgbe_4m.bin of=libreboot.rom bs=1 count=12k conv=notrunc
(in other words, add the modified descriptor+gbe to your ROM image)

descriptor and gbe successfully written to the file: ich9fdgbe_8m.bin
Now do: dd if=ich9fdgbe_8m.bin of=libreboot.rom bs=1 count=12k conv=notrunc
(in other words, add the modified descriptor+gbe to your ROM image)

descriptor and gbe successfully written to the file: ich9fdgbe_16m.bin
Now do: dd if=ich9fdgbe_16m.bin of=libreboot.rom bs=1 count=12k conv=notrunc
(in other words, add the modified descriptor+gbe to your ROM image)

descriptor successfully written to the file: ich9fdnogbe_4m.bin
Now do: dd if=ich9fdnogbe_4m.bin of=yourrom.rom bs=1 count=4k conv=notrunc
(in other words, add the modified descriptor to your ROM image)

descriptor successfully written to the file: ich9fdnogbe_8m.bin
Now do: dd if=ich9fdnogbe_8m.bin of=yourrom.rom bs=1 count=4k conv=notrunc
(in other words, add the modified descriptor to your ROM image)

descriptor successfully written to the file: ich9fdnogbe_16m.bin
Now do: dd if=ich9fdnogbe_16m.bin of=yourrom.rom bs=1 count=4k conv=notrunc
(in other words, add the modified descriptor to your ROM image)

Apply Flash Descriptor to Binary

$ cd ~/libreboot_r20160907_grub_x200_8mb/
$ cp -v x200_8mb_usqwerty_vesafb{,_customised}.rom
'x200_8mb_usqwerty_vesafb.rom' -> 'x200_8mb_usqwerty_vesafb_customised.rom'
$ dd if=ich9fdgbe_8m.bin of=x200_8mb_usqwerty_vesafb_customised.rom bs=1 count=12k conv=notrunc
12288+0 records in
12288+0 records out
12288 bytes (12 kB, 12 KiB) copied, 0,0299453 s, 410 kB/s


Programmer Setup Validation / Lenovo BIOS backup

flashrom -p ch341a_spi -c MX25L6405D -r rom1.bin

flashrom -p ch341a_spi -c MX25L6405D -r rom2.bin

flashrom -p ch341a_spi -c MX25L6405D -r rom3.bin

flashrom -p ch341a_spi -c MX25L6405D -r rom4.bin

flashrom -p ch341a_spi -c MX25L6405D -r rom5.bin

cmp rom{1,2}.bin

cmp rom{1,3}.bin

cmp rom{1,4}.bin

cmp rom{1,5}.bin


$ sudo flashrom -p ch341a_spi -c MX25L6405D -w ~/libreboot_r20160907_grub_x200_8mb/x200_8mb_usqwerty_vesafb_customised.rom

Accounts of LibreBoot Flashing

Embedded Controller (EC) information

HOWTO: restore an iPad using only Free Software
Feb 14th, 2018 by miki

Thanks to the fine people at the libimobiledevice project, who bothers to reverse engineer Apple products, I recently succeeded in resurrecting a relative’s iPad stuck in a boot loop (something with jailbreaking, running Sydia, missing an iOS update and attempted Sydia removal) without any use of proprietary tools.

This is a brief recipe of the procedure done using Ubuntu 16.04.

As the required tool from libimobiledevice, idevicerestore, is not packaged in the Ubuntu libimobiledevice package we need to build this from scratch from the sources.

iPad during recovery

iPad in recovery mode during firmware download using libimobiledevice

  1. Install build dependencies
    sudo apt install libusbmuxd-dev libplist-dev libplist++contents under-dev libzip-dev
  2. fetch and build libimobiledevice main library
    git clone
    cd libimobiledevice/
  3. fetch and build libirecovery library
    git clone
    cd libirecovery
  4. fetch and build idevicerestore tool, using the homebuilt libraries
    git clone
    cd idevicerestore
    CFLAGS="-I$HOME/libirecovery/include -I$HOME/libimobiledevice/include" LDFLAGS="-L$HOME/libirecovery/src/.libs \
    -L$HOME/libimobiledevice/src/.libs" PKG_CONFIG_PATH=~/libirecovery:~/libimobiledevice/src ./
  5. put the iDevice in recovery mode (iPad = press power+home until screen with “iTunes+cable” symbol appear, see image above and check Apple support for details), make sure it has adequate charge or it will refuse (red battery flashing)
  6. perform the actual restore, asking for flashing of latest firmware (~2.5GiB automatically downloaded), this will probably get you in trouble if you desire to jailbreak the device. I noticed while writing this post that the below actually doesn’t run the tool using the libraries built above, but I’m leaving it as it was done because it “worked for me” (TM) and I can’t experiment further because I haven’t got access to any iDevices (and desire to keep it that way):
    sudo $HOME/idevicerestore/src/idevicerestore --latest
    NOTE: using cached version data
    Found device in Recovery mode
    Identified device as j71ap, iPad4,1
    Latest firmware is iPad_64bit_11.2_15C114_Restore.ipsw
    Verifying 'iPad_64bit_11.2_15C114_Restore.ipsw'...
    Checksum matches.
    Extracting BuildManifest from IPSW
    Product Version: 11.2
    Product Build: 15C114 Major: 15
    INFO: device serial number is DMPM4V3SFK15
    Device supports Image4: true
    Variant: Customer Upgrade Install (IPSW)
    This restore will update your device without losing data.
    Using cached filesystem from 'iPad_64bit_11.2_15C114_Restore/058-86080-124.dmg'
    Found ECID 6653578882512
    Getting ApNonce in recovery mode... 03 6b cc ac 57 8a b4 29 29 c1 a9 fe e4 97 54 3b a8 36 59 5a 
    Trying to fetch new SHSH blob
    Getting SepNonce in recovery mode... df 5c ad 67 48 bd 38 b4 6f 72 0a 5c b0 81 87 c3 95 37 4a da 
    WARNING: Unable to find BbChipID node
    WARNING: Unable to find BbSkeyId node
    Request URL set to
    Sending TSS request attempt 1... response successfully received
    Received SHSH blobs
    Extracting iBEC.ipad4.RELEASE.im4p...
    Personalizing IMG4 component iBEC...
    Sending iBEC (710360 bytes)...
    Recovery Mode Environment:
    iBoot build-version=iBoot-4076.30.43
    iBoot build-style=RELEASE
    Sending AppleLogo...
    Extracting applelogo@2x~ipad.im4p...
    Personalizing IMG4 component AppleLogo...
    Sending AppleLogo (22709 bytes)...
    Extracting 058-85997-124.dmg...
    Personalizing IMG4 component RestoreRamDisk...
    Sending RestoreRamDisk (59978774 bytes)...
    Extracting DeviceTree.j71ap.im4p...
    Personalizing IMG4 component RestoreDeviceTree...
    Sending RestoreDeviceTree (101420 bytes)...
    Extracting kernelcache.release.ipad4...
    Personalizing IMG4 component RestoreKernelCache...
    Sending RestoreKernelCache (13226783 bytes)...
    About to restore device... 
    Waiting for device...
    Device 3fb0f5cc97b83c61c85d4b8333796d9e536a4c83 is now connected in restore mode...
    Connecting now...
    Connected to, version 15
    Device 3fb0f5cc97b83c61c85d4b8333796d9e536a4c83 has successfully entered restore mode
    Hardware Information:
    BoardID: 16
    ChipID: 35168
    UniqueChipID: 6653578882512
    ProductionMode: true
    Starting FDR listener thread
    About to send NORData...
    Found firmware path Firmware/all_flash
    Getting firmware manifest from build identity
    Extracting LLB.ipad4.RELEASE.im4p...
    Personalizing IMG4 component LLB...
    Extracting applelogo@2x~ipad.im4p...
    Personalizing IMG4 component AppleLogo...
    Extracting batterycharging0@2x~ipad.im4p...
    Personalizing IMG4 component BatteryCharging0...
    Extracting batterycharging1@2x~ipad.im4p...
    Personalizing IMG4 component BatteryCharging1...
    Extracting batteryfull@2x~ipad.im4p...
    Personalizing IMG4 component BatteryFull...
    Extracting batterylow0@2x~ipad.im4p...
    Personalizing IMG4 component BatteryLow0...
    Extracting batterylow1@2x~ipad.im4p...
    Personalizing IMG4 component BatteryLow1...
    Extracting glyphplugin@2x~ipad-lightning.im4p...
    Personalizing IMG4 component BatteryPlugin...
    Extracting DeviceTree.j71ap.im4p...
    Personalizing IMG4 component DeviceTree...
    Extracting recoverymode@2x~ipad-lightning.im4p...
    Personalizing IMG4 component RecoveryMode...
    Extracting iBoot.ipad4.RELEASE.im4p...
    Personalizing IMG4 component iBoot...
    Extracting sep-firmware.j71.RELEASE.im4p...
    Personalizing IMG4 component RestoreSEP...
    Extracting sep-firmware.j71.RELEASE.im4p...
    Personalizing IMG4 component SEP...
    Sending NORData now...
    Done sending NORData
    About to send RootTicket...
    Sending RootTicket now...
    Done sending RootTicket
    Waiting for NAND (28)
    Checking filesystems (15)
    Checking filesystems (15)
    Unmounting filesystems (29)
    Unmounting filesystems (29)
    Creating filesystem (12)
    About to send filesystem...
    Connected to ASR
    Validating the filesystem
    Filesystem validated
    Sending filesystem now...
    [==================================================] 100.0%
    Done sending filesystem
    Verifying restore (14)
    [==================================================] 100.0%
    Checking filesystems (15)
    Checking filesystems (15)
    Mounting filesystems (16)
    Mounting filesystems (16)
    About to send KernelCache...
    Extracting kernelcache.release.ipad4...
    Personalizing IMG4 component KernelCache...
    Sending KernelCache now...
    Done sending KernelCache
    Installing kernelcache (27)
    About to send DeviceTree...
    Extracting DeviceTree.j71ap.im4p...
    Personalizing IMG4 component DeviceTree...
    Sending DeviceTree now...
    Done sending DeviceTree
    Certifying Savage (61)
    Flashing firmware (18)
    [==================================================] 100.0%
    Updating gas gauge software (47)
    Updating gas gauge software (47)
    Updating Stockholm (55)
    About to send FUD data...
    Sending FUD data now...
    Done sending FUD data
    About to send FUD data...
    Sending FUD data now...
    Done sending FUD data
    Fixing up /var (17)
    Modifying persistent boot-args (25)
    Unmounting filesystems (29)
    Unmounting filesystems (29)
    Got status message
    Status: Restore Finished
    Cleaning up...
  7. The iDevice should reset and boot into the new firmware.
iPad during firmware flashing using libimobiledevice

iPad during firmware flashing using libimobiledevice

If you want to interact with iDevices from within Ubuntu during ordinary use, you could also install some utils and plugins for that. Below will fx. add a context menu in nautilus with info about the iDevice and install the ideviceinstaller command line utility which can be used to administer installed applications on the device.

sudo apt install libimobiledevice-utils nautilus-ideviceinfo ideviceinstaller

[Danish] S&S: gemme data i Arduino ROM/Flash (PROGMEM / F())
Dec 21st, 2016 by miki

Mit svar på et spørgsmål i Facebook-gruppen Danske Arduino Entusiaster omkring Arduino ROM/Flash, PROGMEM og system-inklude-filer.


Hej er der en der ved hvor jeg kan hente dett lib. <avr/pgmspace.h> jeg skal bruge denne funktion PROGMEM
så jeg kan gemme et billede i Arduino uden SD kort
det kan være der er en der kender en anden måde at gøre det på.


pgmspace.h er en inklude-fil som er en del af c-biblioteket til AVR-arkitekturen (avr-libc). C-bibliotekets inklude-filer vil normalt ligge i kompilerens “system include”-sti (se GCC options -I og -isystem). Dermed kan den inkluderes blot med “#include <avr/pgmspace.h>”. Se evt. også Arduino-referencen på
Bemærk at PROGMEM ikke er en funktion, men en storage modifier (lager-modifikator) som fortæller kompileren at den kan placere en en given variabel i ikke-skrivbar lager (ROM/Flash). Der skal efterfølgende anvendes specielle funktioner til at læse data fra en sådan variabel (se referencen).
Arduino-frameworket har dog lavet en nem måde at placere konstant-strenge i Flash på (normalt lagres de i SRAM!), nemlig funktionen F() som kan anvendes direkte i f.eks. printf/write/print (Serial.print(F(“Waiting for connection”));)
Hvis du vil inspicere indholdet af pgmspace.h, kan du finde filen i Arduino IDE’ets installations-mappe under hardware/tools/avr/avr/include/avr/pgmspace.h. Det er ikke en man kan/skal redigere manuelt i, da den er tæt koblet med den binære kode i selve biblioteket.
Der findes også EEPROM-lager du sikkert vil kunne bruge til samme formål;

Se svaret på Facebook.

Den videre færd med F()

Da jeg ikke kunne finde en uddybende forklaring på F()-funktionen (som egentlig er en makro) i Arduino-dokumentationen (brugen nævnes meget kort i PROGMEM , Memory og Print), gravede jeg efterfølgende lidt rundt for at lære mere. I de sparsomme Arduino-eksempler er den anvendt udelukkende med konstante strenge, hvilket også viser sig at være et krav (eller i hvert fald noget der kan castes til const char *).

Makroen er defineret af Arduino-frameworket i filen hardware/arduino/avr/cores/arduino/WString.h (referencerne er ifht. min lokale installation af Arduino 1.6.9, pt. er nyeste 1.6.13) således:

#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

Altså parametren til F() bruges som parameter til PSTR() (progmem string, er mit bud på navn) som er en makro defineret i pgmspace.h fra avr-libc.

Dens funktion er at caste parametrens type til konstant streng-pointer med PROGMEM modifier;

#define PSTR(s) ((const PROGMEM char *)(s))

Skal vi se på hvad PROGMEM rent faktisk er, så finder vi endnu et sæt makroer der ender med at blive udviddet til kompiler-attributten  __progmem__, igen definieret i pgmspace.h (hardware/tools/avr/avr/include/avr/pgmspace.h):


#define __ATTR_PROGMEM__ __attribute__((__progmem__))

__progmem__ attributten er en instruks til kompileren (GCC) og linkeren om ved programmering/flashing af programmet at placere disse data i en sektion af hukommelsen der hedder “.progmem“. Se evt. mere om dette i GCC-kompilerens dokumentation. For hver AVR-chip kompileren understøtter er der eksakte definitioner af hvilke hukommelsesadresser .progmem ligger på for netop denne chip.

Dvs. når man i sin kode skriver F(“test”) får man i virkeligheden:

(reinterpret_cast<const __FlashStringHelper *>(((const __attribute__((__progmem__)) char *)(“test”)))

Altså en konstant streng der lagres i AVR-processorens progmem-sektion, og som returværdi får en pointer til en konstant instans af en klasse kaldet “__FlashStringHelper“. Denne klasse må være lavet sådan at den anvender de korrekte mekanismer til at læse fra progmem-området (måske mere om dette i en senere artikel). Arduinos funktion-bibliotek (Serial.print() mm.) er lavet således at de direkte kan tage en parameter af denne type som erstatning for en konstant-streng (og det er netop her Arduino-frameworket viser sin værdi ved at abstrahere sådanne kompleksiteter væk fra programmøren).

One-liner: Decompress file and diff against another file
Dec 8th, 2016 by miki

Below is a handy shell one-liner for comparing the decompressed contents of a compressed file against a plain file. The purpose here is to test whether the compressed file is actually derived from compressing the plain file. This particular example is from a real life situation where log rotation by cron.daily on a Ubuntu server had begun failing. The situation is thought to be the result of an interrupted logrotate execution leaving a compressed (but non-rotated) intermediate file in the file system that prevented further log rotation on subsequent executions.

The command constructs a pipe between two process, specified using the | symbol (vertical line), to send the decompressed contents from gunzip stdout to stdin of the compare tool. The example uses diff as compare tool which is suitable for textual contents. You could use f.x. cmp instead if the contents is binary. Both diff and cmp interprets the file name “-” as meaning that input should be read from stdin.

$ gunzip --stdout /var/log/syslog.1.gz | diff --report-identical-files - /var/log/syslog.1
Files - and /var/log/syslog.1 are identical

The above uses long options for clarity, in a real life situation you would probably be using short options instead. That means -c instead of –stdout and s instead of –report-identical-files.

$ gunzip -c /var/log/syslog.1.gz | diff -s - /var/log/syslog.1
Files - and /var/log/syslog.1 are identical


(Danish language) S&S: Brug GUI-programmer på tværs af brugere og maskiner (kommander X-vinduer med DISPLAY)
Jan 12th, 2016 by miki

Fra en tråd i gruppen “Linux for begyndere” (


Hvordan bliver man root bruger i linux mint ?? i grafisk brugerflade ??


For fremtidig reference:
Hvis man ønsker at køre en X-klient (et vilkårligt grafisk/GUI program) som root-brugeren, men vise dets vinduer på en X-server (typisk dit desktop environment/DE, som f.eks Gnome/KDE/Unity/lxde/xfce m.f.) der eksekveres af en ikke-privilegeret bruger kan man gøre som følger:

1) som X-server-brugeren kør kommandoen ‘xhost +’ i en grafisk konsol/terminal. Dette tillader at alle brugere og maskiner må vise vinduer på X-serveren (ja, X er en netværksprotokol). Tilladelsen bevares indtil X-serveren genstartes, eller den trækkes tilbage med ‘xhost -‘.

2) som root (su/sudo) eksekver det ønskede GUI-program, med specifikation af hvilken X-server og hvilket display dets vinduer ønskes vist på i DISPLAY environment-variablen (ja, det er muligt at køre flere separate X-servere/displays på samme maskine).
Simpleste form med visning på display 0 på den lokale maskine vil være (med xterm-konsollen som eksempel) ‘DISPLAY=:0 xterm’. Vil man vise vinduet på en anden maskines X-server skal IP-adressen blot angives før ‘:’, som f.eks.: ‘DISPLAY= xterm’ (det er stadig en xterm der afvikles på den lokale maskine, vinduet vises blot på en ekstern X-server (ja, det kan være farligt, pas på).

Bemærk at man med sudo skal passe på at sætte env-vars i den rigtige shell. F.eks. vil sudo direkte foran ovenstående ikke virke da sudo afskærmer env af sikkerhedsgrunde. I stedet vil man kunne benytte følgende trick: sudo bash -c ‘DISPLAY=:0 xterm’ (enkelt citationstegn til -c er vigtigt).

HTC One Stagefright disable instructions
Jul 29th, 2015 by miki

Until your device is sufficiently patched against the Stagefright vulnerabilty I recommend disabling automatic MMS retrieval on any Android phones from 2.2 and up (which is hopefully all in current use) to prevent unattended triggering.

Howtos for Google and Samsung devices are here.

Below are screenshots of how to do it on HTC One M7 using the stock (HTC Sense) messaging application called “SMS”. The procedure is likely to be very similar on most HTC devices using Sense.
The UI shown is in Danish locale, the English menus will be something like SMS->Settings->Multi Media Messages (MMS)->Automatic Retrieval.

wpid-wp-1438164382994.jpeg wpid-wp-1438164394794.jpeg wpid-wp-1438164402504.jpeg

Schneier discusses details here and this seems to be the commit in CyanogenMod for the underlying problem in the media library. Check aælso the issue’s review page

Howto: disable HDMI blanking in Ångström on BeagleBone Black (BBB)
Jul 9th, 2014 by miki

A very annoying feature of the Ångström image that is shipped with the BeagleBone Black, is that a display connected to the HDMI output of the board will by default be blanked when powering up, and is first woken when any pointer activity occur (touch/mouse).

This seems to originate from the fbdev that is used for displaying graphics, and it took me some time to figure out how to cirumvent it. The normal X commands for controlling blanking of “xset -dpms” or “xset s off” did nothing, and neither did the terminal options of “setterm powersave off” or “setterm powerdown 0”. I went all the way back to old ANSI escape sequences trying “echo -e ‘\033[9;X]'” without success.

Luckily I fell by at’s framebuffer tips, which listed the sys-fs node named /sys/class/graphics/fb0/blank that controls blanking of the low level framebuffer, thus executing (as root)

echo 0 > /sys/class/graphics/fb0/blank

disables blanking and wakes up the BBB HDMI output.

To do this at every boot (really login) you can use the Gnome Startup Applications Preferences (gnome-session-properties) to execute this at Gnome autologin, or add it to whatever startup script you see fit.

Beware that you might need to delay the execution when using the gnome-session-properties, I had to put in  a sleep, but that probably depends on what other stuff is starting up from it.



Raw HTTP session with telnet
Jul 21st, 2010 by miki

Once in a while it is useful to dismiss abstractions and layers that makes daily routines easier and take the raw approach. Like when debugging a software problem that doesn’t make sense, it is nice to see the underlying basic stuff is behaving nicely, to better be able to locate where the unexpected occurs.

In the IP world of the internet, the swiss army knife for debugging interprocess communications in a totally protocol agnostic way is called ‘telnet’. Telnet opens up a communication channel between your local computer and a daemon/server on a specific port on a specific IP address. Then it gets out of the way for you to talk directly to the daemon in clear text.

Knowledge of how to interact using a specific protocol can be very useful to check server availability and functionality. All common protocols in use on the internet (like DNS, HTTP, SMTP, POP3, IMAP, XMPP etc.) can be debugged like this, because all of them transfers data in clear text (or at least initiates other transfer types from a clear text session). Full specifications for the HTTP protocol can be found in IETF RFC2616. I keep forgetting this, and end up digging around for it when needed, therefore this blog post.

Interactively using Telnet

Below is a basic HTTP session to my web server using telnet on the command line.

Red text is local text input by me. Blue text is local text by telnet application. Green text is server response.

$ telnet 80
Connected to
Escape character is ‘^]’.
GET /index.php/2010/06 HTTP/1.1

HTTP/1.1 200 OK
Date: Wed, 21 Jul 2010 09:19:13 GMT
Server: Apache
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” ““>

<… remainder of HTML document dropped …>

We are asking the server at port 80 (default http port) for the document at path /index.php/2010/06 (“GET /index.php/2010/06”). Notice the two CRLF characters after the Host header field, this indicates to the server that the request header is done, and that it should begin parsing header and send its response. Also notice that even though you tell the telnet program on the commandline that you want to access, you have to tell it again to the server in th HTTP Host field. Thats because telnet is only concerned about the IP address of the server, it resolves to the IP through DNS and forgets about it. From the servers point of view, it needs to know which of its virtual hosts you want to talk to, cause one server application on one port on one ip can potentially host thousands of separate websites (virtual hosts).

One-liner using netcat (nc)

Below is the same session using nc (netcat) as a one-liner (wow, old PHP at Hostinger, better get that move to a self-administered box going).

$ echo -ne "GET /index.php/2010/06 HTTP/1.1\r\\r\n\r\n"|nc 80 | head -10
HTTP/1.1 200 OK
Date: Thu, 05 Jul 2018 16:30:07 GMT
Server: Apache
X-Powered-By: PHP/5.5.35
Link: <>; rel=""
Content-Length: 32356
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">


2018-07-05: nc command line added

»  Substance:WordPress   »  Style:Ahren Ahimsa
© 2019 Mikkel Kirkgard Nielsen, contents CC BY-SA 4.0