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, но если эта геометрия предполагает наличие более 16 головок, то кернел обновит ее командой IDENTIFY.
Игорь Грень
(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, но если эта геометрия предполагает наличие более 16 головок, то кернел обновит ее командой IDENTIFY.
Игорь Грень
Компьютерная газета. Статья была опубликована в номере 36 за 1999 год в рубрике soft :: unix