Coreboot auf dem Thinkpad X200 & X201

Die Freiheit nehm' ich mir

Freie Software hat sich mittlerweile in vielen Bereichen etablieren können, da ist es besonders Schade, dass auf den meisten PCs ein abgeschottetes, undurchsichtiges BIOS installiert ist und teils aktiv den Interessen des Besitzers entgegenwirkt. Mit Coreboot gibt es dazu eine freie Alternative, die neben ideologischen auch ein paar handfeste Vorteile bringt.

Angefangen hat es ganz einfach: Mein Thinkpad lief irgendwie nicht stabil, immer mal wieder erlag es beim Versuch einzuschlafen einer Panik-Attacke. Nach einigen Experimenten stellte ich fest, dass es sehr wahrscheinlich ein Problem mit dem WLAN-Treiber war, organisierte mir darum eine andere WLAN-Karte und baute diese voller Vorfreude ein. Doch die Freude hielt nicht lange: Das BIOS verweigerte den Segen und war nicht gewillt, den Laptop überhaupt starten zu lassen, solange eine «fremde» Karte eingebaut war.

Da ich wenig Verständnis für unnötige künstliche Einschränkungen habe (es handelt sich ganz offensichtlich um einen Versuch von Lenovos Seite, die Leute dazu zu nötigen, nur offizielle Ersatzteile zu verwenden), machte ich mich auf die Suche nach Möglichkeiten. So fand ich einerseits modifizierte BIOS-Versionen, welche die Installation von inoffiziellen Erweiterungskarten zuliessen, wurde aber andererseits auch auf Coreboot aufmerksam, von dem ich schon das eine oder andere Mal gehört hatte. Die Idee eines völlig offenen BIOS überzeugte mich letztlich trotz zu erwartendem Mehraufwand und so hatte ich bald darauf meine erste Coreboot-Installation am laufen.

Mittlerweile habe ich das System mehrmals neu installiert und aktualisiert und auch einen zweiten Laptop befreit von seinem proprietären BIOS. Es gibt im Internet unzählige Anleitungen, wie man das macht, und ich werde mich etwas zurückhalten. Der Artikel soll mir grösstenteils als Nachschlagewerk dienen, wenn ich wieder mal nicht weiss, welchen Weg herum ich den Stecker am BIOS-Chip anschliessen muss, aber vielleicht findet ja auch sonst jemand das eine oder andere wissenswerte Häppchen.

An Material habe ich verwendet:

Das Raspberry Pi verwende ich, um per SPI mit dem BIOS-Chip zu kommunizieren. Man kann natürlich auch irgendein anderes Gerät verwenden, welches SPI-Anschlüsse hat; ein Versuch mit einem Bus Pirate dauerte aber sehr lange, das Raspberry ist deutlich schneller.

Initiale Installation

Die Erstinstallation besteht im Wesentlichen aus vier Schritten:

Verkabeln

Hier unterscheiden sich die Modelle ein wenig. Grundsätzlich sind die BIOS-Chips gleich anzusprechen, aber sie sind etwas anders verpackt. Die folgende Tabelle soll das erläutern:

Leitung X200 SOIC-16 X201 SOIC-8 Raspberry Pi
CS 7 1 24
CLK 16 6 23
MOSI 15 5 19
MISO 8 2 21
GND 10 4 25
VCC (+3V) 2 8 17

Ich habe mir die Testclips fest an ein Kabel montiert, so dass ich mich nicht jedes Mal darum kümmern muss, was ich wo einstecke. Die Farben in der Tabelle entsprechen den Farben der Adern dieses Kabels, dürften bei anderen Leuten mit anderen Kabeln also abweichen; für mich sind sie aber recht praktisch.

Thinkpad X200

Zur Position des BIOS-Chip und zur Frage, was man alles auseinandernehmen muss, um diesen zu erreichen, fand ich insbesondere den Artikel im Coreboot-Wiki und die Anleitung bei Libreboot sehr hilfreich. Die Leitungen zwischen dem SOIC-16-Chip (links) und dem Raspberry (rechts) sind wie folgt zu verbinden (siehe auch die Tabelle oben); der Pfeil soll illustrieren, wie der SOIC-Chip auf dem Mainboard ausgerichtet ist:

GND und VCC werden erst nach den anderen Leitungen angeschlossen; zuerst GND, und dann, ganz am Schluss, noch VCC; das wird zumindest überall so empfohlen.

Thinkpad X201

Beim X201 hat auch wieder das Coreboot-Wiki eine gute Anleitung, wie man den BIOS-Chip findet und zugänglich macht. Hier sind die Leitungen zwischen dem SOIC-8-Chip (links) und dem Raspberry (rechts) wie folgt zu verbinden:

Der Laptop muss Strom haben (also Akku oder Netzteil) damit die Kommunikation mit dem Chip funktioniert.

Altes BIOS auslesen

Wenn alles verkabelt ist, kann es losgehen mit auslesen. Das machen wir aus zwei Gründen: Einerseits weil wir einige Komponenten des alten BIOS weiterverarbeiten werden, andererseits aber auch um zu prüfen, ob unsere Verbindung zum BIOS-Chip wirklich stabil funktioniert. Dazu verwenden wir den folgenden Befehl:

# flashrom -p linux_spi:dev=/dev/spidev0.0 -c "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E" -r /tmp/orig.rom

Der Wert nach dem -c kann ein wenig variieren, flashrom würde sich entsprechend beschweren.

Wir machen das drei mal hintereinander und schauen, ob die MD5-Summen der Dateien übereinstimmen. Wenn das geklappt hat, und alle drei Dateien die gleiche Prüfsummen aufweisen, dann kann es weiter gehen. Ich speichere die ausgelesene Datei unter einem Namen, der auch gleich die originalen Versionsnummern enthält, damit ich später wieder weiss, woher ich meine Daten habe – beim X200 wäre das dann original_6det28ww_1.05-1.03.bin.

Als nächstes zerlegen wir das ausgelesene BIOS in seine Einzelteile. Coreboot hat dazu gleich ein Werkzeug dabei:

$ ifdtool -x original_6det28ww_1.05-1.03.bin

Damit werden dann die einzelne Regionen des Flash-Chips in eigene Dateien abgelegt; was konkret herauskommt, hängt vom Laptop-Model ab.

Thinkpad X200

Beim X200 findet ifdtool fünf Regionen:

File original_6det28ww_1.05-1.03.bin is 8388608 bytes Flash Region 0 (Flash Descriptor): 00000000 - 00000fff Flash Region 1 (BIOS): 00600000 - 007fffff Flash Region 2 (Intel ME): 00001000 - 005f5fff Flash Region 3 (GbE): 005f6000 - 005f7fff Flash Region 4 (Platform Data): 005f8000 - 005fffff

Diese landen in entsprechend in fünf eigenen Dateien:

$ ls -sh1 4.0K flashregion_0_flashdescriptor.bin 2.0M flashregion_1_bios.bin 6.0M flashregion_2_intel_me.bin 8.0K flashregion_3_gbe.bin 32K flashregion_4_platform_data.bin 8.0M original_6det28ww_1.05-1.03.bin

Von diesen brauchen wir für meine Coreboot-Konfiguration die erste als descriptor.bin, die dritte als me.bin und die vierte als gbe.bin, alle jeweils im Verzeichnis 3rdparty/blobs/mainboard/lenovo/x200/.

Thinkpad X201

Bei meinem X201 findet flashrom auch wieder fünf Regionen, wobei eine unbenutzt ist:

File original_6quj19us_1.40-1.15.bin is 8388608 bytes Flash Region 0 (Flash Descriptor): 00000000 - 00000fff Flash Region 1 (BIOS): 00500000 - 007fffff Flash Region 2 (Intel ME): 00003000 - 004fffff Flash Region 3 (GbE): 00001000 - 00002fff Flash Region 4 (Platform Data): 00fff000 - 00000fff (unused)

Diese landen wieder in entsprechend in eigenen Dateien:

$ ls -sh1 total 16M 4.0K flashregion_0_flashdescriptor.bin 3.0M flashregion_1_bios.bin 5.0M flashregion_2_intel_me.bin 8.0K flashregion_3_gbe.bin 8.0M original_6quj19us_1.40-1.15.bin

Meine Coreboot-Konfiguration braucht davon wieder die erste als descriptor.bin, die dritte als me.bin und die vierte als gbe.bin, alle jeweils im Verzeichnis 3rdparty/blobs/mainboard/lenovo/x201/.

Damit haben wir alle Elemente, um unser eigenes Coreboot-BIOS für den Laptop zu kompilieren.

Coreboot bauen

Eine Anleitung dazu, wie man Coreboot kompiliert, gibt es glücklicherweise bereits. Wenn alles soweit geklappt hat, und es Zeit wäre, die Konfiguration zu erstellen, bietet es sich an, dies auf Basis meiner Coreboot-Konfigurationsdatei zu tun – fürs X200 oder fürs X201. Diese sind noch nicht unbedingt perfekt optimiert, funktionieren bei mir aber ausgezeichnet. Wichtig dabei ist, dass wir Teile aus dem Original-BIOS (konkret descriptor.bin, me.bin und gbe.bin) wie oben erwähnt ins korrekte Verzeichnis kopieren, damit sie mit ins neue BIOS-Image hinein verarbeitet werden können.

Wenn das alles am richtigen Ort ist, mit make kompilieren; das sollte nach wenigen Minuten fertig sein.

Neues BIOS installieren

Wenn alles fertig kompiliert hat, kommt ein coreboot.rom als Resultat heraus. Diese Datei können wir nun auf den BIOS-Chip laden:

# flashrom -p linux_spi:dev=/dev/spidev0.0 -c "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E" -w /tmp/coreboot.rom flashrom v0.9.8-r1888 on Linux 3.18.11+ (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK Found Macronix flash chip "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E" (8192 kB, SPI) on linux_spi. Reading old flash chip contents... done. Erasing and writing flash chip... FAILED at 0x00000000! Expected=0xff, Found=0x00, failed byte count from 0x00000000-0x00000fff: 0x700 ERASE FAILED! Reading current flash chip contents... done. Looking for another erase function. FAILED at 0x00001000! Expected=0xff, Found=0x00, failed byte count from 0x00000000-0x00007fff: 0x4f66 ERASE FAILED! Reading current flash chip contents... done. Looking for another erase function. FAILED at 0x00000000! Expected=0xff, Found=0x00, failed byte count from 0x00000000-0x0000ffff: 0x2600 ERASE FAILED! Reading current flash chip contents... done. Looking for another erase function. FAILED at 0x00000000! Expected=0xff, Found=0x00, failed byte count from 0x00000000-0x007fffff: 0x22a000 ERASE FAILED! Reading current flash chip contents... done. Looking for another erase function. Erase/write done. Verifying flash... VERIFIED.

Wie man sieht, sind die ersten paar Versuche fehlgeschlagen. Das Problem hatte ich nur auf dem X200, auf dem X201 lief alles reibungslos. flashrom probiert in diesen Fällen munter weiter, es kam aber auf dem X200 auch vor, dass so lange alle Versuche fehlschlugen, bis flashrom resignierte und abbrach – in diesem Fall den Vorgang einfach nochmals starten, irgendwann sollte es klappen.

Nun haben wir das BIOS installiert und können den Laptop normal starten.

Coreboot ersetzen

Wenn wir ein installiertes Coreboot durch eine neuere Version oder durch ein BIOS mit anderer Konfiguration ersetzen möchten, dann ist das deutlich weniger aufwendig als die Erstinstallation. Normalerweise ist es nicht nötig, den Laptop auseinanderzunehmen und mit dem Raspberry zu verkabeln, sondern wir können das bequem aus dem laufenden System auf dem Laptop selber erledigen. Dazu verwenden wir den folgenden Befehl:

flashrom -p internal -c "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E/MX25L6473F" -w coreboot.rom

Danach das Gerät neu starten und hoffen, dass alles geklappt hat – oder halt im schlimmsten Fall doch wieder über das Raspberry die alte Version einspielen.