MS-DOS UMA

Egyébbe tettem jobb ötlet híján, retro kérdés következik :)

A kérdésem túl régi és túl specifikus, vagy az is lehet hogy egész egyszerűen nem látom a fától az erdőt, de talán valaki tud segíteni és fényt hozni.

Az eredetileg (és valós módban utána is) 20 bites címzéssel rendelkező x86 processzorok, jelen esetben a 8088 és 8086ra gondolok, műkődképesek DOS 1.0 - DOS 6.22 rendszer mindegyikével. Az 1 megabyteos eredeti memória klasszikus felosztása hogy van a Conventional Memory, ami 0-640K (10x64K - ez mindenre elég, világos), aztán van az UMA, az Upper Memory Area, ami 384k méretű és elvileg mindig ennyi és mindig ott (?) (640K-1024K). Verziótól függően ebben lehet TSR, DEVICE, de még a DOS egy része is.

A kérdésem az, hogy mi van azokban az esetekben, amikor 1MB-nál kevesebb volt az elérhető RAM? többek közt volt 128K, 384K, 512K, 640K méretű kiszerelés is az IBM PCből. Ilyenkor hol van vagy hogy értelmezendő az UMA?  

Hozzászólások

Disclaimer: Piszok régen volt, és akkoriban még kb Pascalban írtam programokat, úgyhogy egészen lowlevel programozási tapasztalatom nincs vele.

Úgy gondolom kb fordítva volt, mint ahogy írod.

Amikor még kevesebb memória volt a gépben, akkor egyszerűen még az egész probléma nem is létezett.

A 640-1024k-s terület eredetileg nem volt memóriának szánva, hanem különféle perifériák voltak fixen leképezve ide. A CGA (asszem 0xA0000-tól kezdve) text mode vagy grafikus framebuffere, az MDA (monochrome display adapter, asszem 0xB0000-B7FFF-ig), a BIOS ROM-ok valahol a legvégen.

Az UMA már egy utólagos hack volt, amikor a gépekben elkezdett annyi memória lenni, hogy ide is jutott. Pl nem minden gépben volt egyszerre CGA (EGA, VGA is ugyanazt a helyet használta) és MDA adapter, így a kettő közül az egyik memóriatartománya szabad volt. Az alaplapnak is tudnia kellett róla, hogy melyik címet küldje az ISA busz (akkoriban még "PC" busz ill a 16bites változata "AT" busz néven futott) fele és melyiket a memóriának, a memória csak a nagyon korai szakaszban ült közös buszon a perifériákkal.

Régóta vágyok én, az androidok mezonkincsére már!

Kösznöm a válaszod, és a pontosítást is, igen azt ugyan nem tettem hozzá, de tudok róla, hogy a leképezések (is) itt kaptak helyet és azt is értem, hogy az UMA megközelítés és annak különböző felhasználása is már egy plusz a DOS részéről. Viszont, a kérdésem továbbra is ugyanaz, ha jól értem a terület eredeti és későbbi, cselesebb felhasználását, ezektől függtelenül: Hol van ez a terület, ha monjduk csak 384K RAM van a gépen? Akkor is létezik, mindentől függetlenül, fix címen 640 és 1024 között, közte meg "lyuk" van? 

Az a címtartomány mindig létezik, csak nem tudsz adatot tárolni ott, mert nincs mögötte semmi. Emlékeim szerint az ISA buszon a memory write ciklus le tud menni visszajelzés nélkül, vagyis a processzor hiba nélkül tud írni erre a területre. A visszaolvasásnál viszont fixen 0xFF-eket fogsz visszakapni (ha jól emlékszem az adatbitek alapból fel vannak húzva, ha nincs senki aki meghajtsa a buszt, akkor 1-es bitek jönnek vissza). DOS alatt a himem.sys volt a felelős érte, abban volt valami nagyon egyszerű beépített memóriateszt arra, hogy kiderítse, hogy van-e ott valódi memória. Ha úgy találta, hogy igen, akkor csinált belőle UMA-t, egyébként nem.

Régóta vágyok én, az androidok mezonkincsére már!

"Hol van ez a terület, ha monjduk csak 384K RAM van a gépen?"

valójában 1MB feletti címeket lapoznak be ide.

a himem.sys az pont nem, az a 286 -os cpu 20 bites cimzési "hibáját" kihasználva az FFFF:0000 feletti 64K -t teszi használhatóvá ; uma a 386 -os processzortól kezdve van, az emm386 valamelyik verziója kell hozzá ; ez azt csinálja, hogy a 386-os proci memoriacimforditási képességeit használva hoz be azokra a teruletekre ramot, amit a bovitokartyak romja szabadon hagy. Ez tudja a 286 -os alaplapoknal megjelent ems -t is emulálni, ami szintén az 1MB feletti területet mappeli be -- már nem emléxem, hogy 16K vagy nagyobbméretű laponként -- de azt keves program hasznalta. Mondjuk a korabeli Clipper pont szerette, ha van.

 

* az eredeti kerdesre a valaszt  XMI jól irta, a tartomány ( a teljes 1MB cimtartomany ) megvan, csak nincs mogotte semmi ; ha csak 384K ram van a gepben, akkor afelett kapsz vissza ff -et. A korabeli XT bios is ugy teszteli, hogy mennyi memoria van a gepben, hogy ir egy cimre eloszor ff -et es visszaolvassa aztan 00 -t es visszaolvassa ; ha egyik esetben nem azt kapja vissza, amit irt, akkor ott a vege. Gyorsabb biosok 55H vagy AAH -t ( masik jelolessel $55 vagy $AA ) -t probalnak be ; méggyorsabb biosok meg nem egyesevel novelik a szamlalot, hanem 1KB -vel ; de ezek ilyen reszletkerdesek :D

HUP te Zsiga !

Én ugyan soha nem használtam, de azt gondolnám hogy az EMS memória már 8088-on is elérhető volt. Az ugyanis lapozós, és éppen az UMA-ba volt egy lap bemappelve.

Mintha lett volna olyan nem túl elterjedt memóriamodul (se nem XMS, se nem EMS), ami a 16 bites ISA buszra csatlakozott, és a 20 bites címtér egy részéből csinált memóriát, lapozás nélkül. Talán ez volt az XMA?

8088 -on ha volt ems, akkor az csak valami zsugával lehetett, ha egyáltalán ; alapveto problema, hogy 1MB fölé nem tud a proci cimezni. a korabeli XT lapok 8 bites Isa buszán keresztul nemcsoda, ha nemlett sikertörténet.

286 -nal mar nagyobb a cimtartomány, lett 16 bitre bővitett isa is ; és jelentek meg olyan chipsetek, amik oda-vissza mappelgettek a memoriat ; sajna ennek a kezelese hw szinten nemvolt egyseges ; kezdetben még bios szinten sem ; szóval kb. a vagy működik egy szoftverrel vagy nem állapot megintcsak nem siettette a programolókat, hogy szokjanak rá ; az emm386 trukkjei hozták el a megváltást, de ahhozmeg minimum 386-os proci kellett, benne van a neveben :D

HUP te Zsiga !

Szerintem ems 286-tól volt. Az emm386 biztosan, de gondolom a 286-oson is virtuális módba kapcsolata a processzort (védett mód, de a programok úgy látják, mintha valós módban lennének, ez direkt visszafele kompatibilitási okokból van), és emlékeim szerint az 1mb feletti memóriát lehetett belapozni a 640k és 1mb közé.

Az $55 $AA más volt, az a BIOS bővítő (Option ROM) első két byte-ja volt kötelezően, a BIOS a memória végignézése közben erről tudta felismerni, hogy van bővítőkártya a gépben. Option ROM - Wikipedia

The BIOS Boot Specification requires that option ROMs be aligned to 2 kB boundaries (e.g. segments C8000h, C8800h, C9000h, C9800h, etc.). The first two bytes of the ROM must be 55 AA.[4] The third byte indicates the ROM size in 512-bytes blocks (e.g. 20h for 16kB ROM). And the fourth byte is where the BIOS begins execution of the option ROM to initialize it before the system boots.

Szerkesztve: 2024. 04. 17., sze – 11:18

Én nemrég találtam 1-2 jó videót, amik elmagyarázzák hogyan is volt DOS alatt a memóriakezelés.

https://youtu.be/P_FdCxHOeyU

https://youtu.be/EDl9qBZ9Bb0

Hát mit ne mondjak, szar világ volt akkoriban. Ma meg babzsákfejlesztő króm-developer befoglalja a 4-8-16 gigabájtját, és csüffög kényelmesen benne. Amíg a sok memory leak miatt ki nem fogy abból is.

>>Ilyenkor hol van vagy hogy értelmezendő az UMA?  

ugyanott, de a mm driver nem fog umb-ként használható területeket találni benne

Ott olyankor nincs RAM. A címtartomány létezik, ebbe kerülhetnek be mindenféle kiegészítések, olyan kártyák, amelyeknek saját ROM-juk van, és be tudnak fűződni a BIOS-ba. Vannak fix címek, ahol ezek a plusz kiegészítések kezdődhetnek (nem tudom, mekkora lépcső), a boot folyamatban a BIOS ezeket a címeket megpróbálja kiolvasni, ha talál az adott helyen egy megfelelő szekvenciát, akkor tudja, hogy ott van egy BIOS kiegészítés és arra átadja a vezérlést, aztán amikor visszatér, folytatja tovább, így több plusz kártya is használható. Így lehetett pl. az XT-ben használni 1,2 és 1,44 MB-os floppyt (az eredeti XT BIOS csak a 360 kB - és az annál kisebb szabványos - lemezformátumra volt felkészítve) illetve HDD-t használni, ha a floppyvezérlőn vagy a HDD vezérlőn (MFM vagy RLL) volt BIOS kiegészítés.

Ha 640 KiB és annál kevesebb memória van egy ilyen 20 bites címtartományú vagy 16 bites valós módban futó x86-os gépben, akkor nincs neki UMA-ja.

Ha több volt benne, mint 640 KiB, akkor sem biztosan használhattad a 640-1024 KB közötti részt, mert ott meg a BIOS meg egyéb eszközök ROM-ja van (meg videómemória), és ha azok elvileg feleszik az egészet, akkor nem marad semmi. Bár ez nem gyakorlati eset, mivel a gyakorlatban az eszközök minimális ROM-ra építkeztek, így maradt mindig valamennyi memória az UMB-ben.

Ez nem is csak MS-DOS 1.0-6.22 függő, hanem igaz mindenféle DOS-ra (FreeDOS, DR-DOS, OpenDOS), és azoknak minden verziójára, tehát az MS-DOS-nak a 7-8-as, meg PC DOS-nak a 2000-es, stb. verzióira is, sőt, a nem DOS operációs rendszerekre is, CP/86, Xenix, stb., bármire, ami valós módban fut (pl. saját gyártású bare metal program, ami mondjuk a boot sectorból indul), és nem használ más módot, annak ezek a memóriaterületek így érhetők el. Még a BIOS-ra is ezek a korlátok vonatkoznak, nem véletlenül volt szükséges az UEFI egy ponton túl.

Vigyázz, attól hogy DOS fut, attól ez nem mindig marad igaz, mert 386-ostól felfelé a himem.sys, emm386 és más memóriamenedzserek csaltak ám, és valós mód helyett virtuális móddal érték el az 1 MB feletti memóriát, XMS, EMS memóriaként, de ez már nem valós mód ilyenkor! Hasonlóan csaltak az DOS extenderek, amik 32 bites védett módban indultak, DOS4G(W), CWSDPMI, DJGPP, de a DOS alapú Windowsok DPMI módja is ide tartozik (Windows 3.0-Me között megjelent összes, nem NT alapú verzió).

Ezért is van, hogy a memóramenedzserek szépen 64 KB-osával belapozgatták az UMB-be az illető EMS memóriát, mert úgy már valós módban futó programok számára is elérhető. Az XMS memóriánál meg a himem.sys (és klónjai) a 20. címbittel variáltak, hogy elérjék ugyanezt.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Vigyázz, attól hogy DOS fut, attól ez nem mindig marad igaz, mert 386-ostól felfelé a himem.sys, emm386 és más memóriamenedzserek csaltak ám, és valós mód helyett virtuális móddal érték el az 1 MB feletti memóriát, XMS, EMS memóriaként, de ez már nem valós mód ilyenkor! Hasonlóan csaltak az DOS extenderek, amik 32 bites védett módban indultak, DOS4G(W), CWSDPMI, DJGPP, de a DOS alapú Windowsok DPMI módja is ide tartozik (Windows 3.0-Me között megjelent összes, nem NT alapú verzió).

386-tól érdekes mód volt még (vagy inkább egy kiskapu) a flat real mód, ahol átkapcsolták a processzort védett módba, és a GDT-ben be lehet állítani a szegmens méretét. Majd visszakapcsoltak valós módba.  Ezután valós módban lehetett megcímezni 4 Gb-ot egy szegmensen belül. De, hogy hol van szabad memória, az kérdés volt persze, a himemmel pl tudtál foglalni, majd elérni egy-az egyben. De szerintem ezt nem sokan használták, mert akkor már ott a védett mód.

Nem hallottam még erről, de most utánanéztem. Valóban van ilyen, de ez nem hivatalos működés, csak egy utólag, nem hivatalosan kitalált csúnya hekk, ami 286-tól működik. A 386 és felettieken is, értelem szerűen, de azok nem szorulnak erre rá, mert azokon ott van a rendes, 32 bites védett mód. A 8086-8088, amire a kolléga kíváncsi, ott meg nem játszik. Így lényegében ez egy 286 only trükk, amivel nem nagyon élt senki, nem volt bevett gyakorlat sem használni. Így én ezt továbbra sem használnám, mert oké, korabeli hardveren működik, de virtuális gépben, emulátorban lehet gondot okoz.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Igen, ismerem, és inkább csak érdekességnek írtam.

286-on soha nem használtam, és nem is látom az értelmét a 16 bites regiszterek miatt (de lehet hogy van), 386-tól egy otthon "kódolgató tinédzsernek" van értelme, például: ha védett módba vagy, akkor gondoskodnod kell róla, hogy meg tudjanak hívódni a megszakítások, a bios, és a dos-os rutinokat meg tudd hívni. Vagy használsz egy pmode extendert mint a Dos4gw vagy a Tran pmode extender, vagy csinálod ezt a "csúnya hack"-et. Azért találtam olyan hivatalos játékot, ami ezt használta, tehát voltak aki "production"-ben is használták. :) Egyébként a gépekben (virtuális is) működik.

Persze, hogy akkor van értelme. Ilyen kódolgató tinédzser volt anno ez a Doom polós, egyetemista Torvalds gyerek is, az eredetileg Minix-ből puskázott, 1 floppy-s, ATA only hobbikernelével.

Félelmetes belegondolni, hogy hol lennénk ma, ha csak 286-os unreal módban írja, vagy a 386BSD (Jolix) fél évvel előbb jeleneik meg, akkor ma nem létezne a Linux.

Egyébként nosztalgikusak ezek a DOS-os, hekkelős megoldások, meg az bare metal ASMx86, de tróger idők voltak, mindenféle móddal, szegmentálással, stb. szórakozni. Ma már ennyiből könnyebb, az UEFI átlövi a procit 64 bites védett módra (ezt továbbra is muszáj, mert alapból hardveresen mindig úgy van tervezve, hogy visszafelé kompatibilitás miatt valós módban induljon), aztán jó idő, nem kell semmilyen más móddal, szegmentálással, stb. szívni, a compiler-ök meg vadul optimalizálnak is.

Persze ma már ennek a valós módú kompatibilitásnak sincs értelme, mivel ilyen 16 bites rendszerek amúgy sem futnak. Nem tudják meghajtani a modern SATA, NVMe, USB-s háttértárakat, a modern gépeket már Legacy CSM BIOS emuláció sincs, meg az ATA mód SATA-n emulálása is hiányzik, sőt, az Intel 4. gentől kezdve az A20 vonal kapcsolgathatóságát is letiltotta az Intel. Így ilyen DOS, CP/M86, meg egyebek le lettek úgyis húzva a klotyón, emulátorban kell őket futtatni.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Azért tegyük hozzá, hogy ez x86-on igaz, mert összekötötték a védett módot az 1 mega feletti memória kezelésével. Ez egyáltalán nem lett volna szükségszerű.

De egy beágyazott rendszerben, mondjuk Cortex-M3 maggal, 32 bites egységes címtérrel teljesen jól használható a valós mód. Én megőrülnék, ha azt sem tudnám mi hol van a címtérben. Meg ott ritkán akarunk több alkalmazást futtatni, amiket memóriában szeparálni kellene egymástól.

Egyébként nosztalgikusak ezek a DOS-os, hekkelős megoldások, meg az bare metal ASMx86, de tróger idők voltak, mindenféle móddal, szegmentálással, stb. szórakozni.

Szívesen gondol rájuk az ember. Ma meg komplex library-kat kell hívogatnia, és 10000 réteg van egymáson, sajnos ilyen alacsony szintre nem kell menni. Már van olyan generáció, akiknek ezekről fogalma sincs, olyan magas szintű dolgokkal találkozhat már csak.

Persze ma már ennek a valós módú kompatibilitásnak sincs értelme, mivel ilyen 16 bites rendszerek amúgy sem futnak.

Az ARM-nek lenne még értelme nekifutni, gondolom ilyenek ott sincsenek. Érdekes lehet, hogy ott hogy működik, hova kell betölteni, mik a proci specifikus dolgok. Ezt még egyszer jó lenne megismerni. (meg nyerni a lottón, hogy legyen rá idő. :)) Iskolás voltam, és egy kb 10 évvel idősebb szomszédom volt, akit szintén érdekelt a programozás. Mentem a projekt tervemmel, és mondta, hogy sajnos tuti nem lesz rá munka és család mellett ideje. Emlékszem, hogy ezt nem hittem el neki, gondoltam magamban, hogy mindenkinek arra van ideje, amit akar. :)

Sőt, ezeket én is most olvasom, érdekes:

In August 1988, HIMEM.SYS version 2.03 implemented a new method of copying memory on 386 compatible processors, using unreal mode (or Big Real mode as it’s called in the HIMEM source) when the processor isn’t already in protected (or more specifically, V86) mode.

http://www.os2museum.com/wp/himem-sys-unreal-mode-and-loadall/

Tehát ezek szerint maga a himem.sys is használta.  :) Érdekes a cikk, érdemes szerintem elolvasni.

Tévhit, hogy ennek a DOS-hoz van köze. Nem, nincs. Bármilyen real mód alatt futó OS alatt is a 640K és az 1M közötti rész az az IO részére van fenntartva, tehát bizonyos perifériák oda vannak mappelve a memóriába. Pl. Videó RAM is itt található, de a video ROM, system ROM is.

Azonban mi van, ha a gépbe 1 mega memóriát pakoltak. Semmi. Elveszik. Illetve nem teljesen.

1) A ROM-ok áttölthetők az azonos címen található RAM-ba (shadow). Ez sokkal gyorsabb elérést tesz lehetőve.

2) Ha nem akarjuk a shadow-t használni, akkor egyes chipsetek képesek ezt a 384K-t hozzácsapni az XMS-hez.

3) Az EMM386 DOS alatt lehetővé teszi ennek a memóriaterületnek a részleges felhasználását. Ahol nincs semmilyen periféria, azt képes hasznosítani.

Szerkesztve: 2024. 04. 18., cs – 09:02

- Ha 1MB vagy még több RAM volt a gépben, és az alaplap+BIOS is úgy akarta, akkor a felső 384KB nem használt részeire kerülhetett RAM, csak a DOS nem tudott róla, ad-hoc programmal felvenni ezeket a területeket a DOS szabadmemória-listájára. (Neat/286/16MHz alaplapon csináltam ilyet 199x-ben. Szerk: ennél az alapnál volt olyan opció is, hogy pontosan 1MB RAM esetén 384KB az 1MB határ fölött legyen, Windows-hoz pl.)

- HIMEM: a hardverrel zsonglőrőzve a hagyományos 1MB felett 64KB-t (16byte híjján) használhattunk, 286+ processzorral, valós módban. (A HIMEM.SYS a DOS része, így DOS5+ tudta használni ezt a memóriát (vö: LOADHIGH, DEVICEHIGH, DOS=HIGH).

- EMS (fizikai): memóriabővítő hardver (ISA kártya), ami a felső 384KB-ben egy 64KB-s ablakban teszi elérhetővé a bővített memóriát, 4 darab 16KB-os keretben. (Nem volt triviális a használata, de pl. Ramdisk-nek nagyon jó.)

- EMS (szoftveres): az EMM386.EXE a CPU-t virtuális 8086 módba kapcsolja, így olyan memóriamiosztást allít be, amilyet akar, nevezetesen emulálja a fizikai EMS-t, és/vagy a címtartomány felső 384KB-jában a kihasználatlan részekre RAM-ot lapoz. (Ezeket a DOS5+ tudja használni, hiszen az EMM386.EXE a DOS komponse, vö.: DOS=UMB)

+1 286+ CPU-hoz voltak olyan szolgáltatások, amik memóriák másolását vállalták a teljes címtartományban, mégpedig úgy, hogy ideiglenesen védett módba kapcsoltak (megszakítást letiltva), aztán vissza valósba. (Ez utóbbi 286-on némi haxolást igényelt, ugyanis egy 'nem resetelő reset' művelet kellett hozzá.]

Elo kene szednem a regi 286-osomat, amin 1 mega memoria volt. Valahogy anno sikerult is hasznalnom ezt a 384k-t de mar nem emlekszem pontosan hogyan :) Rutinszeruen mar a 4 megas 386-osnal hasznaltam EMS-es lapozasos bovitest, az teljesen jo volt igy megismerni a dolgok lelkivilagat meg elsajatitani az ipar ezen reszet. 

Az XMS-t sima masolos modon hasznaltam, azaz hogy a felso memoriabol bemasolta a lenti reszbe ami onnan kellett es vice verza. Az EMS-t lehetett volna lapozosan is, de azt is inkabb igy hasznaltam (es akkor egy kvazi-azonos API-val lehetett a ket technikat hasznalni es/vagy keverni). Olyan nagy overhead nem remlik. Vagyis nyilvan joval hatekonyabb volt ez mint a kezi swappeles... mert legbelul mindegyik `rep movsd` + opcionalis `movsw` + `movsb` utasitaskora fordult, ami meg azert elegge hatekony a korulmenyekhez kepest... ah, a regi szep idok! 

Nekem 2M RAM volt a 286-osomban (úgy vadásztam össze a ram chip-eket régi rossz alaplapokból), és 1.3 megás ramdrive-ot tudtam csinálni. Asszem kellett hozzá alaplapi support, hogy a felső 384k-t az 1M feletti címtartományba mappelje.

Jól jött, mikor megdöglött a 20 megás mfm hdd-m, de a Norton Commander túl sokat megevett belőle, a Turbo Pascal-nak kellett a hely :) Iszonyat gyors volt, a fordítás gyakorlatilag instant ment.