% Content-encoding: UTF-8 \documentclass[ngerman]{article} \usepackage[utf8]{inputenc} \usepackage{multicol,babel} \setcounter{secnumdepth}{0} \setcounter{tocdepth}{0} \begin{document} \renewcommand{\figurename}{Tabelle} \title{Bootmanager und FAT-Reparatur: Vierter Fort(h)schritt (patchbares BIOS im RAM)} \ifx\shorttitle\undefined\else \shorttitle{Bootmanager 4 — BIOS im RAM} \fi \author{Fred Behringer} \maketitle Im vorliegenden Artikel werden einige Forth--Worte entwickelt, mit deren Hilfe man eine \emph{Hilfsdiskette} so präperieren kann, dass sie ganz früh in den Bootprozess eingreift, so früh, dass es z.B. möglich wird, das ROM--BIOS des PCs ins RAM zu kopieren und es ab dann (bis zum \emph{Abschalten}) vom RAM aus wirken zu lassen. Das so erzeugte RAM--BIOS kann auch gepatcht werden. Die Forth--Worte aus den bisherigen Teilen 1 bis 3 dieser Artikelserie werden mit der Ausnahme des Puffers \texttt{sectbuf} hier nicht benötigt: \texttt{sectbuf} wird der Vollständigkeit halber hier noch einmal angegeben, und zwar genau so, wie er in Teil 1 bereits eingeführt wurde. \begin{multicols}{2} \section{Mein Ziel} Alle bisherigen Vorhaben meiner Serie waren systemnahe. \emph{Normalerweise} würde man dabei an ein Programmieren in Assembler denken (ich betrachte PC--Kompatible und gehe von mindestens dem 80486--Befehlssatz aus). In dem Assembler--Programm, auf das ich mich hier stark beziehe (siehe [WL]), steht \glqq Ein dreifach Hoch auf die Syntax des MASM!\grqq, und der betreffende Autor freut sich darüber, dass der genannte Assembler den speziellen Trick, den er sich vorstellt, tatsächlich mitmacht. \section{Sklave des Assemblers} In Forth hat der Anwender überraschend viele Möglichkeiten. In Forth braucht man sich nicht zum Sklaven eines unveränderbaren kommerziellen \emph{Assemblers} machen zu lassen. In Forth ist der Assembler Teil des Systems. Eine der Stärken von Forth--Systemen liegt darin, dass sie einen fließenden Übergang vom Assembler zum Assemblat (und von da zu Forth und zurück, auch mitten aus dem Betrieb heraus) gestatten. Solcher Programmier--Freiheiten wegen beschäftige ich mich (als Amateur) mit Forth. \section{In den Bootprozess eingreifen} Ich muss zugeben, dass ich eigentlich über das gesetzte Ziel hinausschieße: Ich wollte mir schnell eine Forth--Möglichkeit verschaffen, mit der ich zu einem sehr frühen Zeitpunkt in den Bootprozess eingreifen kann. Dazu hätte weitaus weniger Aufwand genügt als der, den ich im unten stehenden Listing treibe. Aber die (hier weniger betonte) eigentliche Idee, das BIOS \emph{on the fly} zu patchen, faszinierte mich seit eh und je. In der CHIP--Ausgabe 3/2009 wird auf dem Titelblatt vom \emph{Update--Wahnsinn} gesprochen, und davon, was \emph{gegen unsinnige Updates} hilft. Dem stimme ich zu. Ich darf den Gedanken aber gleich auf BIOS--Updates ausdehnen: Mir gefällt es nicht, wenn ich auf BIOS--Sonderwünsche die stereotype Antwort bekomme: \glqq Ja, da müssen Sie im Internet nach einem BIOS--Update suchen.\grqq Für wohlvertraute Computersysteme, die mir unschätzbare Dienste leisten, die aber von keiner Firma mehr herstellt werden? Ich möchte mir meine \emph{Updates} schnell selbst zurechtfeilen. \section{Frage an mich selbst} In meiner Rezension des Vijgeblaadjes 65 (VD--Heft 3+4/2007) habe ich folgende Frage gestellt: Gibt es eine Möglichkeit, dieses BIOS (es war von \emph{One Laptop per Child} die Rede) zeitweilig (so wie bei Zeichensätzen), einem Schatten--BIOS ähnlich, ins RAM meines Rechners zu schalten? Am liebsten über einen Bootmanager (bei mir XFDISK [PM]). Carsten Strotmann nahm meine Frage zum Anlass, einen bereits in seiner Schublade schlummernden sehr interessanten Bericht über seine Arbeiten (VD 2/2008 [CS]) zu veröffentlichen. Friederich Prinz [FP] hat gezeigt (VD 3/2008), wie aufmerksam die VD--Leser das Berichtete verfolgen. Er wies darauf hin, dass bei der gemeinsamen Beschäftigung mit Forth in den VD--Artikeln auch der Lern-- und Lehreffekt, die gegenseitige Anregung, eine nicht zu unterschätzende Rolle spielt. Meine Frage jedenfalls (siehe oben) war ernst gemeint. Sie war aber in erster Linie auch an mich selbst gerichtet: Schaffe ich es, auch als Nichtfachmann? Antwort: In Forth, ja. \section{Der NEAT--Chipsatz} Zu Zeiten des 80286/80386 mit dem NEAT--Chipsatz gab es die Möglichkeit, das ROM--BIOS ins darüberliegende RAM zu kopieren. Es war aber schwierig, den dann zumeist einsetzenden Schreibschutz auszuhebeln, wenn man die Gelegenheit nutzen wollte, ins BIOS ändernd einzugreifen. In der c't 8/1989 steht ein Artikel von Martin Ernst [ME] über gerade diese Dinge. Sein Programm \texttt{RAMADAP.ASM} findet sich auf der c't--PC--Sammeldiskette 20 [SD]. Zwar war sein Ziel nicht unbedingt die Verlegung oder/und Änderung des BIOSystems, sondern eigentlich \emph{nur} die Ausnutzung brachliegenden Hintergrund--RAMs zur Erweiterung des verfügbaren Arbeitsspeichers. Aber das geht ja von den Programmiertechniken her alles Hand in Hand: Auch bei Martin Ernst spielte die Neufassung des Bootsektors eine beträchtliche Rolle. Ich hatte zwar beim 80286 auch mit \texttt{RAMADAP} gearbeitet, hatte aber damals (als Amateur) nicht den geringsten Mut, am Programm selbst herumzubasteln. Heute (immer noch als Amateur), da ich in Forth einen starken Rückhalt habe, traue ich mir mehr zu. \section{BIOS ins RAM} Und wie ist es jetzt? Ich kann bei meinem AMD--K6--2 (mit dem zugeordneten Chipsatz) die Bereiche \texttt{C80000} bis \texttt{DFFFFF} \emph{cachen}, aber komme ich so schon ans BIOS und kann dort Veränderungen vornehmen? Beim Stöbern bin ich auf einen uralten Gegenstand meines Interesses gestoßen: Auf das (Assembler--)Programm \texttt{RAMBIOS.ASM} von Wolfgang Lorenz aus dem Jahre 1991 (Zeitschrift TOOL [WL]): Bei diesem wird vom DOS--RAM--Grundbereich ein gewisser Teil abgezwackt, in welchen dann das ROM--BIOS kopiert wird. Dann werden alle Interrupt--Vektoren, die ins BIOS (ab Segment \texttt{F000}) zeigen, auf den abgezwackten Bereich verbogen (Stack und andere Dinge werden angepasst) und schließlich wird ein Soft--Reset eingeleitet, der insofern keinen Schaden anrichtet, als er das BIOS da belässt, wo es ab dann liegt, nämlich im abgesonderten RAM--Bereich. Damit das funktioniert, wird ein Trick angewandt: Das BIOS--Kopieren und das Umbiegen der PC--Interrupt--Vektoren geschieht aus dem Bootsektor einer speziell dafür präparierten Diskette heraus. Das ist dann im Bootvorgang des PCs früh genug, um bei Aufruf des Reset--Interrupts \texttt{19h} das ins RAM kopierte BIOS und die verbogenen Interrupt--Vektoren nicht mehr anzutasten. Das \emph{Kaltstart--Flag} \texttt{0000:0472} wird dabei vorher auf \texttt{1234h} gesetzt. Warum das dann später, bei schon aufgerufenem DOS, mit einem erneut getätigten Reset nicht mehr geht, wird mich als Nächstes interessieren. Etwas eigenartig ist das schon, da ja andererseits der wiederholte Einsatz der Hilfsdiskette beim Zusammenspiel mit dem Bootmanager XFDISK (siehe unten im Abschnitt Kaskadierung) bestens funktioniert. \section{Programm von Wolfgang Lorenz} Im ASM--Quelltext des Programms steht: \\ Copyright: 1991 TOOL. Autor: Wolfgang Lorenz Gemeint ist mit großer Wahrscheinlichkeit die Zeitschrift TOOL aus dem Verlag Vogel \& Partner, die 1991 im vierten Jahr ihres Erscheinens stand. Und ich vermute, dass das Programm von der Begleitdiskette eines der Hefte dieser Zeitschrift stammt. Computerhefte, Programme und Disketten sind sehr kurzlebig. Ich konnte jedenfalls in meinen Archiven das gesuchte TOOL--Heft nicht mehr finden. Andererseits haben meine IOMEGA--ZIP--Disketten, allen Unkenrufen zum Trotz, ihre Inhalte noch nicht verloren. Und genau da konnte ich das besagte Programm von Wolfgang Lorenz wiederaufspüren. Das Programm liegt mir als Assembler--Quelltext und als Exe--Datei vor. Die Exe--Datei funktioniert prima und ich hätte damit arbeiten können. Was mich stört, ist nur der Umstand, dass ich gern alles in Forth--Assembler vor mir haben würde. Ich möchte ja mit den üblichen (interaktiv leicht zu handhabenden) Forth--Mitteln nach Belieben selbst am Programm herummodifizieren dürfen. \section{Programm als Hex--Listing} Ursprünglich wollte ich also das Programm von Wolfgang Lorenz 1:1 nach Forth umsetzen. Dann wurde mir aber bewusst, dass ich in Forth ja \emph{gemischt} arbeiten kann, hier ein bisschen Forth--Assembler, da ein bisschen High--Level--Forth. Das wäre dann aber im Programm von Wolfgang Lorenz auf Abkürzungen einerseits und Anpassungen andererseits hinausgelaufen. Also habe ich mich dann doch dazu entschlossen, den (an sich ja nicht sehr großen) Teil des Programms von Wolfgang Lorenz, der in den Bootsektor der anzufertigenden Hilfsdiskette geschrieben werden soll, in uralter Heimcomputer--Manier als Hex--Listing zu fassen. Abgetippt braucht ja heutzutage sowieso nichts mehr zu werden: Die Zeitschrift \emph{Vierte Dimension} (VD) steht im Internet als PDF--Datei zur Verfügung und von dort lässt sich jeder Textteil einer PDF, also auch die besagte Hex--Tabelle, (mit dem Textwerkzeug des Acrobat--Readers) leicht extrahieren und über die Windows--Zwischenablage mit Hilfe von NotePad in eine Textdatei schreiben. Andererseits war man sich ja auch zu Zeiten der damals überall zu findenden Turbo--Pascal--Programmierung nicht zu fein, Inline--Hex--Code einzuschieben (vergleiche die semiprofessionellen Listings in den diversen CHIP--Special--Turbo--Pascal--Sonderheften so um 1990/91 herum); Inline--Hex--Code, den man beim Lesen kaum auf Anhieb verstehen kann und den man beim Programmieren sicher nicht immer auswendig weiß. Abgesehen vom \emph{vertrauensvollen} Übernehmen des Programms von Wolfgang Lorenz in Hexform blieb für Forth, zumindest bei der Anfertigung der Hilfsdiskette genügend zu tun übrig. \section{Interpretativ} So, wie ich das Programm zur Erzeugung der Hilfsdiskette eingerichtet habe (siehe Listing), nämlich interpretativ schon beim Einlesen (per \texttt{INCLUDE} oder \texttt{FLOAD}), werden auf jeden Fall etwas mehr als \texttt{512d} Datenstack--Plätze (zur Zwischenspeicherung der Hex--Werte zeitweilig) benötigt. Das lässt sich natürlich sofort auch anders einrichten. \section{Welches Forth} Ich gehe von Turbo--Forth in der 16--Bit--Version [TF] aus und überprüfe alles auch noch mit ZF [ZF]. Beide Systeme fußen auf F83 und im \emph{Grünen Buch} von Ronald Zech [RZ] ist auch der Assemblerteil von F83 gut beschrieben. Mit der besagten Vorgehensweise habe ich gleichzeitig einen Grund gefunden, die in den bisherigen Teilen 1 bis 3 meiner Serie entwickelten Forth--Worte um einige diskettensektorbezogene Worte zu ergänzen. \section{Kaskadierung der BIOS--Vorverlegung} Interessant war für mich eine Zufallsentdeckung beim Experimentieren. Ich arbeite, wie schon gesagt, mit dem Bootmanager XFDISK von Florian Painke und Ulrich Müller [PM]. XFDISK liegt im normalerweise nicht benutzten Bereich der Festplatte zwischen dem MBR und dem Bootsektor der ersten primären Partition und bearbeitet nach dem Booten von der Festplatte die Partitionstabelle im MBR. So weit, so gut. Die hier anzufertigende Hilfsdiskette beeinflusst diesen Vorgang nicht: Ich kann im Bootmanager--Menü auch nach der Vorverlegung des BIOS--Bereichs über die Hilfsdiskette noch andere Betriebssysteme als DOS aufrufen. Es besteht aber am Anfang des Bootvorgangs im XFDISK grundsätzlich auch die Möglichkeit, durch Drücken von {\sf F1} oder {\sf F2} von einer im Laufwerk a: liegenden Diskette zu booten --- vorausgesetzt, dort liegt überhaupt eine bootbare Diskette. Lasse ich nun nach dem ersten Wirken der Hilfsdiskette zur Vorverlegung des BIOS ins RAM die Hilfsdiskette im Schacht \texttt{a:} und drücke {\sf F1} (oder {\sf F2}), dann werden weitere 64 KB vom System zur freien Verfügung gestellt und das BIOS wird ein zweites Mal vorverlegt --- und das könnte dann \emph{beliebig} oft wiederholt werden. Schon allein diese Erscheinung würde mich reizen, demnächst doch mal das Programm von Wolfgang Lorenz genauer unter die Lupe zu nehmen, es in Forth--Assembler zu fassen und dann die Möglichkeit eines schnellen Veränderns der entsprechenden Parameter (vielleicht sogar \emph{on the fly}) auszuschöpfen --- ohne mich mit der Frage, ob \texttt{TASM} oder \texttt{MASM} oder sonstwas für ein \texttt{ASM}, und wer was macht oder nicht macht, herumplagen zu müssen. In Forth bin ich auch in Bezug auf das Assemblieren mein eigener Herr. \section{Nachteil} Man wird immer wieder darauf aufmerksam gemacht, dass man sich ein Soft--Reset (ein Neubooten) des PCs auch mitten aus dem Programm heraus durch einen intersegmentellen Sprung an eine bestimmte Stelle im BIOS erzwingen kann. Da der Computer sowieso zurückgesetzt werden soll, ist es dabei natürlich egal, ob Sprung (über \texttt{jmp-far}) oder Unterprogramm--Aufruf (über \texttt{call-far}). In Forth (auf hex geschaltet) ließe sich das mit folgendem Wort bewirken: \begin{verbatim} code reset far 0 0ffff #) call next end-code \end{verbatim} In meinem (ROM--)BIOS steht an der angesprungenen Stelle \texttt{EA5BE000F0}. In Turbo--Forth überzeugt man sich davon per \texttt{0ffff 0 80 ldump}. \texttt{EA} steht für \emph{direkten Weit--Sprung} und die darauffolgenden vier Bytes stehen (Achtung: Little--Endian) für \texttt{F000:E05B}. Wendet man nun das BIOS--Verlagerungs--Programm von Wolfgang Lorenz an, so steht an der entsprechenden Stelle immer noch \texttt{F000:E05B}. Mit anderen Worten, kommen im ROM--BIOS absolute Bezüge auf sich selbst, also mit Segment \texttt{F000}, vor, dann werden diese im RAM--verlagerten BIOS nicht wieder auf sich selbst, also bei meinem System auf den Anfang des RAM--Segments \texttt{8FC0}, bezogen (das könnte man ja bei Verfeinerung des Verlagerungs--Programms von Wolfgang Lorenz auch noch ergänzen), sondern bleiben auf das ROM--BIOS--Segment \texttt{F000} eingestellt. \section{Vorteil} Im eben gebrachten Beispiel ist der genannte Umstand kein direkter Nachteil, da ja das ursprüngliche BIOS (das ROM--BIOS) sein Leben lang da bleibt, wo es ist. Ein Sprung (oder Call) nach \texttt{F000:E05B} löst also auch nach BIOS--Verlagerung immer noch einen Neustart des PCs aus. Andererseits kann ich aber gerade dieses Beispiel zum schnellen Aufzeigen der eventuellen Vorteile der BIOS--Verlagerung verwenden: Ein \emph{ganz schnell} eingegebenes \begin{verbatim} cb 0ffff 0 lc! \end{verbatim} verwandelt das \texttt{EA} (\texttt{jmp-far}) in ein \texttt{CB} (\texttt{retf}). Die Wirkung des eben eingeführten Forth--Wortes reset ist nach einer solchen Eingabe dann also aufgehoben --- solange aus dem \texttt{CB} nicht wieder ein \texttt{EA} gemacht wird. Und das alles bei Bedarf mitten aus den (eigenen) Programmen heraus. Ob das nun wirklich ein stichhaltiges Argument--pro ist, bleibe dahingestellt (das eben eingeführte Forth--Wort reset könnte man ja mit viel einfacheren Mitteln, auch nachträglich noch, unwirksam machen). Mit diesem Beispiel ist aber jedenfalls gezeigt, dass das umkopierte BIOS (das RAM--BIOS) tatsächlich gepatcht, verändert oder auch neugestaltet werden kann --- ohne auf ein BIOS--Update vom Hersteller warten zu müssen. Ein solches Update würde ich ja für ein BIOS aus dem Jahre 1999 sowieso nicht mehr bekommen. Eine neue Hauptplatine kaufen? Hm --- ich hätte da ja ein paar solcher \emph{neueren} Systeme. Aber wie versehe ich die mit EISA--Steckplätzen für meine Transputer--Karten. \section{Für größere BIOS--Patch--Vorhaben} stünde mir die oben erwähnte Möglichkeit zur Verfügung, die (schon vorliegende) Hilfsdiskette zweimal wirken zu lassen, um mir einen RAM--Freiraum von weiteren 64 KB (oder sogar mehr) zu verschaffen, der von der RAM--Verwaltung (bis zum \emph{Abschalten}, will sagen, Neubooten) nicht mehr angetastet wird. \section{Ich fasse zusammen} (1) Bei Disketten scheint das Lesen und Schreiben von Sektoren nicht ohne Fehlerabfrage und eventuell mehrfachen Versuchen möglich zu sein (siehe Kommentare bei \texttt{getdiskbootsect} und \texttt{putdiskbootsect} im Listing). (2) Das PC--BIOS kann über eine Hilfsdiskette in einen abgetrennten RAM--Bereich gelegt und von dort aus wirksam werden. (3) Das aus dem RAM heraus wirkende BIOS kann auch gepatcht werden. (4) Die besagte Hilfsdiskette wird mit Forth--Mitteln hergestellt und steht danach \emph{für immer} zur Verfügung. (5) Der Computer wird per Hilfsdiskette gebootet, der Bootvorgang leitet dann auf die Festplatte über. (6) In Zusammenarbeit mit dem Bootmanager XFDISK kann der BIOS--Vorverlegungsvorgang auch wiederholt werden (Hilfsdiskette im Schacht lassen). Damit könnte dann mehr als nur ein einziges Stück RAM bis zum Abschalten freigemacht werden. Das überschüssige RAM könnte für größere BIOS--Patch--Vorhaben verwendet werden. (7) Ein einfaches Rücksetzen des Computers über den Reset--Knopf, über einen intersegmentellen Sprung nach \texttt{ffff:0000} oder über den Interrupt \texttt{19h} (Affengriff) macht die BIOS--Verlegung ins RAM wieder rückgängig. Nimmt man die Hilfsdiskette dabei vorher aus dem Laufwerksschacht, dann sind die Verhältnisse wieder so, wie sie vom PC--(BIOS--)Hersteller eigentlich vorgesehen waren. \end{multicols} \section{Literatur und Links} \begin{tabular}{p{3ex}l} {}[CS]&Strotmann, Carsten: Forth ohne/als Betriebssystem. VD--Heft 2/2008.\\ {}[FP]&Prinz, Friederich: Leserbrief im VD--Heft 3/2008.\\ {}[ME]&Ernst, Martin: Treiber verschiebt Treiber. c't 8/1989.\\ {}[PM]&Painke, Florian, und Ulrich Müller: XFDISK.EXE. Public Domain.\\ {}[RZ]&Zech, Ronald: Forth--83. Franzis--Verlag München (1987).\\ {}[SD]&c't--PC--Sammeldiskette 20\\ {}[TF]&Petremann, Marc: Turbo--Forth, Guide de référence. Editions REM CORP 1990.\\ %\phantom{{}[TF] } &Das System liegt u.a. auf dem amerikanischen FTP--Server taygeta.com.\\ {}[WL]&Lorenz, Wolfgang: RAM--BIOS. Höchtwahrscheinlich Zeitschrift TOOL, 1991.\\ {}[ZF]&Zimmer, Tom: ZF--System (16 Bit). Public Domain.\\ \end{tabular} \section{Listing} \listinginput[1]{1}{2009-02/BOOTMA-4.FTH} \end{document}