<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% 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 \&amp; 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]&amp;Strotmann, Carsten: Forth ohne/als Betriebssystem. VD--Heft 2/2008.\\
{}[FP]&amp;Prinz, Friederich: Leserbrief im VD--Heft 3/2008.\\
{}[ME]&amp;Ernst, Martin: Treiber verschiebt Treiber. c't 8/1989.\\
{}[PM]&amp;Painke, Florian, und Ulrich MÃ¼ller: XFDISK.EXE. Public Domain.\\
{}[RZ]&amp;Zech, Ronald: Forth--83. Franzis--Verlag MÃ¼nchen (1987).\\
{}[SD]&amp;c't--PC--Sammeldiskette 20\\
{}[TF]&amp;Petremann, Marc: Turbo--Forth, Guide de rÃ©fÃ©rence. Editions REM CORP 1990.\\
%\phantom{{}[TF] }
&amp;Das System liegt u.a. auf dem amerikanischen FTP--Server taygeta.com.\\
{}[WL]&amp;Lorenz, Wolfgang: RAM--BIOS. HÃ¶chtwahrscheinlich Zeitschrift TOOL, 1991.\\
{}[ZF]&amp;Zimmer, Tom: ZF--System (16 Bit). Public Domain.\\
\end{tabular}
\section{Listing}
\listinginput[1]{1}{2009-02/BOOTMA-4.FTH}

\end{document}</pre></body></html>