High Memory Area
Der Begriff High Memory Area (HMA, englisch teils auch verkürzt himem area[1]) bezeichnet bei einem x86-kompatiblen Prozessor im 16-Bit-Betriebsmodus Real Mode die ersten 65520 Byte oberhalb der 1-MiB-Grenze. Die HMA ist ab dem Intel 80286 verfügbar. Die deutsche Übersetzung hoher Speicherbereich ist inzwischen ungebräuchlich geworden. Ursprünglich eingeführt wurde dieser Hack unter der Bezeichnung HIMEM.[2]
Entstehungsgeschichte
BearbeitenDer ursprüngliche IBM PC nutzte einen 8088-Prozessor, der nur einen Mebibyte an Speicher direkt adressieren kann. Dieser Betriebsmodus wird ab dem 80286 als englisch Real Mode bezeichnet, der durch den neuen Betriebsmodus Protected Mode abgelöst werden sollte. Als Intel den 80286 entwarf, war noch nicht klar, welchen Erfolg die PC-Plattform mit dem darauf dominierenden Betriebssystem MS-DOS und PC DOS haben würde. Der Protected Mode ist daher nicht mit der bestehenden Software kompatibel, die weiterhin den Real Mode nutzte. In diesem laufen auch alle neueren x86-Prozessoren im 8086-komaptiblen Modus, in dem nur 1 MiB RAM direkt adressierbar bleibt.
Im 80286 können 16 MiB Arbeitsspeicher im Protected Mode genutzt werden, ab dem 80386 sind es 4 GiB (4096 MiB). Dieser Speicher liegt unter 8088/8086-kompatiblen reinen 16-Bit-Systemen wie anfangs PC-kompatiblem DOS allerdings brach, denn im Real Mode kann nicht darauf zugegriffen werden. Erst mit der Extended Memory Specification, kurz XMS, konnte dieser „Erweiterte Speicher“ auch unter 16-Bit-Betriebssystemen im Real Mode, allen voran DOS, genutzt werden.
Der HIMEM-Trick nutzt die Art und Weise aus, wie der Real Mode ab dem 80286 emuliert wird. Der Zugriff auf den RAM wird dabei in Segmente aufgeteilt, das sind 16 sich nicht überlappende Speicherseiten à 64 kB. Beim 8088/8086 endet der Speicher bei 1 MiB (1024 kB) und es kommt zu einem Überlauf, wenn Speicher über dieser Grenze angesprochen wird. Dieser Umstand wurde von vielen DOS-Programmen ausgenutzt, um sie schneller zu machen. Beim PC/AT musste sich IBM daher einen Mechanismus ausdenken, damit sich auch der 286er wie der originale IBM PC verhält, und hat die A20-Leitung eingeführt. Diese kann ein- und ausgeschaltet werden, sodass es auch möglich wird, keinen Überlauf hervorzurufen. Da die Segmentadressen im Regelfall 16 Bytes groß sind, werden diese beim HIMEM-Trick in den letzten 16 Bytes, die innerhalb des 1 MiB vom Real Mode zugreifbaren Speicherbereichs liegen, abgelegt. Der darin definierte Speicherabschnitt liegt damit 64 kB, minus den 16 Bytes, im Erweiterten Speicherbereich oberhalb der 1-MB-Grenze des Real Mode, und wird vom 80286 und nachfolgenden Prozessoren auch korrekt angesprochen, während der Prozessor dennoch im Real Mode verbleibt.
Dieser Programmiertrick findet sich unter anderem im Taskswitcher DESQview von Quarterdeck. Microsoft griff dieselbe Technik mit Windows 2.1 auf, das erstmals mit HIMEM.SYS ausgeliefert wurde.
Unter DOS kann die HMA dazu genutzt werden, Teile von sich selbst in diesen Bereich zu verschieben, um mehr Konventionellen Speicher für Programme zur Verfügung zu haben.[2]
HIMEM.SYS / HIDOS.SYS
BearbeitenDa zu MS-DOS auf dem IBM PC kompatibles DOS ursprünglich nur das erste Mebibyte des Hauptspeichers verwaltete, traten Probleme auf, sobald mehr als ein Programm oder Treiber die HMA nutzen wollten. Um dieses Problem zu lösen, wurden in den Speichermanager HIMEM.SYS
, der den Zugriff auf den Erweiterten Speicher regelt, Funktionen aufgenommen, die die Reservierung und Freigabe der HMA regelten.
Nutzung der HMA
BearbeitenAb DR DOS Version 5.0 (1990) und MS-DOS Version 5.0 (1991) war DOS in der Lage, seinen eigenen Systemkern in die HMA zu verlagern, wenn HIDOS.SYS bzw. HIMEM.SYS geladen war. Dies wurde durch die Option HIDOS=ON
bzw. DOS=HIGH
in der Konfigurationsdatei CONFIG.SYS erreicht. Damit wurde weniger „konventioneller Speicher“, also Speicher unterhalb der 640-KiB-Grenze, vom DOS-Kern belegt, was bei der chronischen Speicherknappheit unter DOS vorteilhaft war.
Bei DR DOS konnte nicht nur ein Teil des Systemkerns selbst in die HMA verschoben werden, sondern auch der residente Teil des Kommandozeileninterpreters COMMAND.COM (mit Option/MH), Teile der Pufferverwaltung (HIBUFFERS
) und ab DR DOS 6.0 eine ganze Reihe von speziell dafür ausgelegten Treibern wie KEYB, NLSFUNC und SHARE (jeweils mit Option/MH), wodurch weiterer konventioneller Speicher für Anwendungen und normale Treiber frei wurde.
Ab DR-DOS 7.02 erlaubte der Parameter SIZE=xxxx
der Konfigurationsdirektive SHELLHIGH=
eine Feineinstellung der Präallokation für den residenten Teil des Kommandozeilenprozessors, womit insbesondere bei der Verwendung von alternativen Kommandozeilenprozessoren wie 4DOS einer Fragmentierung der HMA vorgebeugt werden konnte (etwa mit SHELLHIGH SIZE=20 c:\4dos.com ...
in CONFIG.SYS), so dass insgesamt noch mehr zusammenhängender freier Speicherplatz für HMA-fähige Treiber nutzbar wurde.
Obwohl eine möglichst weitreichende Nutzung der HMA durch Treiber erstrebenswert war, machten insgesamt nur vergleichsweise wenige Treiber davon Gebrauch und wenn, dann in der Regel nur exklusiv, ohne dass dann gleichzeitig auch noch Teile des Betriebssystems oder andere Treiber in die HMA hochgeladen werden konnten.
Aufgrund der Tatsache, dass die Adressleitung A20 über das A20-Gate jederzeit von anderen laufenden Prozessen maskiert werden konnte, wodurch die HMA temporär nicht mehr erreichbar war, konnten nur Programmteile in die HMA verlagert werden, die über kurze Funktionen (sogenannte stubs) im konventionellen Speicher angesprungen wurden, in denen sichergestellt wurde, dass die A20-Leitung temporär wieder aktiviert wurde, bevor Code oder Daten in der HMA angesprochen wurden, also z. B. keine Interruptroutinen. Auch der Aufruf von externen Unterroutinen (mit nicht immer vollständig bekannten Seiteneffekten durch TSRs) aus der HMA heraus oder die Unterbrechung durch Interrupts war nicht unkritisch und erforderte besondere Vorsorgemaßnahmen in der Implementierung, da sich dabei sonst der Zustand des A20-Gates „scheinbar zufällig“ ändern konnte. Da von Seiten des Betriebssystems hierfür nur rudimentäre APIs zur Verfügung gestellt wurden und für eine sichere Implementierung etliche nicht sofort offensichtliche Race Conditions zu beachten waren, war eine Hochlademöglichkeit für manche Treiber je nach Aufgabe technisch prinzipiell nicht erreichbar, für andere zumindest aufwendig zu realisieren. Erst 386-Speichermanager wie EMM386, die unautorisierte Zugriffe auf das A20-Gate abfangen und softwaretechnisch entsprechend verarbeiten konnten, schafften hier betriebssystemseitig mehr Sicherheit in der Verwendung der HMA. Auch auf Rechnern, bei denen die A20-Leitung nicht maskierbar ist, war man vor solchen Problemen gefeit.
Ein weiterer Punkt war jedoch die Adressierung des Codes innerhalb der HMA selbst. Bei einer Relokation in die Upper Memory Area (UMA), wie sie für normale Treiber möglich war, wurde normalerweise die Segmentadresse an das Zielsegment angepasst, im Falle der HMA stand die Segmentadresse jedoch fest auf FFFEhex oder FFFFhex, so dass, wenn mehrere Software-Komponenten gleichzeitig in die HMA geladen werden sollten, sich stattdessen die Offset-Adressen ändern mussten, da zum Zeitpunkt der Kompilierung noch nicht feststand, an welcher Stelle innerhalb des HMA-Segments gerade noch Platz für den hochzuladenden Code sein würde. Diese Intra-Segment-Offset-Relokation erforderte jedoch spezielle Ladetechniken, bei denen alle Offsetbezüge innerhalb des Codes beim Laden entsprechend angepasst wurden, und die Anwendung verschiedener Programmiertricks, die nur wenige Programmierer beherrschten.[3]
Begriffsverwirrung
BearbeitenIn den deutschsprachigen MS-DOS-Versionen, die die HMA unterstützten, wurde diese als „oberer Speicherbereich“ bezeichnet. Als die Unterstützung für Upper Memory Blocks hinzukam, verwendete man dann für diese den Namen „hoher Speicherbereich“. Die Benennung war also im Deutschen gerade umgekehrt gehandhabt wie im Englischen, was zusammen mit der insgesamt schweren Verständlichkeit der MS-DOS-Speicherverwaltung zu viel Verwirrung bei den Anwendern führte. Erst unter Windows 95 wurden die deutschen Begriffe vertauscht, so dass sie nun den Englischen direkt entsprachen.
Einzelnachweise
Bearbeiten- ↑ Jim Seymour: Utilities: System Setup – The Inside Story; Setup and Configuration: Defining the Terms. In: PC Magazine. Band 10, Nr. 6. Ziff Davis, 26. März 1991, S. 311, Defining Terms; continued (englisch, eingeschränkte Vorschau in der Google-Buchsuche): Himem area High memory area or HMA.
- ↑ a b Barry Simon: Lab Notes – How to Get the Most From your System’s High DOS Memory. In: PC Magazine. Band 9, Nr. 10. Ziff Davis, 29. Mai 1990, S. 347 ff., HIMEM (englisch, eingeschränkte Vorschau in der Google-Buchsuche): “Microsoft did not invent HIMEM, as is usually supposed. It was used earlier by Quarterdeck’s DESQview, though it became widely available only with the release of Microsoft Windows 2.10. HIMEM uses a mere 64K of available extended memory—or, to be more exact, it uses the first 64K (minus 16 bytes) of extended memory, the memory directly above 1MB. The very important thing about HIMEM is that this 64K is accessible in real mode and can be used without a DOS extender. One possible use for HIMEM is to allow DOS to locate some of itself there, thus freeing up additional memory below 640K for user programs.
HIMEM actually depends on a bug in the same way the 286 emulates the 8086! In addition to breaking up memory into pages—16 nonoverlapping 64K chunks—the CPU thinks of memory as overlapping 64K chunks, called segments, which start every 16 bytes. Suppose the CPU tries to access one of those segments that starts very close to the top of the 1MB boundary. An 8086 will wrap around to very low memory, as shown in Figure 2.
On an 80286, however, the address actually accessed is just above the 1MB boundary. This provides real-mode addressability to the first 64K (minus 16 bytes) of extended memory. It’s 16 bytes less than 64K because the last segment begins 16 bytes shy of the 1MB boundary. To overcome the emulation bug, IBM built special capabilities into the bus that force memory to wrap around, like an 8086/88, in real mode. What the HIMEM driver does is to undo this safeguard selectively, so that a program specially written to use that area can put code there. That is what Microsoft Windows, DESQview, Ventura Publisher and Carousel do.” - ↑ Matthias Paul: Treiber dynamisch nachladen (Intra-Segment-Offset-Relokation zum Laden von TSRs in die HMA). In: de.comp.os.msdos. 2. Februar 2002, abgerufen am 2. Juli 2017.