10. April 2013

Neues Samsung-BIOS: P07RAC ...

... ändert leider gar nichts! Unter Linux werden keine efivars angezeigt, auch der NVRAM ist immer noch zu klein. Daher sind Probleme weiterhin absehbar und man sollte sich nicht in Sicherheit wiegen! Einen Changelog suchte ich leider vergeblich. Wenn jemand einen findet, bitte Bescheid geben.

22. Februar 2013

Samsung Phoenix BIOS UEFI Implementation Bug #2

Weitere Analysen ergeben, dass Samsungs UEFI Implementation nicht so ganz den Standards und Vorgaben entspricht. So entdeckte ich weitere Hinweise auf die Vermischung von UEFI Version 1 und UEFI Version 2. Des Weiteren scheint die Größe des nicht-flüchtigen Speichers (NVRAM) viel zu klein zu sein, als dass dieser den von Windows 8 geforderten 64KB entsprechen würde.

1. Windows 8 NVRAM-Anforderungen:
Zu lesen unter http://msdn.microsoft.com/en-us/library/windows/hardware/jj128256.aspx

Zitat:
"28. Mandatory. Reserved Memory for Windows Secure Boot UEFI Variables. A total of at least 64 KB of non-volatile NVRAM storage memory must be reserved for NV UEFI variables (authenticated and unauthenticated, BS and RT) used by UEFI Secure Boot and Windows, and the maximum supported variable size must be at least 32kB. There is no maximum NVRAM storage limit."

Übersetzung:
"28. Erforderlich. Reservierter Speicher für Windows Secure Boot UEFI Variablen. Insgesamt mindestens 64 KB nicht-flüchtiger Speicher (NVRAM) muss für NV UEFI Variablen reserviert sein (authentifizierte und unauthentifizierte, BootServices und RuntimeServices), welcher vom UEFI SecureBoot und Windows benutzt wird. Die maximal unterstützte Variablengröße muss mindestens 32 KB betragen. Ein oberes NVRAM-Limit existiert nicht."

Mithilfe einer angepassten UEFI-Shell v2 habe ich bei meinem NP300E5C-A05DE die geforderten Größen mithilfe der Funktion RuntimeServices->QueryVariableInfo() ausgelesen:

Die verfügbare Größe des NVRAM (obere Werte) unterscheiden sich gravierend von den Anforderungen. Weder die 64KB Gesamtgröße (erster Wert: 24556 Byte = ca. 24KB) noch die 32KB für die einzelne Variable (letzter Wert: 8152 Byte = ca. 8KB) sind verfügbar.

Inwiefern sich dies auf Windows 8 auswirkt und wann Windows 8 tatsächlich die Anforderungen ausreizt weiß ich nicht. Dennoch ist es mir schleierhaft, wieso auf Samsungs Webseite für dieses Notebook Windows 8 empfohlen wird.

[Update 24. Februar 2013:]

Inwiefern sich dieses Mini-NVRAM auswirken könnte kam mir noch ein Gedanke. Hierzu sollte man sich Matthew Garretts Blog und sein Windows-Experiment unter http://mjg59.dreamwidth.org/22855.html durchlesen. Er schreibt einiges an UEFI-Variablen in den NVRAM woraufhin sein Notebook geschrottet wird, obwohl er nicht ansatzweise die 64KB vollschreibt. Leider erwähnt Matthew Garrett keine ausgelesenen NVRAM-Größen seiner UEFI-Firmware. Ich könnte mir aber vorstellen, dass auch sein NVRAM die geforderten 64KB nicht einhält.

Er erwähnt in seinem Blog u.a. auch, wie Linux mit Crashdumps umgeht. Diese betragen ca. 10KB. Wie man sehen kann sind in meinem NVRAM gerade mal noch 11KB frei (zweiter Wert, obere Zeile). Ich kann mir gut vorstellen, dass der Firmware beim Neustart nach einem Crashdump, der die verfügbaren 11KB mehr oder weniger verbraucht, einfach zu wenig freier NVRAM verfügbar ist, da UEFI zum Starten auch ein bisschen braucht. Vielleicht liegt ja hier das Problem. Garrett schreibt seinen NVRAM voll (da er davon ausgeht, 64KB zu haben, was vermutlich nicht der Fall ist), der Rechner möchte neu starten, findet aber keinen verfügbaren NVRAM mehr und hängt sich auf.

Sicher ist, dass die Firmware bestimmte Variablen im NVRAM beim Starten aktualisiert. So z.B. "LastBootCurrent" oder auch "BootState". Bei einem Update einer Variablen wird aus Sicherheitsgründen diese Variable neu anlegt und dann die alte als gelöscht markiert. Daher wird auch für das Updaten zusätzlicher Speicher benötigt. Das könnte zumindest bei meinem Mini-NVRAM einen Brick erklären, da nach einem Linux-Crashdump der Platz hierfür eventuell nicht mehr reicht.

[Update Ende]

2. UEFI 1 vs. UEFI 2

Die entdeckte "Fehlfunktion" wirkt sich vermutlich nicht negativ bzw. zerstörend auf die Notebooks aus. Dennoch zeigt sie, wie scheinbar sorglos oder ahnungslos die UEFI-Firmware der Notebooks programmiert ist.

Nachdem ich nach dem Ende Januar entdeckten Bug eine gepatchte lauffähige UEFI-Shell v2 hatte, habe ich natürlich seitdem diese verwendet. Dabei viel mir auf, dass das "drivers"-Kommando nicht funktioniert und sich das Notebook aufhängt. Das Shell-Kommando "drivers" listet alle geladenen UEFI-Treiber auf. Die letzte Spalte der angezeigten Tabelle enthält dabei den sogenannten "DevicePath", also den Pfad zu der Treiberdatei (welche sich meistens in der Firmware selbst befindet). Um den DevicePath eines Treibers ausfindig zu machen, bedient sich UEFI (für wie so vieles) eines Protokolls, in diesem Fall dem "DEVICE_PATH_PROTOCOL". Ich möchte nicht das gesamte Protokoll erläutern. Nur so viel: der zu ermittelnde Pfad ist in DevicePath-Sektionen aufgeteilt. Diese DevicePath-Sektionen haben einen Typ. Bei Treibern ist dieser Typ beispielsweise MEDIA_DEVICE_PATH. Diese Sektionen sind verkettet um so den Gesamtpfad ermitteln zu können. Das Ende des Pfads wird von einer Sektion vom Typ END_DEVICE_PATH_TYPE (0x7F) gekennzeichnet.

Leider nicht bei Samsung. Hier wird der scheinbar in UEFI 2 nicht mehr verwendete Typ END_ENTIRE_DEVICE_PATH_TYPE (0xFF) benutzt. Dadurch hängt sich die UEFI-Shell v2 in einer Endlosschleife auf, da sie das Ende des DevicePaths nicht finden kann.

Hierüber kann man diskutieren. Sollte die Shell nicht auch den anderen Typ abfragen? Oder verwendet Samsung diesen Typ falsch? Die Shell basiert auf der Intel-UEFI, Samsungs UEFI kommt von Phoenix. Inkompatibel?

Nein. Auch auf der Phoenix-Seite taucht dieser scheinbar veraltete Typ nicht mehr auf: http://wiki.phoenix.com/wiki/index.php/EFI_DEVICE_PATH_PROTOCOL
(zu bemerken: die verlinkte Seite bei Phoenix ist von 2008 - also nicht neu!)

Samsung verwendet eine Firmware von Phoenix. Bei Phoenix taucht dieser Typ aber bereits auf einer Seite von 2008 nicht mehr auf. Ist die Firmware älter - bei einem fast neuen Laptop? Oder programmiert Samsung selbst alte Dinge rein? Klärt mich mal bitte jemand auf?

 

29. Januar 2013

Samsung Phoenix BIOS UEFI Implementation Bug 

Leider gibt es bei Samsung scheinbar keine Kontaktmöglichkeit, Fehler in Programmen oder anderen Hard- und Softwarebereichen zu melden. Nachdem ich nunmehr zwei Wochen versuche, mit Samsung in Kontakt zu treten, möchte ich hier meine Erkenntnisse zu diversen Foreneinträgen bezüglich der BIOS-Implementation der aktuellen Notenbook-Serien veröffentlichen.

Bei meinem Notebook handelt es sich um ein Samsung-Notebook der Serie 3, NP300E5C-A05DE. Aktuelle BIOS-Version ist P06RAC. Wie in einigen Internetforen zu lesen ist, gibt es UEFI-Probleme mit Linux, bis hin zu Totalausfällen der Geräte. Ich empfehle in einem solchen Fall die Garantie bzw. Gewährleistung in Anspruch zu nehmen. Man sollte dabei vorsichtig sein, Linux zu erwähnen. Die Hotline neigt dazu, den Garantie- bzw. Gewährleistungsanspruch bei einer "nicht von Samsung unterstützten Software" in Frage zu stellen.

Aktueller Fall:

Das Samsung-Phoenix-BIOS unterstützt offiziell die UEFI-Version 2.3.1, welche für einen reibungslosen UEFI-Boot von Windows 8 sorgen soll. Die Einstellmöglichkeiten im BIOS sind mager, man kann lediglich UEFI-Boot an- oder abschalten. Irgendeine Option "SecureBoot" gibt es leider nicht. Da Linux aber ohne jedes SecureBoot läuft und zudem meldet, dass SecureBoot abgeschaltet ist, vermute ich, dass dies auch so ist. Nun egal, wir sind ja nicht paranoid und verzichten gerne auf dieses Feature, zudem ich es sowieso abgeschaltet hätte, damit ich keine Probleme mit unsignierten Bootloadern bekomme.

Im Unterschied zu vielen Betroffenen hatte ich mein Linux Mint glücklicherweise erst einmal im normalen BIOS-Modus installiert. Viele der erwähnten Foreneinträge beklagen akute Lebensgefahr für die Notebooks, da diese während der Installation im UEFI-Modus gebrickt werden. Im Gegensatz dazu stellte ich mein Linux im nachhinein auf UEFI um (MBR-Partition auf GPT umstellen, EFI-Partition anlegen, Grub Efi-Version installieren - läuft!). Nach der Umstellung lief das Notebook weiterhin wunderbar - eine Woche später stellte ich jedoch fest, dass ich nicht mehr in das BIOS-Setup gelangen konnte. F2 bewirkte gar nichts.

Fehlerursache:

Zuerst muss man ein bisschen wissen, wie UEFI funktioniert. Die Starteinträge der Betriebssysteme werden nicht mehr von einem Bootloader auf der Festplatte verwaltet, sondern in einem speziellen Bereich in der UEFI-Firmware hinterlegt. Installiert man ein neues System, liest dieses während der Installation die vorhandenen Einträge aus und hängt sich selbst hinten dran. Vorraussetzung, damit das klappt, ist natürlich, dass das Auslesen der vorhandenen Einträge funktioniert. Die nötigen Funktionen zum Auslesen und Erstellen neuer Einträge stellt das UEFI durch seine sogenannten Runtime-Services zur Verfügung. Eine dieser wichtigen Funktionen nennt sich GetNextVariableName(). Mithilfe dieser Funktion scannt der Installer alle UEFI-Variablen durch und sucht nach vorhanden Booteinträgen. Eine genaue Beschreibung der Funktion findet man unter http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29
Im Samsung-BIOS verhält sich diese Funktion nicht den Vorgaben entsprechend. Der Fehler EFI_INVALID_PARAMETER ist laut Beschreibung dann zurück zu geben, wenn einer der übergebenen Variablenpointer den Wert NULL aufweist und somit auf einen falschen Speicherbereich zeigt. In der Samsung-UEFI-Firmware gibt die Funktion diesen Fehler aber auch zurück, wenn der übergebene Speicherblock nicht die exakte Größe von 128 Byte aufweist, also beispielsweise (wie im zuständigen Linux-Modul efivars) 1024 Byte. Leider rechnet das Linux-Modul nicht mit diesem Verhalten und geht fälschlicherweise davon aus, dass keine Variablen vorhanden sind - somit auch keine Booteinträge. Folglich trägt sich Linux als ersten Booteintrag im UEFI ein, wo vorher das Setup eingetragen war. Damit kommt man nicht mehr in das Setup, da hier nun Linux steht...

Dieser Fehler wirkt sich nicht nur auf Linux aus, sondern auch auf die UEFI-Shell Version 2.0. Auch hier wird ein deutlich größerer Puffer für den Variablennamen übergeben, wodurch die Shell schon beim Setzen der Umgebungsvariablen durcheinander kommt und gar nicht startet. Eine kleine Änderung im Quellcode und die Shell läuft einwandfrei: Samsung UEFI-Shell 2.0 64Bit (gepatchte 64-Bit Shell, auf FAT16/32-USB-Stick als /EFI/BOOT/BOOTx64.efi speichern, dann mit angeschaltetem UEFI-Boot vom Stick booten)

Der Fehler ist vermutlich auf eine Vermischung der UEFI-Versionen 1 und 2 zurück zu führen. In Version 1 waren die Namen der Variablen noch auf feste 128 Byte festgelegt. Ab Version 2 wurde das geändert, scheinbar aber nicht bei Samsung.

Lösung:

Eine offizielle Lösung für diesen Bug gibt es zur Zeit nicht. Letztlich muss Samsung hier tätig werden. Da aber sowohl der Quellcode von efivars als auch der UEFI-Shell verfügbar sind, kann man hier selbst Hand anlegen, indem man feste Größen von 128 Byte einträgt. Letztlich ist das aber keine gute Lösung auf Dauer. Zudem vermute ich, dass dies nicht der einzige Fehler im BIOS ist, da hierdurch noch nicht zwingend komplette Bricks zu erklären sind.

Ein gepatchtes efivars-Modul zeigt unter /sys/firmware/efi/vars plötzlich die UEFI-Variablen an:

vorher:

nachher:

(der Pfad enthält hier ein "efi2"-Verzeichnis, welches normalerweise "efi" heißt und nur von mir verändert wurde, damit ich beide Module parallel laden kann)