КомпьютерПресс 10'91
А. Борзенко. Заглянем на диск.
"Многие вещи, нам непонятны не
потому, что наши понятия слабы, но
потому, что сии вещи не входят в круг
наших понятий".
К.Прутков
Заглянем на диск
Каждый, кто впервые попадает в удивительный мир персональных компьютеров, непременно сталкивается буквально с лавиной новых английских и русских терминов. Часть из них пока "неузаконена" (по крайней мере, у нас), поэтому под разными названиями нередко скрыты одни и те же понятия. Это зачастую приводит к путанице даже среди вполне квалифицированных прикладных программистов. Одно из наиболее типичных терминологических заблуждений, с которым приходится сталкиваться на практике, связано с первым физическим сектором на винчестере и флоппи-диске (сектор 1, головка 0, цилиндр 0).
"Если на клетке слона прочтешь надпись "буйвол",
не верь глазам своим".
Опуская подробности работы POST BIOS (Power-on Self Test) IBM-совместимого компьютера, обратимся к другой важнейшей процедуре BIOS — подготовке начальной загрузки модулей DOS. Эту функцию осуществляет ROM Bootstrap Routine — программа начальной загрузки, хранящаяся в ПЗУ, т.е. BIOS. Иногда эту программу называют просто — "Начальный Загрузчик". Вышеназванная программа первым делом пытается считать сектор 1 (головка 0, цилиндр 0) с устройства А: в оперативную память компьютера по адресу 0:7C00h. В случае, если это устройство не готово, делается попытка прочитать тот же физический сектор, но уже с первого винчестера (устройство С:). Первый физический сектор на дискете имеет несколько названий: Boot Sector, Boot Record, Корневая Запись и, опять же, Начальный Загрузчик. С названиями такого же сектора на винчестере тоже не соскучишься: Master Boot Record, Partition Table Sector, Boot Sector, Master Boot Sector, Блок Начальной Загрузки. Условимся пока (хотя это дело вкуса) называть эти физические сектора так: для дискеты — просто Boot-сектор, а для винчестера — Master Boot Sector.
"Смотри в корень!"
Первым байтом Boot-сектора диска должен быть либо код безусловного перехода JMP (E9h) с последующим 16-битным смещением, либо код "короткого" (short) перехода JMP (EBh) с 8-битным смещением, причем третьим байтом в этом случае является код операции NOP (90h). Заканчивается сектор определенной кодовой комбинацией — сигнатурой — 0AA55h.
Сразу за инструкцией JMP в этом секторе следует 8-байтное поле, резервируемое для идентификации имени и версии OEM (Original Equipment Manufacturer), например, MS DOS 3.3 или PC Tools.
Третьим — главным компонентом Boot-сектора — является BIOS Parameter Block (BPB — блок параметров BIOS). Это важнейшая структура данных, содержащая, в частности, тип носителя (media descriptor), a также другие параметры, характеризующие формат диска (рис. 1).
Смещение hex | Размер, байт | Содержание |
---|---|---|
00h | 3 | Код инструкции перехода на программу IPL2 E9xxxx или EBxx90 |
03h | 8 | Имя и версия OEM |
0Bh | 2 | Количество байт на сектор |
0Dh | 1 | Количество секторов на кластер |
0Eh | 2 | Количество резервных секторов, включая Boot-сектор |
10h | 1 | Число таблиц FAT |
11h | 2 | Максимальное число элементов в корневом оглавлении |
13h | 2 | Общее количество секторов на логическом диске |
15h | 1 | Тип носителя (media descriptor) |
16h | 2 | Количество секторов в одной FAT |
18h | 2 | Количество секторов на трек |
1Ah | 2 | Количество головок |
1Ch | 4 | Количество "скрытых" секторов |
20h | 4 | Общее количество секторов на логическом диске |
24h | 1 | Физический номер диска |
25h | 1 | Зарезервировано |
26h | 1 | Сигнатура 29h |
27h | 4 | Двоичный номер диска |
2Bh | 11 | Метка диска |
36h | 8 | Зарезервировано |
3Eh | 1 | ПРОГРАММА IPL1 |
1FEh | 2 | Сигнатура 0AA55h |
Последний элемент Boot-сектора диска — это программа, называемая обычно Bootstrap, но, чтобы не путать ее с ROM Bootstrap Routine (и с легкой руки И. Карасика), удобнее назвать ее IPL2 (Initial Program Loading 2). Начальная инструкция JMP в Boot-секторе выполняет переход на точку входа именно этой программы. IPL2 в свою очередь, используя информацию из ВРВ, определяет, являются ли два первых файла в корневом оглавлении диска модулями DOS. Затем программа загружает эти файлы в младшие адреса памяти (70:0000h) и передает управление на IO.SYS (IBMBIO.COM). Далее следует процесс инициализации, выполняемый средствами самой DOS.
"Не в совокупности ищи единства,
но более — в единообразии разделения".
Если в память компьютера считан с винчестера Master Boot-сектор, то управление передается программе IPL1, которая расположена в его начале (рис. 2). Эта программа сканирует содержание Partition Table (таблицы деления диска), состоящее из четырех 16-байтных элементов, разбитых на поля. Поля содержат информацию о номерах начального и конечного секторов, номерах головок и цилиндров для соответствующего раздела, а также числе секторов, предшествующих разделу и включенных в раздел (рис. 3). К разочарованию пользователей DOS 3.30 надо отметить, что из четырех разделов диска только два могут принадлежать DOS — Primary и Extended, два оставшихся фирма Microsoft благородно резервирует для альтернативных операционных систем (ОС), например, CP/M-86. Пользователи DOS версий от 2.0 до 3.2 могут позволить себе вообще только один раздел DOS на поделенном диске.
Байт поля "Признак загрузки" используется программой IPL1 для выяснения, какой из разделов диска содержит загружаемую ОС. Активный (загружаемый) раздел в этом поле содержит код 80h, остальные разделы должны быть помечены кодом 00h, даже если ОС и могла бы быть загружена из этих разделов. Программа IPL1 считывает сектор, номер которого находится в поле "Начало раздела", а именно, в трех байтах, следующих за кодом 80h. В этих байтах находятся номера головки, сектора и цилиндра стартового сектора раздела. Несколько странное, на первый взгляд, распределение битов в байтах номеров сектора и цилиндра соответствует формату загрузки регистров перед обращением к функции чтения физического сектора диска прерывания 13h BIOS, обязательно используемого в программе IPL1. Хотя дизассемблирование — дело не для всех увлекательное, без особых усилий в шестнадцатиричном дампе IPL1 можно отыскать, по крайней мере, два обращения к int 13h (байты CD13h). Выбранный таким образом сектор является Boot-сектором активного раздела винчестера, а его содержание аналогично содержанию Boot-сектора флоппи-диска.
Байты | Размер байт | Содержание |
---|---|---|
000 - 1BDh | 446 | Резервируется для IPL1 |
1BE - 1CDh | 16 | Элемент 1-го раздела |
1CE - 1DDh | 16 | Элемент 2-го раздела |
1DE - 1EDh | 16 | Элемент 3-го раздела |
1EE - 1FDh | 16 | Элемент 4-го раздела |
1FE - 1FFh | 2 | Сигнатура 0AA55h |
Смещение hex | Размер, байт | Содержание |
---|---|---|
00h | 1 | ПРИЗНАК ЗАГРУЗКИ 80h - загружаемый раздел 00h - незагружаемый раздел |
01h 02h 03h | 1 1 1 | НАЧАЛО РАЗДЕЛА ДИСКА бит 0-7: номер головки (0-255) бит 0-5: номер сектора (1-63) бит 6 и 7: старшие биты номера цилиндра бит 0-7: младшие биты номера цилиндра (0-1023) |
04h | 1 | ТИП РАЗДЕЛА 00 - раздел не используется 01h - DOS 2.X с 12-битовой FAT 04h - DOS 3.X с 16-битовой FAT 05h - DOS 3.30 Extended-раздел 06h - DOS 4.X с 16-битовой FAT |
05h 06h 07h | 1 1 1 | КОНЕЦ РАЗДЕЛА ДИСКА бит 0-7: номер головки (0-255) бит 0-5: номер сектора (1-63) бит 6 и 7: старшие биты номера цилиндра бит 0-7: младшие биты номера цилиндра (0-1023) |
08h | 4 | ОТНОСИТЕЛЬНЫЙ СЕКТОР Количество секторов перед началом раздела |
0Ch | 4 | РАЗДЕЛ Количество секторов в разделе |
"Щелкни кобылу в нос — она
махнет хвостом".
Программа IPL1 может выдавать на экран три сообщения. Если Partition Table содержит более одного загружаемого раздела — выдается сообщение Invalid Partition Table; если Boot-сектор активного раздела не удается считать в память — выдается сообщение Error loading operation system; если в Boot-секторе отсутствует сигнатура 0AA55h — выдается сообщение Missing operating system.
"Не будь портных — скажи: как
различил бы ты служебные ведомства?"
Теперь еще об одном важном поле элементов Partition Table — "Тип раздела". Код в этом поле указывает, какой именно ОС принадлежит данный раздел. Начиная с DOS 3.0, максимальный размер раздела физического диска может быть увеличен с 16 Мбайтов до 32 Мбайтов, благодаря введению 16-битных элементов FAT (File Allocation Table — таблица размещения файлов на диске). Хотя теоретически DOS 3.0 могла бы управлять диском размером вплоть до 134 Мбайтов. Действительно, если учесть, что максимальное количество кластеров 65535, а каждый кластер содержит 4 сектора размером по 512 байт: 65535*4*512=134215680 байт. Но граница в 32 Мбайта диктуется здесь известной структурой BPB в Boot-секторе раздела диска, в которой для общего количества принадлежащих диску секторов отведено лишь два байта (максим. 65535). Таким образом, максимальный размер действительно составляет: 65535*512 = 33553920 байтов.
Для того, чтобы сохранить совместимость с DOS 2.X, в DOS 3.0 была оставлена возможность управлять разделами диска с 12-битными элементами FAT. Поэтому все DOS З.Х-разделы диска размером меньше 16.7 Мбайт используют 12-битные элементы FAT. Так что при использовании разделов диска меньше указанного размера код в поле "Тип раздела" будет соответствовать DOS 2.X. Размеры разделов винчестера, начиная с DOS 4.0, перешагнули границу в 32 Мбайта и теоретически могут достигать фантастической пока цифры — 2048 Мбайтов. Для этого формат BPB был расширен, и под поле общего числа секторов диска было отведено уже 4 байта. Ревностным приверженцам DOS версии 3.30 не следует забывать, что Extended-раздел практически не ограничен размером, но должен быть поделен на логические диски (D,E,F и т.д.) с объемом каждого не более 32 Мбайтов.
"Во всех частях земного шара
имеются свои, даже иногда очень
любопытные, другие части".
Если поле "Тип раздела" содержит код 05h (Extended-раздел), то физический сектор, определяемый в поле "Начало раздела диска", является вовсе не Boot-сектором Extended-раздела, а вторичным Master Boot-сектором винчестера (Secondary Boot Sector). Этот сектор содержит собственную таблицу разделов, называемую Таблицей Логического Диска (Logical Drive Table), и непременную сигнатуру 0AA55h. Эта таблица и определяет местоположение и размер раздела, с которым DOS, вообще говоря, обращается, как с отдельным физическим диском. Вторичный Master Boot-сектор отличается от Master Boot-сектора, во-первых, тем, что он не содержит программы IPL1 и, соответственно, никогда не определяет загрузочный диск. Во-вторых, Таблица Логического Диска содержит максимум два 16-байтных элемента, а не четыре, как у Partition Table. Причем, если поле "Тип раздела" первого элемента таблицы определяет версию DOS, то такое же поле второго элемента таблицы (если он существует) содержит код Extended-раздела — 05h. Таким образом, второй элемент Таблицы Логического Диска определяет следующий вторичный Master Boot-сектор и т.д. (рис. 4). Каждый диск, определяемый Таблицей Логического Диска, честно содержит Boot-сектор, две копии FAT, корневую директорию, безусловно, область данных и форматируется посредством DOS. Понятно, что расположение Boot-сектора логического диска определяется первым 16-байтным элементом Таблицы.
"Где начало того конца, которым оканчивается начало?"
Число секторов до начала раздела хранится в 4-байтном поле "Относительный сектор". Это число определяется путем последовательного подсчета секторов, начиная с сектора 1, головки 0, цилиндра 0 физического диска, и увеличения номера сектора на дорожке, затем номера головки, затем цилиндра. Число секторов в разделе хранится в 4-байтном поле "Размер". Как и для предыдущего поля, первое слово содержит младшую часть числа, второе — старшую.
"Что имеем не храним;
потерявши — плачем".
Нет нужды говорить о важности информации, хранящейся в Master Boot- и Boot-секторах винчестера. Сохранение копий этих секторов в виде файлов на дискете — не пустая предосторожность. Если верить Д.Н.Лозинскому, "наша страна выходит на первое место в мире по производству вирусов" (хоть в чем-то впереди!). Уже сейчас известны отечественные "продукты", портящие содержание BPB или Partition Table. Воспользовавшись утилитой NU (Norton Utilities) или специальной программой типа SAVBOOT (CGT Associates), вы избавите себя от возможных неприятных хлопот.
"И при железных дорогах лучше
сохранять двуколку".
Не огорчайтесь, если под рукой нет ничего подходящего. Для получения копий секторов понадобится только утилита DOS DEBUG. Создайте в текстовом редакторе два маленьких файла — M_BOOT.DBG:
и BOOT.DBG:
соответственно. После выполнения команд
DEBUG < M_BOOT.DBG
DEBUG < BOOT.DBG
содержание Master Boot- и Boot-секторов будет
сохранено на дискете в файлах MASTER.SEC и BOOT.SEC. Использование int
3 позволяет проверить, насколько удачно завершилось чтение сектора
(отсутствие признака переноса и нулевое значение регистра AH).
"Плюнь тому в глаза, кто скажет,
что можно объять необъятное!"
В последнее время для конфигурации винчестера вместо утилиты FDISK часто используют специальные программы — "диск-менеджеры". Среди них широко распространены такие программы, как Disk Manager, Advanced Disk Manager, Speed Stor. Они имеют собственные таблицы разделов, свои драйверы дисковых устройств, причем необходимая служебная информация может храниться во втором физическом секторе (сектор 2, головка 0, цилиндр 0). Применение "диск-менеджеров" связано с предоставлением ими таких дополнительных возможностей, как защита логического диска от записи, организация парольной защиты и, конечно, создание логических дисков размером более 32 Мбайтов при работе с DOS 3.30.
Вместе с Козьмой Прутковым
составил А. Борзенко