Next Previous Contents

## 11. Детали

## 11.1 Детали IDE - семь геометрий

Драйвер IDE имеет пять источников информации о геометрии. Первый (G_user) указывается пользователем в командной строке. Второй (G_bios) - это таблица с фиксированными параметрами диска в BIOS (только для первого и второго дисков),которая считывается при запуске, до переключения в 32битный режим. Третий (G_phys) и четвертый (G_log) - возвращаются IDE контроллером, в ответ на команду IDENTIFY,это 'физическая' и 'текущая логическая' геометрии.

С другой стороны драйверу нужны две величины для определения геометрии - это G_fdisk,возвращаемая `HDIO_GETGEO` ioctl, и G_used,которая непосредственно используется при операциях ввода вывода.Оба этих параметра инициализируются для G_user если таковой указан,или для G_bios,когда информация предоставлена в CMOS, и G_phys в любом другом случае. Если использование G_log выглядит разумным,то G_used устанавливается для него. В случае же если G_phys выглядит оптимальным, то G_used устанавливается для G_phys. Примечание: термин 'выглядит оптимальным,разумным' - означает, что число головок лежит в пределах 1-16.

Говоря проще : параметры переданные в командной строке имеют больший приоритет, чем параметры полученные от BIOS,и будут определять геометрию которую видит `fdisk`,но если будет указана преобразованная геометрия (более 16 головок),то при операциях ввода/вывода она будет замещена геометрией полученной от команды IDENTIFY.

Заметит что G_bios достаточно ненадежен: для систем загружающихся с SCSI первый и второй диски, могут быть SCSI дисками,и геометрия которую BIOS сообщает для sda будет использована ядром для hda. Более того,диски которые не упомянуты в BIOS Setup,не будут видны BIOS. Это означает, что например на IDE системе,где hdb не упомянут в Setup, геометрия сообщаемая BIOS для первого и второго дисков, будет геометрий hda и hdc.

## 11.2 SCSI детали

Ситуация с SCSI немного отличается,т.к. все SCSI команды используют логические номера блоков(секторов),поэтому геометрия не зависит от физических процессов ввода/вывода. В тоже время формат таблицы разделов такой же что и для IDE, поэтому `fdisk` 'у приходиться изобретать некую геометрию,он также использует `HDIO_GETGEO`. Несмотря на это `fdisk` различает SCSI и IDE диски. Как можно видеть из описанного выше, различные драйвера изобретают различную геометрию. Что вызывает некий беспорядок и неорганизованность.

Если вы не используете DOS или ему подобные системы, то надо опасаться любых установок, связанных с расширенным преобразованием,просто используйте 64 головки,32 сектора на дорожку(для того чтобы у вас на 1 цилиндр приходился 1 МиБ),если это возможно,так чтобы при перестановки диска с одного контроллера на другой не возникало проблем. Некоторые (aha152x, pas16, ppa, qlogicfas, qlogicisp) драйвера SCSI дисков, так обеспокоены совместимостью с DOS ,что они не позволят Линукс использовать более 8 ГиБ. Это баг.

Что такое настоящая геометрия? Самый простой ответ - таковой не существует. Даже если таковая и была бы , вам не нужно бы было её знать и не в коем случае не рассказывать о ней `fdisk` или LILO или ядру. Это дело только SCSI контроллера и диска.

Но если вам это жизненно необходимо, вы можете спросить сам диск. Существует очень важная команда READ CAPACITY, которая сообщает полный размер диска, и команда MODE SENSE, которая на странице Rigid Disk Drive Geometry (страница 04) сообщает количество цилиндров и головок (т.е. параметры которые нельзя изменить), на странице Format (страница 03) дает количество байт в секторе и количество секторов на дорожку. Последнее число обычно зависит от notch, а количество секторов на дорожку обычно переменное - внешние треки имеют больше секторов,чем внутренние. Программа `scsiinfo` сообщает подобную информацию. Существует огромное количество деталей,которые никто,включая операционную систему,знать не хочет. Более того , т.к. мы концентрируемся на `fdisk` и LILO, то обычно получаемые величины вроде C/H/S=4476/27/171 - значения которые не могут быть использованы `fdisk`, т.к. в таблице разделов эти значения не помещаются в отведенные им поля.

А откуда-же берет данную информацию `HDIO_GETGEO`? Оно опрашивает SCSI контроллер,или делает сложный запрос. Некоторые драйвера думают что мы хотим знать настоящие значения, хотя на самом деле нам нужно знать лишь то, что будет использовать Fdisk в DOS или OS/2.

Заметит что `fdisk` для Линукс требуются H и S - количество головок и секторов на дорожку, для преобразования LBA номеров в c/h/s адреса,но значение C (количество цилиндров) не играет роли в данном преобразовании. Некоторые драйвера используют значения C/H/S = 1023/255/63 чтобы сигнализировать, что емкость диска как минимум 1023`*`255`*`63 секторов.Это плохо,т.к. не соотвествует реальным размерам, и ограничит пространство доступное пользователям большинства версий `fdisk` 8'ю ГиБ'ами.Это наиболее серьезная проблема сегодня.

В описании данном выше, M обозначает общую емкость диска, и C/H/S количество цилиндров,головок и секторов/дорожка. Задание H,S необходимо если мы расчитываем C как M/(H`*`S).

По умолчанию, H=64, S=32.

aha1740, dtc, g_NCR5380, t128, wd7000:

  H=64, S=32.

aha152x, pas16, ppa, qlogicfas, qlogicisp:

  H=64, S=32 если C не > 1024, в таком случае H=255, S=63, C = min(1023, M/(H`*`S)). (Поэтому C урезается, и H`*`S`*`C не является усредненным значение емкости диска. Это вызывает недоумение у большинства версий `fdisk`.) Код `ppa.c` использует M+1 вместо M и сообщает что из за бага в `sd.c` M уменьшено на единицу.

advansys:

  H=64, S=32 если C не > 1024 и `> 1 GB' опция в BIOS включена, в этом случае H=255, S=63.

aha1542:

  Спрашивает контроллер какая из двух возможных схем преобразования используется,и использует либо H=255, S=63 либо H=64, S=32. В общем случае появляется следующее сообщение при загрузке. "aha1542.c: Использует расширенное преобразование BIOS".

aic7xxx:

  H=64, S=32 если C не > 1024, и загрузочный параметр "extended" либо бит "extended" был установлен в SEEPROM или BIOS, в это случае H=255, S=63. В Линукс 2.0.36 расширенное преобразование всегда устанавливалось ,если не было найдено SEEPROM,но в Линукс 2.2.6 если SEEPROM не найден то расширенное преобразование устанавливается только если пользователь задал соответствующий загрузочный параметр. (если SEEPROM найден то загрузочный параметр игнорируется). Это значит, что setup,который работает с 2.0.36 может перестать загружаться с 2.2.6(и требовать указания параметра 'linear' для LILO,или параметра ядра `aic7xxx=extended' )

buslogic:

  H=64, S=32 если C не >= 1024, и дополнительно,расширенное преобразование не было включено на контроллере ,в этом случае: если M < 2^22 то H=128, S=32; иначе H=255, S=63. Однако после выбора значений для C/H/S,считывается таблица разделов, и если для одной из трех возможностей (H,S) = (64,32), (128,32), (255,63) или значение H=H-1 найдено где либо,то используется пара (H,S),и выдается загрузочное сообщение "Adopting Geometry from Partition Table".

fdomain:

  Находит информацию о геометрии в таблице параметров диска BIOS, или считывает таблицу разделов и использует H=endH+1, S=endS для первого раздела (если такая информация дана), или использует H=64, S=32 для M < 2^21 (1 ГиБ), H=128, S=63 для M < 63`*`2^17 (3.9 ГиБ) и H=255, S=63 иначе.

in2000:

  Использует первое из (H,S) = (64,32), (64,63), (128,63), (255,63) которое сделает C равным < = 1024. В последнем случае, усекает C до 1023.

seagate:

  Считывает C,H,S с дичка. (Кошмар!) Если C или S слишком велики, то устанавливает S=17, H=2 и удваивает H до тех пор пока C не станет <= 1024. Это означает,что H будет установлено в 0 если M > 128`*`1024`*`17 (1.1 ГиБ). Это баг.

ultrastor и u14_34f:

  Одна из трех разметок ((H,S) = (16,63), (64,32), (64,63)) используется в зависимости от режима разметки контроллера.

Если драйвер не указывает геометрию, то мы возвращаемся назад к "отгадыванию" используя таблицу разделов, или используя полную емкость диска.

Взглянем на таблицу разделов. Т.к. обычно разделы оканчиваются на границе цилиндров, мы можем задать `end = (endC,endH,endS)` для любого раздела , просто укажите H = `endH+1` и S = `endS`. (обратно сектора отсчитываются от 1.) Если быть более точными , делается следующее. Если есть не пустой раздел , выбирается раздел с наибольшим `beginC`. Для этого раздела , смотрим на `end+1`, вычисляемое путем добавления `start` и `length` и предполагая что раздел заканчивается на границе цилиндров. Если оба значения совпадают, или если `endC` = 1023 и `start+length` целое произведение `(endH+1)`*`endS`, то предполагается что данный раздел расположен на границе цилиндров. , и используется H = `endH+1` и S = `endS`. Если это не срабатывает, потому - что нет разделов , или потому - что они имеют странные размеры, то используется только M - емкость диска. Алгоритм: возьмем H = M/(62`*`1024) (округленное вверх), S = M/(1024`*`H) (округленное вверх), C = M/(H`*`S) (округленное вниз). Это имеет эффект умножения (C,H,S) с C максимум 1024 и S максимум 62.

Next Previous Contents