% 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}