ThinkPad Fout I9990303: Een Catch-22

Het probleem: "It’s Not OK and RTFM!"

Wanneer ik spreek over "normaal opstarten", is het belangrijk op te merken dat de ThinkPad nog steeds kan opstarten vanaf een speciaal gemarkeerde floppydisk, zoals de onderhouds- of BIOS-update-schijven van IBM. Vanaf zo'n schijf kan hij booten naar DOS, toegang krijgen tot de interne harde schijf of PC Cards, of Windows 3.1 draaien. Met andere woorden: er lijkt niets fundamenteel mis te zijn met de laptop.

Echter, het onvermogen om de BIOS-setup uit te voeren, voorkomt dat de laptop correct geconfigureerd kan worden. Dit zorgt (vermoedelijk) er ook voor dat de PS2-utility faalt, enzovoort. Dus, wat betekent deze fout?

De IBM Hardware Maintenance Manual voor de ThinkPad 750 stelt dat fout I9990303 duidt op een defect moederbord. Het bevat ook deze curieuze opmerking: fouten I9990303 kunnen worden veroorzaakt door blootstelling aan sterke magnetische velden.

Voor nieuwere ThinkPads (bijv. de 760) wordt fout I9990303 gedocumenteerd als een "Bank–2 flash ROM checksum error". Het is mogelijk, zelfs waarschijnlijk, dat de fout betekent dat de firmware gedeeltelijk is gecorrumpeerd. Als de runtime BIOS in orde is, maar de ROM-setup en diagnostiek zijn gecorrumpeerd, verklaart dat waarom deze fout de toegang tot de BIOS-setup blokkeert.

De voor de hand liggende oplossing zou zijn om de BIOS opnieuw te flashen. Maar dat werkt niet. De BIOS-flash utility vereist een opgeladen batterij, die ik niet heb. De tool komt echter niet eens zo ver — hij faalt met een foutmelding die stelt dat het stroombeheer van het systeem is uitgeschakeld (The system power management is disabled). Dit is zeer waarschijnlijk hetzelfde onderliggende probleem als datgene wat de PS2-utility verhindert te werken. Met andere woorden: de BIOS-update komt niet eens aan toe aan het controleren van de batterijstatus; hij faalt al vóór dat punt.

En hier is de Catch-22: een niet-kritiek deel van de BIOS-flashopslag is gecorrumpeerd, iets wat het opnieuw flashen van de BIOS vrijwel zeker zou oplossen. Maar de IBM BIOS-update tool werkt niet vanwege de fout die wordt veroorzaakt door de gecorrumpeerde flash.

De zoektocht naar een uitweg

Is er een manier om dit te omzeilen? Op sommige systemen is er een manier om de firmware-update utility direct uit te voeren, zonder controles. Dat is bij de ThinkPad 750C niet het geval: hoewel de update-floppy gewoon een opstartbare DOS-schijf is met een aangepaste shell (een vervanger voor COMMAND.COM die direct de update utility draait), heeft de tool UPDTFLSH.EXE geen duidelijke instellingen om aan te passen.

De utility controleert alle voorwaarden en voert vervolgens de eigenlijke flash uit. Voor zover ik kan vaststellen, accepteert hij geen command-line argumenten, kijkt hij niet naar omgevingsvariabelen en is er geen zichtbare manier om zijn gedrag te beïnvloeden.

De logische oplossing is om de update utility aan te passen zodat de controles worden overgeslagen. Dit is natuurlijk riskant; de controles zijn er niet voor niets. Maar... heb je ooit de BIOS geflasht op een desktopmachine die geen voldoende opgeladen batterij had? Waarschijnlijk wel, en het werkte prima.

Oude systemen met BIOS in flashgeheugen hebben doorgaans geen veiligheidsmechanismen, geen "boot block BIOS", en als een BIOS-update mislukt (bijv. door stroomuitval), is het systeem onbruikbaar (bricked). Daarom eisen laptops vaak een opgeladen batterij, omdat dit een nuttige veiligheid is in het geval dat de stroom wegvalt (de meest waarschijnlijke oorzaak van een mislukte BIOS-update).

Omdat de laptop echter al defect is, besloot ik dat het risico om hem te proberen te repareren het waard was. Ik heb de UPDTFLSH.EXE utility gedisassembleerd en ontdekt dat deze veel slecht gedocumenteerde en volledig ongedocumenteerde zaken doet. Gelukkig gaven de foutmeldingen me goede aanwijzingen over wat de code deed.

De ThinkPad 750C gebruikt een 486SL-processor en lijkt SMM (System Management Mode) te gebruiken om stroombeheer te implementeren. Het gebruikt een interface die (zeer) gedeeltelijk gedocumenteerd is op de Ralf Brown’s Interrupt List. UPDTFLSH.EXE roept INT 15h/5380h aan met BH=7Eh. Dit zou de "SL control port" teruggeven in BX.

De utility stelt vervolgens CH, CL en BL in op 49h, 42h en 4Dh — de letters 'I', 'B', 'M' in ASCII. AX wordt (opnieuw) ingesteld op 5380h en BH op F0h, waarna de SL-controlepoort die uit de vorige aanroep kwam, wordt geschreven via OUT DX, AX. Dit is vermoedelijk een soort aanwezigheidscontrole.

Ik vermoed dat dit de interface is naar de power management BIOS. Het werkt veel zoals een software-interrupt, maar wordt getriggerd door een I/O-poort schrijfactie omdat de verwerking draait in SMM, in een aparte adresruimte.

Als de OUT-instructie de carry flag niet instelt, zijn de aanwezigheidscontroles geslaagd en gaat de flash utility verder met het verzenden van verdere stroombeheer-verzoeken. Deze controleren of de ThinkPad zich in een uitbreidingseenheid (expansion unit) bevindt (om redenen die onbekend zijn is dat verboden voor BIOS-flashing, wellicht omdat stroomuitval dan niet door een batterij kan worden opgevangen). Daarnaast zijn er routines die controleren of de laptop een batterij heeft geïnstalleerd en of deze voldoende is opgeladen.

Terzijde: de ThinkPad 750C is technisch gezien een PS/2-machine, net als eerdere IBM portables — hoewel hij geen Microchannel gebruikt zoals de ThinkPad 700/720 en oudere IBM laptops deden. De model-byte van de 750C is F8h (de submodel is 61h), een waarde die wordt gebruikt door alle 32-bit PS/2-systemen. Dit is niet dezelfde model-byte (FCh) die wordt gebruikt door PC/AT-compatibelen, welke overigens wel werd gebruikt door de ThinkPad 760 en latere modellen. ISA-gebaseerde PS/2-modellen zijn niet onbekend (bijv. Model 30), en er waren andere machines zoals de PS/2 E (model 9533) die 32-bit ISA-gebaseerde PS/2-systemen waren.

Terug naar de flash utility. Ik besloot de gehele routine op offset CC4h in het eerste codesegment effectief te patchen door altijd nul terug te geven in AX. Ik kopieerde de gehackedte utility naar de BIOS-update schijf, startte de laptop op en keek wat er gebeurde. De utility was EXEPACKed, dus hij moest eerst worden uitgepakt en opnieuw worden gepakt, maar dat is een saai proces.

De aangepaste BIOS-update utility vermeed inderdaad de stroombeheer-gerelateerde fout en liet me het flash-update proces starten. Ik liet het lopen, zonder zeker te weten wat er zou gebeuren.

Het resultaat

Nadat het flashen was voltooid, startte de laptop zichzelf opnieuw op en begroette me met het vertrouwde foutscherm. Een succes! De I9990303-fout is verdwenen, de BIOS-setup kan worden betreden en de laptop start weer normaal op. De BIOS kan nu alles configureren, waardoor fouten 161 en 163 (veroorzaakt door het verlies van CMOS-inhoud) zijn opgelost. De PS2-utility werkt ook weer.

Samenvatting

De I9990303-fout op ThinkPads uit het midden van de jaren '90 duidt vrijwel zeker op gecorrumpeerd flashgeheugen. EPROMs/flash gaan niet noodzakelijkerwijs eeuwig mee en "vergeten" soms hier en daar een bit. Dit kan meestal worden opgelost door de inhoud opnieuw te schrijven. Helaas voorkomt in het geval van de I9990303-fout het probleem dat opgelost zou worden door het flashen van de BIOS, juist dat de BIOS überhaupt geflasht kan worden, wat vrijwel zeker een onbedoeld neveneffect is.

Door gebruik te maken van een gehackedte UPDTFLSH.EXE utility kan de controle worden omzeild en de BIOS worden geflasht. Een succesvolle flash elimineert de I9990303-fout.