В системе управления памятью DOS верхняя область памяти ( HMA ) — это область ОЗУ , состоящая из первых 65520 байт сверх одного мегабайта в IBM AT или совместимом компьютере.
В реальном режиме архитектура сегментации процессоров Intel 8086 и последующих процессоров идентифицирует ячейки памяти с 16-битным сегментом и 16-битным смещением, которое разрешается в физический адрес через (сегмент) × 16 + (смещение). Хотя сегмент: смещение предназначено для адресации только 1 мегабайта (МБ) (2 20 байт) памяти, сегмент: смещение адресует FFFF:0010
и за пределами опорной памяти за пределами 1 МБ ( FFFF0 + 0010 = 100000
). Таким образом, на процессорах 80286 и последующих процессорах этот режим фактически может адресовать первые 65520 байт расширенной памяти как часть диапазона 64 КБ, начиная с 16 байт до отметки 1 МБ — FFFF:0000 (0xFFFF0)
до FFFF:FFFF (0x10FFEF)
. Процессоры Intel 8086 и 8088 , имеющие только 1 МБ памяти и только 20 адресных линий , переносились на 20-й бит, так что этот адрес FFFF:0010
был эквивалентен 0000:0000
. [1]
Чтобы разрешить запуск существующих программ DOS, которые полагались на эту функцию для доступа к нижней памяти на своих новых компьютерах IBM PC AT , IBM добавила специальную схему на материнской плате для имитации цикла. Эта схема представляла собой простой логический вентиль , который мог отключать 21-ю адресную линию микропроцессора, A20 , от остальной материнской платы. Этим вентилем можно было управлять, изначально через контроллер клавиатуры , чтобы разрешить запуск программ, которые хотели получить доступ ко всей оперативной памяти. [1]
Так называемые обработчики A20 могли динамически управлять режимом адресации, [1] тем самым позволяя программам загружать себя в область 1024–1088 КБ и работать в реальном режиме. [1]
Код, подходящий для выполнения в HMA, должен быть либо написан так, чтобы быть позиционно-независимым (используя только относительные ссылки), [2] [1] скомпилирован для работы по определенным адресам в HMA (обычно позволяя только одному или максимум двум фрагментам кода совместно использовать HMA), либо он должен быть разработан так, чтобы допускал перемещение по границе абзаца или даже смещение (со всеми адресами, фиксируемыми во время загрузки). [2] [1]
Прежде чем код (или данные) в HMA смогут быть адресованы ЦП, соответствующий драйвер должен убедиться, что HMA отображен. Для этого требуется, чтобы любые такие запросы туннелировались через заглушку, остающуюся в памяти за пределами HMA, которая будет вызывать обработчик A20, чтобы (временно) включить шлюз A20 . [2] [1] Если драйвер не отображает никаких публичных структур данных и использует только прерывания или вызовы, уже контролируемые базовой операционной системой, можно зарегистрировать драйвер в системе таким образом, чтобы система сама позаботилась об A20, тем самым устраняя необходимость в отдельной заглушке. [1] [nb 1]
Первым пользователем HMA среди продуктов Microsoft была Windows/286 2.1 в 1988 году, которая представила драйвер устройства HIMEM.SYS . Начиная с 1990 года с DR DOS 5.0 [3] от Digital Research (через [4] и CONFIG.SYS ) и с 1991 года с MS-DOS 5.0 [3] (через ), части BIOS и ядра операционной системы также могли быть загружены в HMA, [3] [5] освобождая до 46 КБ обычной памяти . [1] Другие компоненты, такие как драйверы устройств и резидентные программы terminate-and-stay-resident (TSR), могли быть загружены по крайней мере в верхнюю область памяти (UMA), но не в HMA. В DOS 5.0 и выше, с , система дополнительно пыталась переместить дисковые буферы в HMA. [5] В DR DOS 6.0 (1991) и выше дисковые буферы (через , а позже также ), части командного процессора COMMAND.COM, а также несколько специальных самоперемещающихся драйверов, таких как KEYB , NLSFUNC и SHARE , также могли загружаться в HMA (используя их опцию), тем самым освобождая еще больше обычной памяти и верхней памяти для работы с обычным программным обеспечением DOS. [1] TASKMAX , похоже, также переместил части себя в HMA. [6] [7] Novell 's NLCACHE из NetWare Lite и ранние версии NWCACHE из Personal NetWare и Novell DOS 7 также могли использовать HMA. [8] [9] [7] В MS-DOS/PC DOS общая часть COMMAND.COM размером около 2 КБ может быть перемещена в HMA, [10] а также битовые карты DISPLAY.SYS для подготовленных кодовых страниц . [10] [11] В MS-DOS 6.2 (1993) и выше, часть DBLSPACE.BIN / DRVSPACE.BIN размером около 5 КБ может сосуществовать с DOS в HMA (если не вызывается DBLSPACE / DRVSPACE ). [5] [12] В PC DOS 7.0 (1995) и 2000 , DOSKEY загружается в HMA (если доступно), [13]HIDOS.SYS /BDOS=FFFF HIDOS=ONDOS=HIGHDOS=HIGHHIBUFFERSBUFFERSHIGH/MH /NOHMAи SHARE также может быть загружен в HMA (если не /NOHMAуказана его опция). [13] В MS-DOS 7.0 (1995) - 8.0 (2000) части HMA также используются в качестве блокнота для хранения растущей структуры данных, записывающей различные свойства загруженных драйверов реального режима. [7] [14] [15]
[…] Одним из важнейших стимулов для добавления функций было конкурентное давление со стороны
DRDOS 5.0
, о котором мы впервые узнали весной 1990 года. Набор функций DRDOS побудил нас добавить поддержку
UMB
, обмен задачами и функцию Undelete. […] Значительная часть внимания руководства команды была отвлечена на новые функции, такие как программное обеспечение для передачи файлов, функция восстановления и сетевая установка […] В конце концов эта ситуация достигла критической точки в конце июля 1990 года, и под руководством
BradS
руководство команды провело серию напряженных совещаний, чтобы закрепить график и процесс закрытия проекта […](1+32 страницы)
[…]
MS-DOS 7.0
+ добавляет INT 21h/AX=4A03h и INT 21h/AX=4A04h.
RBIL
61 INT 21h/AH=52h содержит некоторую информацию о цепочке HMA MCB MS-DOS 7.0+ […] Перемещение HMA для резидентных программ имеет смысл для
DR-DOS
: хотя вы можете загружать большие части BIOS
и
BDOS
,
резидентную часть оболочки,
BUFFERS
и резидентные программы DR-DOS, такие как
SHARE
,
KEYB
и
NLSFUNC
(а в некоторых случаях и части TASKMGR и
NWCACHE
) в HMA, обычно все еще остается свободное место, обычно около 10 Кб (примерно до 20 Кб при использовании сторонней оболочки). Это также имеет смысл для
MS-DOS 5.0
-
6.22
и
PC DOS
до
2000
, которые обычно оставляют 4 - 7 Кб памяти HMA неиспользованными (SHARE, KEYB и NLSFUNC не могут загрузиться в HMA, но
DBLSPACE
и
HIMEM
могут в некоторой степени). Доступное пространство HMA может быть довольно ограниченным с
MS-DOS 7.0
+, поскольку эта проблема ввела новую и по большей части недокументированную структуру данных RMD, обычно расположенную в HMA. Ядро собирает и записывает данные конфигурации и драйвера реального режима во время загрузки (тип драйвера, прерывания, перехваченные драйвером, строка вызова
CONFIG.SYS
и т. д.) и сохраняет эту информацию в […] сложной […] и […] растущей структуре данных. Предположительно, эта информация должна использоваться ядром Windows для получения более полной картины загруженных драйверов реального режима вместо того, чтобы рассматривать DOS как монолитный блок или даже […] пытаться отсоединить или выгрузить некоторые из них, однако она используется лишь в очень ограниченной степени (например, вы можете увидеть часть информации, отраженной в файлах журнала, созданных при запуске Windows 9x, и некоторые части диспетчера конфигурации Windows также используют ее), оставляя место для предположений, выходящих далеко за рамки технической стороны — в частности, потому что ничего интересного не документировано… […]
NWDOSTIP.TXT
Это всеобъемлющая работа по Novell DOS 7 и OpenDOS 7.01 , включающая описание многих недокументированных функций и внутренних компонентов. Она является частью еще более обширной MPDOSTIP.ZIP
коллекции автора, которая поддерживалась до 2001 года и распространялась на многих сайтах в то время. Приведенная ссылка указывает на более старую версию файла, преобразованную в HTML.) [4][…] некоторые выпуски DISPLAY.SYS (
например,
PC DOS 7
/
2000 ) хранят неиспользуемые в данный момент шрифты в
памяти XMS
. Некоторые более ранние выпуски MS-DOS/PC DOS DISPLAY.SYS, похоже, имели возможность сохранять их в HMA […]
[…]
DOSKEY.COM
[…] Переместить код в HMA, если он доступен. […]
SHARE.EXE
[…] Переместить код в HMA, если он доступен, и добавлена опция /NOHMA для принудительной загрузки низкого уровня. […]
[…] Код ANSIPLUS не может быть загружен в HMA под
MS-DOS 7
(только Windows 9x), поскольку, по-видимому, недостаточно неиспользуемой памяти HMA. […]
[…] 86-DOS , а следовательно, и PC DOS / MS-DOS , использовали хитрый трюк. Байт по смещению 5 PSP содержал код операции дальнего вызова (9Ah); слово по смещению 6 PSP содержало соответствующее значение для указания размера сегмента программы, а также смещенную часть дальнего вызова. Слово по смещению 8, которое служило сегментной частью дальнего вызова, было создано таким образом, что при объединении со смещением оно переносилось (хорошо понятная функция ЦП 8086 ) и указывало на адрес 0:C0h, который содержит вектор прерывания 30h. […] Интерфейс CALL 5 работает даже в эмуляции DOS под Windows NT и OS/2, а эти системы, безусловно, не могут работать с отключенной линией A20 . Как же это тогда работает? […] Вместо того, чтобы обрезать биты адреса, система зеркально отображает пять байтов в 0:C0h в 1000C0h. Тот же метод фактически использовался в DOS 5 и выше, работающих с DOS=HIGH. В этом случае DOS гарантирует, что линейный адрес 1000C0h содержит соответствующий дальний вызов. […]
[…] в случае таких искаженных указателей […] много лет назад Аксель и я думали о том, как использовать *одну* точку входа в драйвер для нескольких векторов прерываний (так как это сэкономило бы нам много места для нескольких точек входа и более или менее идентичного кода кадрирования запуска/выхода во всех них), а затем переключиться на разные обработчики прерываний внутренне. Например: 1234h:0000h […] 1233h:0010h […] 1232h:0020h […] 1231h:0030h […] 1230h:0040h […] все указывают на одну и ту же точку входа. Если вы подключите INT 21h к 1234h:0000h и INT 2Fh к 1233h:0010h и так далее, они все пройдут через одну и ту же «лазейку», но вы все равно сможете различать их и переходить к разным обработчикам внутри. Подумайте о «сжатой» точке входа в заглушку A20 для загрузки HMA. Это работает до тех пор, пока ни одна программа не начнет выполнять магию сегмента: смещения. […] Сравните это с противоположным подходом, когда есть несколько точек входа (возможно, даже поддерживающих протокол IBM Interrupt Sharing Protocol ), который потребляет гораздо больше памяти, если вы подключите много прерываний. […] Мы пришли к выводу, что на практике это, скорее всего, не будет спасением, поскольку никогда не знаешь, нормализуют или денормализуют указатели другие драйверы, и по каким-либо причинам. […]