UMA unter DOS

Konfiguration, Anwendungen, Treiber und TSRs unter DOS
Antworten
Jackintosh
MemMaker-Benutzer
Beiträge: 57
Registriert: Di 25. Okt 2022, 15:46

UMA unter DOS

Beitrag von Jackintosh »

Ich überlege mir eine Kombo ISA Karte zusammen zu bauen, die u.a. ein SRAM beinhaltet, das bei 640KB PCs die UMA zur Verfügung stellt, also RAM zwichen 640 und 1024KB Adressraum einblendet. Da ja einige Segmente durch Grafikkartenspeicher oder ROM belegt sind, kann ich nicht stur 384KByte ab 640KByte einblenden. Daher meine Idee das SW getrieben zu machen.
Wenn mein Konfig-PRG als erstes aus der config.sys aufgerufen wird, soll es:
  • prüfen, ob die HW vorhanden ist
  • falls ja: die HW mit den vom User gewählten Parametern (An welchen Segmenten soll RAM eingeblendet werden?) konfigurieren
Ab diesem Zeitpunkt wäre das RAM in der UMA für die CPU sichtbar, d.h. sie könnte lesend/schreiben darauf zugreifen. Ist dieser Zeitpunkt früh genug, um die UMA für DOS nutzbar zu machen?
Welche Granularität der eingeblendeten RAM-Blöcke wäre sinnvoll? 64KB, 32KB? Je feiner, desto besser, aber das nimmt mir Platz im CPLD weg, den ich für anderes brauche.
mkarcher
LAN Manager
Beiträge: 204
Registriert: Fr 5. Jun 2020, 19:38

Re: UMA unter DOS

Beitrag von mkarcher »

Um UMA/UMB für DOS nutzbar zu machen, brauchst Du einen HIMEM-artigen Treiber, der die UMB-Funktionen der XMS-API zur Verfügung stellt. Das schöne an DOS ist, dass der DOS-Kernel (wenn Du DOS=UMB oder DOS=HIGH,UMB) angegeben hast, einmal alle UMBs reserviert, und dann den Treiber nie mehr aufruft. Er kann sich also danach wieder entladen. Treiber wie USE!UMBS, UMBPCI oder UMB_DRVR tun genau das - das einzige, was die Treiber nicht können, ist die Programmierung Deiner Karte auf die passenden Adressbereiche.

16KB Granularität wäre nicht schlecht. Shared Memory oder Boot-ROMs auf Netzwerkkarten, oder auch das SCSI-ROM auf einem Adaptec 1542 sind häufig 16KB groß. Wenn Du nur für den einfachen Fall VGA-Karte + Mainboard-BIOS arbeiten willst, kannst Du auch einfach den D-Bereich immer einblenden, und den E-Beriech, sowie den oberen C-Bereich jeweils am Stück schaltbar machen. Damit deckst Du die häufigsten Szenarien ab. (32 oder 64KB VGA-BIOS; 64 oder 128KB Mainboard-BIOS)
Jackintosh
MemMaker-Benutzer
Beiträge: 57
Registriert: Di 25. Okt 2022, 15:46

Re: UMA unter DOS

Beitrag von Jackintosh »

mkarcher hat geschrieben: Mi 26. Okt 2022, 21:22 Um UMA/UMB für DOS nutzbar zu machen, brauchst Du einen HIMEM-artigen Treiber, der die UMB-Funktionen der XMS-API zur Verfügung stellt. Das schöne an DOS ist, dass der DOS-Kernel (wenn Du DOS=UMB oder DOS=HIGH,UMB) angegeben hast, einmal alle UMBs reserviert, und dann den Treiber nie mehr aufruft. Er kann sich also danach wieder entladen. Treiber wie USE!UMBS, UMBPCI oder UMB_DRVR tun genau das - das einzige, was die Treiber nicht können, ist die Programmierung Deiner Karte auf die passenden Adressbereiche.
Danke erstmal!
Dann gehe ich jetzt mal davon aus, dass Du meine Frage von oben hiermit mit "Ja" beantwortest?

Einen "missing link" gibt es aber noch in meinem Verständnis: angenommen das Segment $C000 (64KB) ist komplett verfügbar, das SRAM wird auf "sichtbar" für die CPU geschaltet, dann müssen diese 64KB doch irgendwie in die memory-free list von DOS über ein API eingetragen werden, damit dieser Speicher auch für DOS nutzbar wird. Wie geschieht dies?

Führt mich zur nächsten Frage:
Unterliegen executables, die aus der config.sys aufgerufen werden bestimmten Einschränkungen? Darf es z.B. ein COM Programm sein? 64KB reichen vollkommen zur Konfigurierung.
mkarcher
LAN Manager
Beiträge: 204
Registriert: Fr 5. Jun 2020, 19:38

Re: UMA unter DOS

Beitrag von mkarcher »

Jackintosh hat geschrieben: Mi 26. Okt 2022, 21:59 Einen "missing link" gibt es aber noch in meinem Verständnis: angenommen das Segment $C000 (64KB) ist komplett verfügbar, das SRAM wird auf "sichtbar" für die CPU geschaltet, dann müssen diese 64KB doch irgendwie in die memory-free list von DOS über ein API eingetragen werden, damit dieser Speicher auch für DOS nutzbar wird. Wie geschieht dies?
Die Schnittstelle, die DOS nutzt, um die UMB-Liste zu führen ist folgende: Sofern DOS=HIGH oder DOS=UMB (oder beides) gesetzt ist, prüft DOS nach nach dem Laden eines Gerätetreibers, ob er sich unter dem Namen "XMSXXXX0" registriert hat. Sollte das der Fall sein, versucht DOS über die XMS-API die HMA zu reservieren (für DOS=HIGH) und/oder die UMBs zu reservieren (für DOS=UMB). Es muss also nicht Dein UMB-Treiber die UMBs aktiv bei DOS eintragen, sondern stattdessen muss er sich als XMS-kompatibler Treiber im System registrieren. Dann kümmert sich DOS selbst darum, bei deinem Treiber die UMBs abzuholen und in die Free-List einzutragen.
Jackintosh hat geschrieben: Mi 26. Okt 2022, 21:59 Führt mich zur nächsten Frage:
Unterliegen executables, die aus der config.sys aufgerufen werden bestimmten Einschränkungen? Darf es z.B. ein COM Programm sein? 64KB reichen vollkommen zur Konfigurierung.
Du musst in der config.sys zwischen zwei Dingen unterscheiden: Programme, die Du mittels INSTALL startest, und DOS-Gerätetreiber, die Du mittels DEVICE lädst. Da es in Deinem Fall notwendig ist, dass Du das Gerät XMSXXXX0 anbietest, muss Dein Executable das Format eines .SYS-Treibers haben. Man kann, ich glaube seit DOS 4.0, SYS-Treiber in ein EXE-Gerüst verpacken, was in Deinem Fall aber völliger Overkill wäre.
Jackintosh
MemMaker-Benutzer
Beiträge: 57
Registriert: Di 25. Okt 2022, 15:46

Re: UMA unter DOS

Beitrag von Jackintosh »

mkarcher hat geschrieben: Do 27. Okt 2022, 16:56Dann kümmert sich DOS selbst darum, bei deinem Treiber die UMBs abzuholen und in die Free-List einzutragen.
Dies ist für mich nicht nachvollziehbar. Ich habe mal in die XMS30.TXT reingeschaut http://www.phatcode.net/res/219/files/xms30.txt und für mich sieht es so aus, als würden lediglich die Funktionen 10h,11h und 12h für UMBs dienlich sein. Diese sind m.E. vergleichbar mit malloc, free und realloc in der Standard C-Lib. So eine Art "query" sehe ich nicht.
Mein UMB Treiber müsste dann die Funktionscodes 0h, 10h, 11h und 12h unterstützen?

Ich tippe mal, was mir so vorschwebt bzw. wie ich das ganze HMA,UMB etc. Zeug verstehe:
Auf einem 8088/8086 System ist HMA nicht möglich, somit HIMEM.SYS nicht nutzbar?!? UMBs hingegen schon. Ein UMB Treiber, der sich als Devicetreiber und dieser XMSXXXX0 Kennung installiert, wird dann funktionieren. Was aber passiert bei einem 80286 System?
(Systeme mit >= 80386 betrachte ich nicht, da ist so eine UMB Erweiterung sicher unnütz.)
(Ein 8088/8086 System mit 1MB RAM benötigt für UMBs dann einen Treiber wie die von Dir Eingangs genannten USE!UMBS etc.)
  • 80286 mit <= 640KB RAM: mein SRAM und UMB Treiber funktionieren dann wie in einem 8088/8086
  • 80286 mit = 1MB RAM: mein SRAM ist unnötig. Kann HIMEM.SYS hier installiert werden, obwohl keine HMA verfügbar ist? Beschränkt sich HIMEM.SYS in diesem Fall auf das Bereitstellen von UMBs?
  • 80286 mit > 1MB RAM: HIMEM.SYS kann HMA (somit XMS) und UMBs bereitstellen
Ich knobel gerade über der Frage, ob es sinvolle Konstellationen gibt, in denen HIMEM.SYS und mein UMB Treiber gleichzeitig im System geladen werden könnten. Vermutlich geht das aufgrund dieser eindeutigen XMSXXXX0 Kennung (die es dann zweimal gäbe) gar nicht.

Habe die Quellcodes von USE!UMBS und UMM03 überflogen:
  • bei beiden finde ich die XMSXXXX0 Kennung nicht
  • wie bleiben sie resident im Speicher? Einen Aufruf von int 21h ah=31h (keep resident) finde ich bei beiden nicht
Oder werden Treiber, die über DEVICE= aufgerufen werden immer resident gehalten?
mkarcher
LAN Manager
Beiträge: 204
Registriert: Fr 5. Jun 2020, 19:38

Re: UMA unter DOS

Beitrag von mkarcher »

Jackintosh hat geschrieben: Fr 28. Okt 2022, 09:49 Dies ist für mich nicht nachvollziehbar. Ich habe mal in die XMS30.TXT reingeschaut http://www.phatcode.net/res/219/files/xms30.txt und für mich sieht es so aus, als würden lediglich die Funktionen 10h,11h und 12h für UMBs dienlich sein. Diese sind m.E. vergleichbar mit malloc, free und realloc in der Standard C-Lib. So eine Art "query" sehe ich nicht.
Mein UMB Treiber müsste dann die Funktionscodes 0h, 10h, 11h und 12h unterstützen?
Völlig korrekt. Dabei funktioniert die Sache so, dass DOS sich einmalig mit malloc alle UMBs vom XMS-Treiber abholt und danach in Eigenregie verwaltet. Solange Du als einzigen Nutzer von UMBs den DOS-Kern haben willst, kannst Du Dir vermutlich sogar die Funtkionen 11 und 12 sparen...

Query gibts indirekt. Rufe Alloc mit einer unmöglichen Größe auf, dann bekommst Du einen Fehler, und gesagt, was der größte verfügbare Block ist. Dann kann man den Block reservieren und von vorne Anfangen. Wenn der größte verfügbare Block als 0 angegeben wird, sind alle UMBs belegt. Angenommen, wir haben C800-D7FF und DC00 bis DFFF als UMBs verfügbar, dann sieht das etwa so aus:
  • DOS: Gib mir bitte einen 1MB UMB
  • XMS-Treiber: Geht nicht, habe maximal 64KB am Stück
  • DOS: Gib mir bitte einen 64KB UMB
  • XMS-Treiber: Gerne, der beginnt bei C800
    [*']DOS: Gib mir bitte einen 1MB UMB
  • XMS-Treiber: Geht nicht, habe maximal 16KB am Stück
  • DOS: Gib mir bitte einen 16KB UMB
  • XMS-Treiber: Gerne, der beginnt bei DC00
  • DOS: Gib mir bitte einen 1MB UMB
  • XMS-Treiber: Geht nicht, UMBs sind alle belegt.
Jackintosh hat geschrieben: Fr 28. Okt 2022, 09:49 Ich tippe mal, was mir so vorschwebt bzw. wie ich das ganze HMA,UMB etc. Zeug verstehe:
Auf einem 8088/8086 System ist HMA nicht möglich, somit HIMEM.SYS nicht nutzbar?!? UMBs hingegen schon. Ein UMB Treiber, der sich als Devicetreiber und dieser XMSXXXX0 Kennung installiert, wird dann funktionieren. Was aber passiert bei einem 80286 System?
Auch kein Problem. Man kann mehrere Treiber laden, die XMSXXXX0 heißen. Wenn Du den UMB-Treiber zuerst lädst, kannst Du auf einem 286 sogar HIMEM mit DEVICEHIGH in einen UMB laden.
Jackintosh hat geschrieben: Fr 28. Okt 2022, 09:49 80286 mit = 1MB RAM: mein SRAM ist unnötig. Kann HIMEM.SYS hier installiert werden, obwohl keine HMA verfügbar ist? Beschränkt sich HIMEM.SYS in diesem Fall auf das Bereitstellen von UMBs?
Bei 286-Computern mit 1MB RAM wird das RAM häufig als 640KB + 384KB Extended Memory (also lineare Adressen 100000h bis 160000h) angeboten, und nicht als UMB. Damit hast Du eine HMA und etwa 320KB weiteres Extended Memory.
Jackintosh hat geschrieben: Fr 28. Okt 2022, 09:49 80286 mit > 1MB RAM: HIMEM.SYS kann HMA (somit XMS) und UMBs bereitstellen
HIMEM unterstützt keine UMBs. Auf einem 286/386-System mit UMBs lädt man typischerweise erst UMB_DRVR / USE!UMBS und danach HIMEM. DOS holt sich vom UMB-Treiber die UMBs ab, wie oben beschrieben, und danach vom XMS-Treiber auch noch die HMA. Weder UMBs noch HMA werden durch den DOS-Kern je an den XMS-Treiber zurückgegeben. Die Freigabefunktionen sind nur für den Fall gedacht, dass man nicht mit DOS=HIGH,UMB diese Speicherbereiche an den DOS-Kern überreicht, sondern Applikationsprogramme selbst UMBs oder die HMA während der Laufzeit des Programms reservieren und am Ende wieder freigeben. In der Praxis macht das aber keiner.
Ich knobel gerade über der Frage, ob es sinvolle Konstellationen gibt, in denen HIMEM.SYS und mein UMB Treiber gleichzeitig im System geladen werden könnten. Vermutlich geht das aufgrund dieser eindeutigen XMSXXXX0 Kennung (die es dann zweimal gäbe) gar nicht.
Wie oben beschrieben: HIMEM bietet zwar XMS an, aber implementiert die UMB-Funktionen nicht. Du musst also auf jeden Fall beide Treiber anbieten.
Habe die Quellcodes von USE!UMBS und UMM03 überflogen:
  • bei beiden finde ich die XMSXXXX0 Kennung nicht
  • wie bleiben sie resident im Speicher? Einen Aufruf von int 21h ah=31h (keep resident) finde ich bei beiden nicht
Oder werden Treiber, die über DEVICE= aufgerufen werden immer resident gehalten?
Oh, gut dass Du noch einmal nachgeguckt hast. Offenbar ist nicht der Name XMSXXXX0, sondern die Unterstützung von INT 2F, 4300/4310 das Kriterium. USE!UMBS verwendet I_LOVE_M als Kennung, und das geht offenbar auch. Und was die Koexistenz von XMS-Treibern betrifft: Du siehst bei USE!UMBS, dass der XMS-Einsprungspunkt wie folgt beginnt:

Code: Alles auswählen

jmp realentry
nop
nop
nop
realentry:
Wenn Du später auch noch HIMEM lädst, dann patcht HIMEM diese 5 Bytes (2 Bytes JMP SHORT + 3 * NOP) durch einen FAR-Jump auf den HIMEM-Einsprungspunkt. Bei Requests, die HIMEM nicht erledigen kann (z.B. UMB-Requests) spring HIMEM dann auf realentry. Ein XMS-Treiber muss, sofern er bei INT2F schon einen XMS-Treiber findet, eine potentielle Kette von JMP-FAR-Befehlen verfolen, bis er auf JMP SHORT + 3*NOP (EB 03 90 90 90) landet, und sich dann dort reinhängen. Damit ändert sich dann der XMS-Einsprungspunkt trotz Funktionserweiterung nicht. INT 2F muss im Fall, dass schon ein XMS-Treiber vorhanden ist, nicht selbst gehookt werden.

Wenn ein Treiber, der per DEVICE= geladen wird, muss er bei der Treiber-Funktion "Initialisierung" im Request-Header (so nennt USE!UMBS die Datenstruktur) zurückgeben, bis wohin er Speicher belgt. Das ist von DOS vorinitialisiert auf die Größe der .SYS-Datei, aber die meisten Treiber verkürzen das, um den Intialisierungs-Code nicht resident zu halten.
Jackintosh
MemMaker-Benutzer
Beiträge: 57
Registriert: Di 25. Okt 2022, 15:46

Re: UMA unter DOS

Beitrag von Jackintosh »

Ich danke Dir zunächst erstmal für die ausführlichen Informationen!
Da waren einige Dinge dabei, die mir in +30 Jahren nicht bewusst waren.
mkarcher hat geschrieben: Sa 29. Okt 2022, 00:55 Wenn ein Treiber, der per DEVICE= geladen wird, muss er bei der Treiber-Funktion "Initialisierung" im Request-Header (so nennt USE!UMBS die Datenstruktur) zurückgeben, bis wohin er Speicher belgt. Das ist von DOS vorinitialisiert auf die Größe der .SYS-Datei, aber die meisten Treiber verkürzen das, um den Intialisierungs-Code nicht resident zu halten.
OK - verstanden. Den Codeabschnitt habe ich in USE!UMBS gefunden.

Ich komme mal zu keep-it-simple zurück:
  • mein "Treiber" konfiguriert lediglich welche 16KB Blöcke an SRAM für die CPU sichtbar sind
  • und terminiert dann ohne resident zu bleiben
  • UMM03 und UMB_DRV lassen sich über Argumente steuern, wo UMBs vorhanden sind und ich überlasse diesen die UMB Verwaltung
Wegen "ohne resident zu bleiben" werde ich sicher hier irgendwann mal nachfragen müssen.

Nichtsdestotrotz haben mir Deine Erläuterungen zu UMBs eine Menge gebracht. Danke hierfür!

Wegen EMS mache ich einen neuen Thread auf.
Jackintosh
MemMaker-Benutzer
Beiträge: 57
Registriert: Di 25. Okt 2022, 15:46

Re: UMA unter DOS

Beitrag von Jackintosh »

Nachtrag:

ich habe das hier http://www.delorie.com/djgpp/doc/rbinter/id/21/30.html gefunden.
Mit AL=03h hängt DOS selbst UMBs in seinen MemoryPool ein?

Und dann noch https://fd.lod.bz/rbil/interrup/dos_kernel/2158.html
Wenn die AllocationStrategy auf 40h..42h eingestellt wird

Code: Alles auswählen

40h high memory first fit
41h high memory best fit
42h high memory last fit
dann wirkt sich dies auf INT 21h Funktion 48h (memory allocation) aus?
Ich gehe mal davon aus, daß mit "high memory" Speicher im Bereich A000h..FFFFh gemeint ist und nicht die HighMemoryArea >= 10000h.
Somit könnte eine laufende Applikation über dokumentierte Wege an UMB kommen. Sollte dann nicht auch ein passendes free() im UMB Treiber implementiert werden? Oder sehe ich weiße Mäuse?
mkarcher
LAN Manager
Beiträge: 204
Registriert: Fr 5. Jun 2020, 19:38

Re: UMA unter DOS

Beitrag von mkarcher »

Jackintosh hat geschrieben: Sa 29. Okt 2022, 10:35 Wegen "ohne resident zu bleiben" werde ich sicher hier irgendwann mal nachfragen müssen.
Das ist ganz einfach: Setze den End-Offset auf 0, dann schmeißt DOS den Treiber komplett raus. Sache erledigt.
mkarcher
LAN Manager
Beiträge: 204
Registriert: Fr 5. Jun 2020, 19:38

Re: UMA unter DOS

Beitrag von mkarcher »

Jackintosh hat geschrieben: Sa 29. Okt 2022, 11:25 ich habe das hier http://www.delorie.com/djgpp/doc/rbinter/id/21/30.html gefunden.
Mit AL=03h hängt DOS selbst UMBs in seinen MemoryPool ein?
DOS führt die Speicherblöcke, die mit Funktion 48h belegt werden können, in einer verketteten Liste. Sobald DOS mit DOS=UMB dazu angewiesen wurde, UMBs zu verwalten, legt DOS eine zweite verkette Liste in den UMBs an. Mit Funktion 5803 kann man die UMB-Liste mit der Haupt-Liste verketten, oder diese Verkettung wieder aufheben.
Jackintosh hat geschrieben: Sa 29. Okt 2022, 11:25 Und dann noch https://fd.lod.bz/rbil/interrup/dos_kernel/2158.html
Wenn die AllocationStrategy auf 40h..42h eingestellt wird

Code: Alles auswählen

40h high memory first fit
41h high memory best fit
42h high memory last fit
dann wirkt sich dies auf INT 21h Funktion 48h (memory allocation) aus?
Genau so ist es. Wenn die UMBs mittels 5803 in die Haupt-Liste verkettet wurden, dann funktionieren die 40er-Strategien, die nur UMBs berücksichtigen, oder die 80er-Strategien, die zunächst versuchen, in den UMBs Speicher zu belegen, und nur wenn das nicht passt, in den konventionellen Speicher ausweichen. Ich bin mir gerade unsicher, ob nicht auch die Standard-Strategien in (0,1,2) in der Lage sind, UMBs zu belegen, wenn der konventionelle Speicher voll ist, und mit 5803 die Verwendung von UMBs freigeschaltet wurde.
Jackintosh hat geschrieben: Sa 29. Okt 2022, 11:25 Ich gehe mal davon aus, daß mit "high memory" Speicher im Bereich A000h..FFFFh gemeint ist und nicht die HighMemoryArea >= 10000h.
Völlig richtig. (MS-)DOS bietet keine offizielle API, um Bereiche der HMA zu belegen. Auch HIMEM bietet keine Möglichkeit, die HMA teilweise zu belegen. Der XMS-Call zum Belegen der HMA enthält zwar eine Byte-Anzahl, aber der gibt nicht an, wieviel Bytes belegt werden sollen, sondern der Call reserviert immer die gesamte HMA für den Aufrufer - wenn er Erfolgreich ist. Die Byte-Anzahl ist ein Hinweis an den XMS-Treiber, wieviele Bytes der Aufrufer in der HMA nutzen will, und dann kann HIMEM entscheiden, ob es lohnt, die HMA für diese Byteanzahl herauszugeben, oder ob HIMEM die Herausgabe ablehnt und auf einen anderen Kandidaten wartet, der mehr Speicher aus der HMA nutzen möchte. Dazu hat HIMEM die Option /HMAMIN, mit der eingestellt werden kann, wie viele Bytes ein HMA-Nutzer mindestens benutzen muss, damit er die HMA (exklusiv) bekommt.

Speicher in der HMA ist insofern problematisch, als Zeiger in die HMA nicht normalisiert werden können. So kann zum Beispiel ein Sektorpuffer an der Adresse FFFF:1020 liegen. Wenn jetzt auf den Zeiger die gewöhnliche Huge-Zeiger-Normalisierung angewendet wird, ergibt das 0101:0000, was mitten im DOS-Kern auf normalen DOS-5-Systemen liegt. Viele DOS-Libraries gehen davon aus, dass eine Zeiger-Normalisierung nicht schadet, daher ist es ungünstig, HMA-Zeiger an Code weiterzugeben, den man nicht im Detail kennt.
Jackintosh hat geschrieben: Sa 29. Okt 2022, 11:25 Somit könnte eine laufende Applikation über dokumentierte Wege an UMB kommen. Sollte dann nicht auch ein passendes free() im UMB Treiber implementiert werden? Oder sehe ich weiße Mäuse?
Du siehst weiße Mäuse. Laufende Applikationen können in der Tat über 48h/49h Speicher in UMBs belegen und freigeben. Dabei wird der Besitz des Speichers (genau wie im konventionellen Speicher) aber nur zwischen der Applikation und DOS hin- und hergeschoben. Der Speicher wird nie von DOS an den XMS-Treiber zurückgegeben.
Antworten