Вернуться на ГЛАВНУЮ страницу
Вернуться к СПИСКУ СТАТЕЙ


Автор: Максим Тимонин aka Максагор
Дата:
31.12.2017 г.
Примечание: опубликовано в электронном журнале "InfoGuide" №12


32Мб хватит на всех - классическая "ошибка Билла Гейтса" в ATM-версии ОС CP/M

Только когда долго эксплуатируешь ту или иную ОС, можно досконально изучить все ее особенности, достоинства и недостатки, вплоть до глюков и ошибок. Это банальная истина, но именно это позволило найти такой недостаток в ATM-реализации ОС CP/M v2.2, о котором вот так просто предположить было нельзя.

Чтобы была понятна суть недостатка, кратко пробегусь по структуре организации дисковых устройств в данной версии ОС. Она такова: всего в системе может быть до 8 драйверов с номерами от 0 до 7. При этом номера драйверов 0, 6 и 7 были зарезервированы под будущие расширения и не использовались, №5 (NETdisk – сетевой диск) был заявлен в документации, но на данный момент неизвестна прошивка ПЗУ, где бы он был бы реализован, №1 (ROM-диск) мной был встречен только один раз в специальной «увеличенной» ПЗУ объемом в 256Кб для ATM-turbo 2+, №4 (HDD) имеется в наличии ПЗУ только ATM-turbo 2(+), и только драйвера под номерами 2 (RAM-диск) и 3 (FDD) имеются в прошивках для всех типов АТМ.

Путем подключения к данным драйверам описателей блочных устройств можем получить разные диски или разделы на дисках. Всего таковых РАЗНЫХ описателей-каналов в ядре системы может быть создано 10 (десять). В свою очередь, эти 10 каналов можно подключить к 16 (ШЕСТНАДЦАТИ) буквам логических дисков-устройств (A: B: C: D: …. N: O: P:). При этом, учитывая, что каналов-описателей меньше, чем логических дисков, только максимум 10 дисков будут независимыми друг от друга, а дополнительные диски можно задействовать, если, например, в целях большего удобства в копировании, назначать некоторые каналы сразу на несколько дисков, например, привязать  Флоппи-дисковод 0 сразу к буквам A: и C:, а флоппик 1 – к буквам B:, D: и K: и т д.

Вот с таким набором и приходится иметь дело в CP/M на машинах линейки ATM. И если при работе на ATM-turbo 1 где из реально существующих дисков есть только FDD и RAM-диск и, по факту, реально мной использовались только буквы A: B: C: (собственно RAM-диск и два флопика), то все изменилось, когда я пересел на ATM-turbo 2+, где присутствует Его Величество Винчестер. В CP/M нет полноценных каталогов, поэтому огромное количество файлов быстро превращаются в бессвязную кашу, в которой трудно что-либо найти. Плюс, чем больше файлов в каталоге, тем все больше тормозит система при попытке его обработать. В итоге, зачастую, скорость работы программы с винтом может, при большом числе файлов в каталоге упасть почти до скорости работы флопа в том же TR-DOS. Поэтому в мануалах по работе с винчестером в CP/M на АТМ не зря обращалось особое внимание на нерекомендуемость создавать слишком объемные разделы на винте и слишком большие области каталога. Наоборот, рекомендовалось делать изначальный, системный раздел винта с наиболее базовыми и часто встречающимися файлами и файлами настроек не больше 1-2Мб и каталогом в 128 файлов, а остальные уж как получится, то не более 512 – максимум 1024 файла в каталоге. При этом путем «метода проб и ошибок» я пришел к заключению, что максимальный размер раздела, с которым имеет смысл работать – 8Мб и 512 файлов в каталоге. В итоге, послушав советы в мануалах, я так как там написано и сделал, решив создать такую карту дисков:

Сначала тоже, что и в АТМ 1 (разве что там RAM-диск меньше на 512Кб)

            A: - RAM-диск в 944Кб (он на этой букве изначально после запуска. Переназначить можно, но по причинам, лежащим вне данной статьи это нерационально).
            B: - FDD 0 (640Кб)
            C: - FDD 1 (640Кб)

А дальше я планировал следующие разделы винта (их объем указан округленно):

            D: - HDD-partition 1 (1Мб, 128 файлов в каталоге) – тот самый системный раздел
            E: - HDD-partition 2 (4Мб, 256 файлов в каталоге) – тоже системный, чуть больше
            F: - HDD-partition 3 (8Мб, 512 файлов в каталоге)
            G: - HDD-partition 4 (8Мб, 512 файлов в каталоге)
            H: - HDD-partition 5 (8Мб, 512 файлов в каталоге)
            I: - HDD-partition 6 (8Мб, 512 файлов в каталоге)
            J: - HDD-partition 7 (8Мб, 512 файлов в каталоге)

И вот тут-то я и столкнулся с глюком: Разделы D-H создавались и открывались нормально, а вот созданные разделы I-J при попытке их открыть, хоть в оболочке прочитать каталог, хоть просто в командной строке только перейти на их букву, заканчивалось висяком системы намертво. Она просто застывала и переставала реагировать на все вокруг, кроме сброса – короче, полная «птица обломинго». Даже не было понятно, с чего начать разбираться. Удалось только выяснить, что если, к примеру, не назначать какую-то и ранних букв (например, G:), то тогда удавалось назначить диск из ранее «недоступных» букв. Также без проблем удавалось назначить эти буквы на уже существующие каналы – когда новая буква просто означала тот же диск, что одна из предыдущих букв. На этом когда-то исследования и были прекращены. И было это более 10 лет назад.

Сегодня, когда доступны эмуляторы АТМ, работающие с образами винчестера, что позволяет в любой момент посмотреть, что происходит в памяти, я вернулся к этой давней полузабытой нерешенной проблеме и, создав образ и разбив его на разделы, воспроизвел в точности эту ошибку, после чего полез в отладчик эмулятора. До сути я докопался довольно быстро. И ошибка оказалась не совсем ошибкой, но достаточно банальной. Вот в чем суть:

Ядро CP/M (CCP+BDOS+BIOS) в АТМ располагается по следующим адресам:

#D400-#DC05:        CCP (интерпретатор командной строки, независим от железа на котором запускается)
#DC06-#E9FF:       BDOS (диспетчер функций DOS, независим от железа на котором запускается)
#EA00-#F7FF:        BIOS (стандартная керналь низкоуровневых «железозависимых» функций).

Сразу за этими частями ядра лежит еще область:

#F800-#FFFF:         System Monitor – монитор наиболее низкоуровневых системных функций, куда обращаются «железозависимые» функции BIOS. Представляет собой керналь функций по прямому доступу к низкоуровневым драйверам физических устройств ввода-вывода, драйверу экранной консоли.

При этом раздел BIOS только отчасти «забит» кодом. В конце его располагаются области различных переменных – прежде всего описатели структуры подключенных дисков, а область размером в 2048 байт, непосредственно прилегающая к области System Monitor (#F000-#F7FF) отведена под т.н. «вектора размещения блоков» подключенных дисков. Другими словами, здесь размещаются карты заполнения дисков, которые не хранятся на самих дискетах (вроде FAT в MS-DOS), а вычисляются системой посредством анализа каталога вновь выбираемого диска – при этом под каждый логический блок выделяется 1 бит. Если блок свободен, бит=0, если занят – равен 1. Один логический блок может, теоретически, изменяться программно при создании дисковых описателей, но по умолчанию всегда системой выставляется равным 2048 байт или 2Кб. При этом существующими утилитами, занимающимися подключением новых дисков и описателей к дисковым каналам (@.COM, AS.COM, ASS.COM, ASSIGN.COM, FDISK.COM) можно менять только такие параметры как число головок, секторов, дорожек и размер фиизическихсекторов, да количество файлов в каталоге, но не размер логического блока. Таким образом, на текущий момент можно считать размер такого блока в 2048 байт как данность. В карте диска такой блок занимает 1 бит. Значит, на 8 блоков (16 Кб в сумме) придется 1 байт битовой карты.

По мере подключения новых и новых каналов дисков в рамках общей области #F000-#F7FF им один канал за другим выделяется пропорциональное размеру дисков место. Так, образом, битовая карта флоппи-дискеты размером в 640Кб займет 40 байт. Начало битовой области каждого из подключенных дисков запоминается и может быть получено программистом по функции BDOS №27. Нетрудно подсчитать, что вся эта область в 2048 байт в сумме позволит адресовать 16384 блока или 32768 килобайт (32 мегабайта) для всех подключенных дисковых каналов В СУММЕ. А что будет, если попытаться превысить этот объем? В моем случае, когда я подключал (см.табличку выше) диски A (RAM), B,C (FDD), D,E,F,G,H (HDD) общий объем составил 30896 Кб, т.е. почти приблизился к заветной границе. Подключение еще одного раздела винчестера, объемом 8Мб (8192Кб) однозначно превышала оставшийся незанятым объем выделенной под вектора размещения блоков области, заканчивающейся, как уже говорилось, на байте #F7FF. Как оказалось, в системе нет контроля за переполнением данной области. В результате, когда такое дополнительное устройство подключалось, при попытке его выбрать система, добросовестно обнуляя свою часть области перед считыванием каталога для анализа занятости диска, просто затирала начинающийся с #F800 системный монитор низкоуровневых функций, намертво вешая систему. Вот и все.

Остается только вопрос – почему была выделана такая маленькая область, учитывая, что нумерация блоков основана на 16-битной адресации, т.е. максимальное число блоков на логическом устройстве может достигать 65536, что только при размере блока в 2Кб дает максимальный размер одного устройства в 128Мб. И это если не увеличивать размер самих логических блоков! У меня есть предположение, что в свое время, при создании системы, никто не мог и представить таких объемов дисков, и посчитали, что 32 мегабайт под все подключенные диски будет выше крыши. Таким образом, перед нами очередное воплощение классической «ошибки Билла Гейтса», который, рассуждая про объемы ОЗУ, заявил, что «640Кб хватит всем». А вот не хватило – ни ОЗУ, ни зарезервированного объема в 32Мб для дисков.

В качестве итога: я еще планирую в будущем поиграться-таки размером логических блоков, для чего придется написать утилиту-настройщик. А пока уважаемым читателям – пользователям CP/M на АТМ настоятельная рекомендация тщательно считать общий объем создаваемых дисков, и при этом самим решать, что лучше – меньше разделов винта, но пообъемнее, или больше, но меньшего размера – лично я предпочитаю теперь второе. Меньшие разделы работают шустрее. А если мне их не хватает, то никто не мешает создать на винте какое угодно их количество, только подключать их  к конкретным буквам дисков поочередно, по мере необходимости. Всем успехов!