РАБОТАЕМ С UNIX

КОМПЬЮТЕРНАЯ ГАЗЕТА

Linux и большие диски

Всем известна старая проблема, которая встречается при установке операционной системы на жесткие диски, количество дорожек на которых превышает магическое число 1024. Попробуем в ней разобраться.

(c) Компьютерная газета

Итак, предположим, что Вы стали обладателем такого диска (кажется, дефицита на подобные устройства сейчас не наблюдается). Также представим себе, что Вы работаете с операционной системой, которая использует BIOS. Вот теперь Вы столкнулись с проблемой, потому что обычное 13-ое прерывание BIOS использует для адресации цилиндров диска поле размером всего в 10 бит, поэтому для BIOS все цилиндры, начиная с 1024-го и выше, недоступны.
К счастью, Linux не использует BIOS и не знает этой проблемы. Но за исключением двух случаев:
1. Когда Вы загружаете операционную систему, Linux еще не успела взять на себя управление компьютером и не может избавить Вас от проблем BIOS. И это сказывается на LILO и других загрузчиках Linux.
2. Необходимо, чтобы все операционные системы, которые одновременно уживаются на Вашем компьютере, например DOS и Linux, пришли к соглашению друг с другом в вопросе геометрии жесткого диска и его разделов, которые они занимают. А этим занимаются сам кернел Linux и программа fdisk.

Загрузка
При загрузке системы BIOS считывает сектор с номером 0 (в миру известный как МБR — Master Boot Record) с первого жесткого диска или дискеты и перескакивает на адрес, указанный там, — обычно на адрес стандартного загрузчика. Стандартные загрузчики не имеют своих драйверов дисков и используют информацию о диске, которую предлагает им BIOS. Это значит, что кернел Linux может быть загружен, только если он расположен на диске не выше 1024-го цилиндра.
Эта проблема относительно легко разрешима — сам кернел и несколько файлов, необходимых при загрузке (LILO и др.), должны находиться на разделе диска, который целиком расположен ниже 1024-го цилиндра. Этот раздел доступен для BIOS, и обычно это первый или второй диск.
Второй способ — заставить BIOS и загрузчик договориться между собой насчет геометрии диска. Можно задать параметр "linear" для загрузчика LILO.

Геометрия и разделы диска
Если на Вашем диске сосуществуют несколько операционных систем, значит для каждой из них отведен один или несколько разделов этого диска. Любые разногласия между ними в вопросе физического расположения этих разделов могут иметь катастрофические последствия. МБR содержит таблицу разделов, которая описывает место расположения главных разделов (primary). В ней 4 записи, для четырех основных разделов, и каждая выглядит примерно так:

struct partition {
char active; /* 0x80: загружаемый, 0: не загружаемый */
char begin[3]; /* CHS первого сектора */
char type;
char end[3]; /* CHS последнего сектора */
int start; /* 32 бита для номер сектора (считая с 0) */
int lenght; /* 32 бита для количества секторов */
};
(CHS — эквивалент для Cylinder/Head/Sector, цилиндр-голова-сектор).

Информация эта даже избыточна — место расположения раздела можно определить как по двум 24-битным полям begin и end, так и по двум 32-битным полям start и lenght.
Linux использует только данные start и lenght и, следовательно, может работать с разделами, количество секторов которых не превышает 232 — что-то в районе двух Терабайт. Это значительно превышает максимальный размер жестких дисков, которые существуют сегодня, и, возможно, будет достаточным на ближайшее десятилетие.

К сожалению, 13-ое прерывание BIOS использует трехбайтный формат для адресации разделов диска (CHS), в котором 10 бит отводится для номера цилиндра, 8 бит — для номера магнитной головки, и 6 бит — на номер сектора на дорожке. Поэтому возможное количество цилиндров: 0-1023, число головок: 0-255 и число секторов: 1-63 (да, сектора на дорожке считаются с первого, а не с нулевого). Эти 24 бита разрешают адресацию всего 8455716864 байт (7.875 GB), что в двести раз больше самого большого диска, который существовал в 1983 году.
К еще большему сожалению, стандартный интерфейс IDE позволяет адресовать 256 секторов на дорожке, 65536 цилиндров и 16 головок. Само по себе это дает возможность работы с 237 = 137438953472 байт (128 GB), но в сочетании с ограничением BIOS на 63 сектора и 1024 цилиндра остается возможность адресации всего 528482304 байта (504 Мб).
Этого явно не достаточно для современных дисков, и люди постоянно придумывают разные трюки (как программные, так и аппаратные), чтобы обойти эти ограничения.

Преобразования и менеджеры дисков
На самом деле "настоящая" геометрия диска никого не интересует. Ведь число секторов на дорожке диска — величина переменная даже для одного диска, на внешних дорожках диска секторов больше, чем на внутренних, поэтому "настоящего и конкретного" числа секторов не существует! Пользователю проще представить свой диск как простой линейный массив секторов с номерами 0, 1,... и оставить контроллеру заботу о том, где располагается каждый из этих секторов.
Такая линейная нумерация известна как LBA. Линейный адрес, который принадлежит (c, h, s) на диске с геометрией (C, H, S), можно вычислить по формуле: c*H*S + h*S + (s-1). Все SCSI и большинство IDE контроллеров поддерживают LBA.
Если BIOS сможет конвертировать 24 бита (c, h, s) в LBA и передать эти данные контроллеру, который поддерживает этот режим, мы опять сможем адресовать 7.875 GB. Этого все еще не достаточно для всех дисков, но заметен прогресс по отношению к 504 Мб. Но теперь CHS, который использует BIOS, не имеет никакого отношения к реальности.
Иногда это может сработать, даже если контроллер диска не поддерживает LBA, но BIOS знает о возможности таких преобразований (в настройках BIOS можно указать параметр "Large"). Теперь BIOS рапортует операционной системе о геометрии (C', H', S') и использует (C, H, S) при общении с контроллером диска. Обычно S=S', C'=C/N и N'=H*N, где N — это наименьшее число, которое позволит добиться значения C'<=1024. Такие преобразования также позволяют адресовать 7.875 GB.


Если BIOS не знает таких слов, как "LBA" или "Large", в борьбу вступает программное обеспечение. Дисковые менеджеры (например, OnTrack или EZ-Drive) подменяют команды работы с диском BIOS своими собственными. Часто это достигается размещением кода дискового менеджера в МБR и последующих секторах (ОnTrack называет этот код DDO: Dynamic Drive Overlay), и он загружается перед загрузкой любой операционной системы. Но при установленном дисковом менеджере возникают проблемы при загрузке с дискет.
Эффект получается более-менее схожим с результатом преобразования данных BIOS, но если на одном диске уживается несколько операционных систем, дисковые менеджеры могут вызвать немало проблем.
Linux поддерживает дисковый менеджер ОnTrack, начиная с версии 1.3.14, и EZ-Drive с версии 1.3.29.
Если кернел Linux обнаружит присутствие любого менеджера на IDE диске, он постарается сохранить такую же геометрию диска, поэтому Linux увидит те же разделы диска, как, например, DOS с установленным OnTrack или EZ-Drive. Но если геометрия диска описана в командной строке: "hd=cyls, heads, secs", то вся совместимость с менеджером диска будет потеряна.


Преобразование геометрии диска начинается перебором количества головок: 4, 8, 16, 32, 64, 128, 255 (но произведение H*C остается постоянным) — до тех пор, пока или C не станет меньше, чем 1024, или Н=255.
Пользователи Linux должны быть уверены в том, что fdisk и LILO используют правильную геометрию диска, где слово "правильная" означает для fdisk именно ту геометрию, которую использует другая операционная система, если она расположена на этом же диске, а для LILO — та, которая обеспечит наилучшее взаимодействие с BIOS компьютера в момент загрузки. (Как правило, это две стороны одной же монеты).
Как программа fdisk узнает о геометрии диска? Она просто спрашивает об этом кернел, используя функцию HDIO_GETGEO. Но пользователь может изменить ее интерактивно или в командной строке.
Как загрузчик LILO узнает о геометрии диска? Он также спрашивает об этом кернел при помощи HDIO_GETGEO. Но пользователь опять может изменить ее, задав параметр "disk=" или параметр "linear".

Откуда кернел знает ответ на этот вопрос? Прежде всего пользователь может описать геометрию диска в командной строке: "hd=cyls, heads, secs". Или кернел сам спросит у компьютера.
Для IDE дисков есть четыре источника информации об их геометрии. Первый (G-user) указывается пользователем в командной строке. Второй (G-bios) — это таблица параметров жесткого диска BIOS (только для первого и второго диска), которая считывается при запуске компьютера, до переключения на 32-битный режим. Третий (G-phys) и четвертый (G-log) возвращают контроллер IDE в ответ на команду IDENTIFY — это "физическая" и "текущая логическая" геометрии.
Но драйверу необходимы два значения геометрии диска: и G-fdisk, который возвращает функция HDIO_GETGEO, и G-used, используемый для выполнения операций ввода-вывода. И тот, и другой инициализируются, если задан или G-user, или G-bios, если эту информацию содержит CMOS, или G-phys.
Другими словами: командная строка заменяет информацию, представляемую BIOS, и определяет геометрию диска, которую видит программа fdisk, но если эта геометрия предполагает mber