From: Bob <ubob@mail.ru.>
Newsgroups: email
Date: Mon, 24 Jan 2005 14:31:37 +0000 (UTC)
Subject: Логическая структура жесткого диска
Исправленный и переработанный вариант статьи доступен по адресу http://www.opennet.ru/base/dev/hdd_struct2.txt.html
ЛОГИЧЕСКАЯ СТРУКТУРА ЖЕСТКОГО ДИСКА
В статье расcматривается логическая структура жесткого диска, соответствующая
стандарту Microsoft - "основной раздел - расширенный раздел - разделы не-DOS".
Пространство на жестком диске может быть организовано в виде одного или
нескольких разделов, а разделы могут содержать один или несколько логических
дисков.
На жестком диске по физическому адресу 0-0-1 располагается главная загрузочная
запись (master boot record, MBR). В состав MBR входят:
- внесистемный загрузчик (non-system bootstrap - NSB);
- таблица описания разделов диска (таблица разделов, partition table, PT).
Эта таблица расположена в MBR по смещению 0x1BE и занимает 64 байта;
- сигнатура MBR. Последние два байта MBR должны содержать число 0xAA55.
Таблица разделов описывает размещение и характеристики имеющихся на винчестере
разделов. Разделы диска могут быть двух типов - primary (первичный, основной) и
extended (расширенный). Максимальное число primary-разделов равно четырем.
Наличие на диске хотя бы одного primary-раздела является обязательным.
Extended-раздел может быть разделен на большое количество подразделов -
логических дисков.Упрощенно структура MBR представлена в таблице 1. Таблица
разделов располагается в конце MBR, для описания раздела в таблице отводится 16
байт.
Таблица 1.
Структура MBR
Смещение (offset) Размер (Size) Содержимое (contents)
-------------------------------------------------------------------------
0 446 Программа анализа таблицы разделов
и загрузки System Bootstrap
с активного раздела
-------------------------------------------------------------------------
0x1BE 16 Partition 1 entry ( элемент таблицы разделов)
-------------------------------------------------------------------------
0x1CE 16 Partition 2 entry
-------------------------------------------------------------------------
0x1DE 16 Partition 3 entry
-------------------------------------------------------------------------
0x1EE 16 Partition 4 entry
-------------------------------------------------------------------------
0x1FE 2 Сигнатура 0xAA55
Структура записи элемента таблицы разделов показана в таблице 2.
Таблица 2.
Структура записи элемента таблицы разделов
Смещение Размер поля, Содержание
байт
-------------------------------------------------------------------------
0x00 1 Признак активности (0 - раздел не активный,
0x80 - раздел активный)
--------------------------------------------------------------------------
0x01 1 Номер головки диска, с которой
начинается раздел
---------------------------------------------------------------------------
0x02 2 Номер цилиндра и номер сектора, с которых
начинается раздел
----------------------------------------------------------------------------
0x04 1 Код типа раздела System ID
----------------------------------------------------------------------------
0x05 1 Номер головки диска, на которой
заканчивается раздел
----------------------------------------------------------------------------
0x06 2 Номер цилиндра и номер сектора, которыми
заканчивается раздел
----------------------------------------------------------------------------
0x08 4 Абсолютный (логический) номер начального
сектора раздела
----------------------------------------------------------------------------
0x0C 4 Размер раздела (число секторов)
Первым байтом в элементе раздела идет флаг активности раздела (0 - неактивен,
0x80 - активен). Он служит для определения, является ли раздел системным
загрузочным и есть ли необходимость производить загрузку операционной системы с
него при старте компьютера. Активным может быть только один раздел. За флагом
активности раздела следуют координаты начала раздела - три байта, означающие
номер головки, номер сектора и номер цилиндра. Номера цилиндра и сектора задаются
в формате прерывания Int 0x13, т.е. биты 0-5 содержат номер сектора, биты 6-7 -
старшие два бита 10-разрядного номера цилиндра, биты 8-15 - младшие восемь битов
номера цилиндра.
Затем следует кодовый идентификатор System ID, указывающий на принадлежность
данного раздела к той или иной операционной системе. Идентификатор занимает один
байт. За системным идентификатором расположены координаты конца раздела - три
байта, содержащие номера головки, сектора и цилиндра, соответственно. Следующие
четыре байта - это число секторов перед разделом, и последние четыре байта -
размер раздела в секторах.
Таким образом, элемент таблицы раздела можно описать при помощи следующей
структуры:
struct pt_struct {
u8 bootable; // флаг активности раздела
u8 start_part[3]; // координаты начала раздела
u8 type_part; // системный идентификатор
u8 end_part[3]; // координаты конца раздела
u32 sect_before; // число секторов перед разделом
u32 sect_total; // число секторов в разделе
};
Элемент первичного раздела указывает сразу на загрузочный сектор логического диска
(в первичном разделе всегда имеется только один логический диск), а элемент
расширенного раздела - на список логических дисков, составленный из структур,
которые именуются вторичными MBR (Secondary MBR, SMBR).
Свой блок SMBR имеется у каждого диска расширенного раздела. SMBR имеет структуру,
аналогичную MBR, но загрузочная запись у него отсутствует (заполнена нулями),
а из четырех полей описателей разделов используются только два. Первый элемент
раздела при этом указывает на логический диск, второй элемент указывает на
следующую структуру SMBR в списке. Последний SMBR списка содержит во втором
элементе нулевой код раздела.
Рассмотрим программу, отображающую информацию обо всех разделах
(основных и логических), созданных на жестком диске. Программа функционирует под
управлением ОС Linux.
void read_ext_ptable(__u64 seek)
{
int num = 4; // начиная с этой позиции, массив структур pt_t будет
// заполняться информацией о логических дисках
__u8 smbr[512];
/* Функция принимает один параметр seek - смещение (в байтах) к расширеному разделу
* от начала диска. Для получения информации о логических дисках организуем цикл
*/
for(;;num++) {
/* Считываем SMBR, находящуюся по смещению seek от начала диска */
memset((void *)smbr, 0, 512);
pread64(hard, smbr, 512, seek);
/* Заполняем два элемента таблицы pt_t, начиная с num. Первый элемент будет
* указывать на логический диск, а второй - на следующую структуру SMBR
*/
memset((void *)&pt_t[num], 0, PT_SIZE * 2);
memcpy((void *)&pt_t[num], smbr + 0x1BE, PT_SIZE * 2);
/* Вносим поправку в поле "Номер начального сектора" -
* отсчет ведется от начала диска
*/
pt_t[num].sect_before += (seek / 512);
/* Если код типа раздела равен нулю, то больше логических дисков нет */
if(!(pt_t[num + 1].type_part)) break;
Имеется жесткий диск, подключеный как Primary Master. На диске
созданы три основных раздела (FAT32 и два EXT2 раздела) и расширенный раздел в
составе одного логического диска с файловой системой FAT32.
Результат работы программы:
# ./part_view
Сигнатура - 0xAA55
Num Bootable Start Total Id Type
1 * 63 4096512 0x0B FAT32
2 4096575 30732345 0x0F Win Ext'd (LBA)
3 34828920 12289725 0x83 Linux
4 47118645 31037580 0x83 Linux
5 4096638 30732282 0x0B FAT32
Для контроля получим информацию о логических дисках при помощи fdisk:
# fdisk -l -u
Disk /dev/hda: 40.0 GB, 40020664320 bytes
255 heads, 63 sectors/track, 4865 cylinders, total 78165360 sectors
Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 63 4096574 2048256 b Win95 FAT32
/dev/hda2 4096575 34828919 15366172+ f Win95 Ext'd (LBA)
/dev/hda3 34828920 47118644 6144862+ 83 Linux
/dev/hda4 47118645 78156224 15518790 83 Linux
/dev/hda5 4096638 34828919 15366141 b Win95 FAT32
1105 Прочтений • [Логическая структура жесткого диска] [08.05.2012] [Комментариев: 0]