Главная – А. Борзенко. «Заглянем на диск». Эта статья в DJVU формате

КомпьютерПресс 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
Размер,
байт
Содержание
00h3Код инструкции перехода на программу IPL2
E9xxxx или EBxx90
03h8Имя и версия OEM
0Bh2Количество байт на сектор
0Dh1Количество секторов на кластер
0Eh2Количество резервных секторов, включая Boot-сектор
10h1Число таблиц FAT
11h2Максимальное число элементов в корневом оглавлении
13h2Общее количество секторов на логическом диске
15h1Тип носителя (media descriptor)
16h2Количество секторов в одной FAT
18h2Количество секторов на трек
1Ah2Количество головок
1Ch4Количество "скрытых" секторов
20h4Общее количество секторов на логическом диске
24h1Физический номер диска
25h1Зарезервировано
26h1Сигнатура 29h
27h4Двоичный номер диска
2Bh11Метка диска
36h8Зарезервировано
3Eh1
ПРОГРАММА IPL1

1FEh2Сигнатура 0AA55h
Рис. 1. Формат Boot-сектора

Последний элемент 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 - 1BDh446Резервируется для IPL1
1BE - 1CDh16Элемент 1-го раздела
1CE - 1DDh16Элемент 2-го раздела
1DE - 1EDh16Элемент 3-го раздела
1EE - 1FDh16Элемент 4-го раздела
1FE - 1FFh2Сигнатура 0AA55h
Рис. 2. Таблица деления диска (Disk Partition Table).
Смещение
hex
Размер,
байт
Содержание
00h1ПРИЗНАК ЗАГРУЗКИ
80h - загружаемый раздел
00h - незагружаемый раздел

01h
02h

03h

1
1

1
НАЧАЛО РАЗДЕЛА ДИСКА
бит 0-7: номер головки (0-255)
бит 0-5: номер сектора (1-63)
бит 6 и 7: старшие биты номера цилиндра
бит 0-7: младшие биты номера цилиндра (0-1023)
04h1ТИП РАЗДЕЛА
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ОТНОСИТЕЛЬНЫЙ СЕКТОР
Количество секторов перед началом раздела
0Ch4РАЗДЕЛ
Количество секторов в разделе
Рис.3. Формат полей описания диска

"Щелкни кобылу в нос — она
махнет хвостом".

Программа 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. Формирование логических дисков винчестера.

"Где начало того конца, которым оканчивается начало?"

Число секторов до начала раздела хранится в 4-байтном поле "Относительный сектор". Это число определяется путем последовательного подсчета секторов, начиная с сектора 1, головки 0, цилиндра 0 физического диска, и увеличения номера сектора на дорожке, затем номера головки, затем цилиндра. Число секторов в разделе хранится в 4-байтном поле "Размер". Как и для предыдущего поля, первое слово содержит младшую часть числа, второе — старшую.

"Что имеем не храним;
потерявши — плачем".

Нет нужды говорить о важности информации, хранящейся в Master Boot- и Boot-секторах винчестера. Сохранение копий этих секторов в виде файлов на дискете — не пустая предосторожность. Если верить Д.Н.Лозинскому, "наша страна выходит на первое место в мире по производству вирусов" (хоть в чем-то впереди!). Уже сейчас известны отечественные "продукты", портящие содержание BPB или Partition Table. Воспользовавшись утилитой NU (Norton Utilities) или специальной программой типа SAVBOOT (CGT Associates), вы избавите себя от возможных неприятных хлопот.

"И при железных дорогах лучше
сохранять двуколку".

Не огорчайтесь, если под рукой нет ничего подходящего. Для получения копий секторов понадобится только утилита DOS DEBUG. Создайте в текстовом редакторе два маленьких файла — M_BOOT.DBG:

а 100
mov       bx,200
mov       ax,201
mov       cx,1
mov       dx,80
int       13
int       3
« здесь пустая строка »
g
rcx
200
n a:\master.sec
w cs:200
q

и BOOT.DBG:

1 cs:100 2 0 1
rcx
200
n a:\boot.sec
w
q

соответственно. После выполнения команд
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.

Вместе с Козьмой Прутковым
составил А. Борзенко