Пред-замечание от 2024 года: всё это описание стало в основном иметь чисто исторический характер. Подавляющее большинство современных подходов основано на 1) интерфейсах с линейным адресом блока (LBA) — таких, как NVMe; 2) современных драйверах файловых систем; 3) загрузкой через EFI (UEFI), где обязательно использование таблицы разделов GPT с линейными адресами. Поэтому 99.9+% современных пользователей не увидят все перечисленные проблемы. Для остальных же остаётся данное описание.

ATA (IDE) — технология с историей и со странностями. Путь ее развития весьма извилистый. Этим объясняется множество проблем и заморочек, с которыми приходится на ней сталкиваться. Некоторые из них перешли и на применение SCSI дисков — например, проблемы с partition tables.

Диск — это непрерывный массив физических блоков(*1). Непрерывность этого массива принципиальна — нарушения сейчас допускаются только для "плохих" (нечитаемых и иным образом испорченных) физических блоков, и то эта особенность постепенно уходит в прошлое — плохие блоки там, где должны быть критически важные структуры, и раньше не допускались, а сейчас (по крайней мере для ATA дисков) сообщение о плохом блоке означает исчерпание внутреннего резерва запасных блоков и поэтому невозможность дальнейшей работы с этим диском. В то же время, адресовать блоки в этом непрерывном массиве можно двумя путями. Первый путь — адресация по прямому номеру блока; блоки нумеруются от нуля до максимально возможного номера, без разрывов в этой последовательности. Этот путь был изначальным для SCSI и воспроизводится в более новых интерфейсах типа NVMe, а также используется в любом сетевом доступе типа iSCSI, но не для IDE. Второй — изначальный для IDE/ATA, но не для SCSI — использование трех чисел, которые называются номером цилиндра, головки (дорожки) и сектора. Весь наш рассказ посвящен проблемам, которые исходят от этого пути.

((*1) В современных интерфейсах типа NVMe допускается разделение одного диска средствами его самого на несколько областей, в каждой из которых своя непрерывная адресация. В это мы сейчас не влазим.)

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

Адресация CHS — то есть, цилиндр/головка/сектор (cylinder/head/sector) - напрямую отражает технологию, принятую в (ранних) магнитных дисках. Опишем её подробнее.
Диск — множество пластин (одна или больше), на которых могут использоваться одна или две стороны. Номер поверхности — номер головки (еще один синоним к имеющимся двум, но использовать его мы не будем). Поверхность разбита на кольцевые дорожки. Группа дорожек на равном расстоянии от центра — цилиндр. На всех дорожках одинаковое количество одинаковых блоков. Угловая скорость чтения/записи блока — одинакова для всех цилиндров; линейная — растет по мере удаления от центра. Нехитрая премудрость этой адресации здесь заканчивается. Интерфейс ATA вплоть до ATA-6 (2002 г.) требовал поддержку этого режима, которая используется при начальной загрузке системы и других операциях; номер цилиндра, головки и сектора пишутся прямо в порты адресов ATA контроллера (и передаются напрямую диску), при этом диапазоны допустимых значений таковы: C — 0..65535, H — 0..15, S — 1..255. (По принятому стилю, нумерация секторов начинается с 1, а не с 0.) Практически, и все современные диски (в пределах Parallel ATA как минимум) поддерживают CHS адресацию, сохраняя совместимость с древними стандартами.

С ростом технологий, подобная схема стала слишком примитивной. Росли плотности как по количеству дорожек на поверхность, так и по количеству секторов. С какого-то момента контроллер диска стал производить ретрансляцию переданной ему геометрии в реальную дисковую, которая потеряла описанную примитивность — количество секторов на дорожку могло меняться, плотность записи могла меняться, и так далее. Используемая непосредственно на шине и рапортуемая для этих целей диском геометрия стала фиктивной, от которой требовалось соответствие желаниям и ограничениям интерфейса и софта, но не реальной обстановки на диске.

Размер блока (сектора) аж до 2010 года оставался равным 512 байт. В 2010 году производители выдвинули инициативу Big Sector, согласно которой сначала появляются диски с физическим размером сектора 4KB, но 512 байт на шине; через несколько лет обещали 4KB на шине. Детальное описание этого изменения см. в конце статьи. Заметим, что реально это изменение стало возможным только когда из-за размеров дисков перестала работать MS-DOS partition table — то есть на границах 1TB и 2TB.
Реально это изменение состоялось только для небольшого числа серверных дисков. Для остальных остался видимый для шины логический размер блока 512 байт, но рапортуемый через запрос свойств - 4096 байт - и то не для всех дисков. Для SSD, к тому же, дополнительная логика, требующая группировки операций размером блока SSD (обычно не менее 128 KiB), перекрывает данную группировку... в результате все проблемы группировки операций возложили на ОС и на кэш диска.

Как сказано выше, ограничение шины — 65536*16*255. В то же время, BIOS (интерфейсами d-1302, d-1303 — см. Ralf Brownʼs Interrupt List) ввела другие ограничения: 10 бит на цилиндр, 8 на головку и 6 на сектор, что дало предельную геометрию 1024*256*63. Эти же ограничения были повторены в структуре записи раздела в MSDOS partition table. Одновременно с C/H/S адресом блока, в таблицу писались абсолютные (линейные) адреса (номер начального блока и длина раздела), но для доступа средствами MS-DOS они не использовались — геометрия одна, и проще было применять CHS номера, чем пересчитывать абсолютные номера блоков. Драйверам файловых систем все равно приходилось делать такой пересчет, потому что в файловых системах нумерация была абсолютной; но загрузчики были лишены общения с абсолютными номерами блоков.

Шинную геометрию можно узнать (если диск поддерживает ATA-5 или более ранний стандарт) у диска командой Identify Device (код 0xEC). Эта команда появилась не сразу (но очень рано — во времена приблизительно 60MB дисков); до этого можно было только задавать геометрию руками в настройках BIOS. С ее появлением в BIOS появилась возможность сделать автодетект диска - диску отдавалась команда Identify Device и геометрия бралась из ответа диска. Значительно позднее стали применять автоидентификацию при каждой загрузке, вместо ручного прогона при изменении конфигурации.

Идиллия с геометрическим доступом кончилась по достижению барьера в 1024*16*63 блока, то есть 504 MiB (528 MB; производители дисков обычно пишут объёмы в десятичных мегабайтах, а не двоичных). Ограничение шины — 65536*16*255 - почти 2^28 блоков. (С учетом описанного ниже предела в 63 сектора - почти 2^26 блоков.) Ограничение BIOS и MSDOS — 1024*256*63 — почти 2^24 блока. Зато общее подмножество — только около 2^19 блоков, общая геометрия — 1024*16*63, что дает 504 "длинных" мегабайта (MiB), или 528 "коротких" (MB). Вместо переделки шин и таблиц, было принято решение по использованию ретрансляции на произвольном участке между MSDOS (и Windows, к тому времени) и шиной ATA — это решение откладывало переделку таблиц как минимум до достижения объема в 32 раза больше, чем 504M. Два пути, которыми это решалось — поддержка BIOS режимов, названных LARGE и LBA, и специальные драйвера, загружавшиеся на этапе чтения config.sys, сделанные из OnTrack Disk Manager производителями своих дисков (или OnTrack Disk Manager непосредственно).

(Во всём этом для меня самое непонятное - откуда в случае BIOS взялись именно такие размеры, кто и как их рассчитал. Даже если две поверхности у одного "блина" (физического диска — носителя информации), то я не могу себе представить 128 таких блинов в одном устройстве. Если бы предположили, например, пределы CHS соответственно 1024*64*256, это было бы значительно логичнее и сложные трансляции (см. ниже) пришлось бы включать при размере в 4 раза больше.)

Пример решения с трансляциями в BIOS для Quantum Fireball 1.2G. Геометрия диска, видимая на шине — 2484*16*63, что дает 1.28 "коротких" G. BIOS, видя количество цилиндров больше чем 1024, включал режимы ретрансляции: если установлен режим LARGE, то геометрия показывалась 1242*32*63; если LBA — то 621*64*63. Только вариант, выбранный для LBA трансляции, был пригоден для использования всего диска в MS-DOS и других системах, использующих BIOS в качестве драйвера. Группа прерываний BIOS "int 13h" использовалась в любом случае в DOS, но при установке такого режима, BIOS производил трансляцию геометрии, полученной в вызовах группы INT 13h, в ту, которая сообщалась диском, или же в абсолютный номер блока, если такое поддерживалось диском (см. ниже).

Начиная с дисков размером около 4GB, установилась практика транслировать при выборе LBA трансляции в фиктивную геометрию с 255 головками и 63 секторами. Режим в 256 головок решили не применять из-за ограничений используемого софта (много таких программ, которые воспринимали 0 в поле как 0, а не как положенное 256). Эта трансляция используется и поныне, хотя в 1024 цилиндра новые диски давно уже не вмещаются даже при ней.

(Точный механизм вычисления так называемой LBA-геометрии, если точнее — LBA-assist геометрии, следующий. Полное количество блоков диска, полученное из ответа команды Identify Device, делилось на 1024*63. (Поправка: на mossywell написано, что деление на 1024 было с округлением вверх, то есть не x/1024, а 1+(x-1)/1024. Это нельзя свести к такому же округлению при делении на 1024*63.) Если частное было 255 или больше, количество головок в геометрии устанавливалось 255. Если меньше, происходило округление вверх до ближайшего числа из следующего набора: 16, 32, 64, 128, 255. Разделив количество блоков диска на 63 и на подобранное количество головок и округлив ответ вниз до целого, получали количество цилиндров в итоговой LBA-assist геометрии. Если оно было более 1024, часть диска уже не могла адресоваться через старые (геометрические) вызовы BIOS и требовала линейной адресации.)

Отметим, что от декларирования шинной геометрии с количеством секторов больше 63 отказались (вплоть до перехода 32G границы — см. ниже) из-за желания получить все ту же совместимость с BIOS и MSDOS даже при выборе режима трансляции NORMAL (то есть без трансляции вообще). Решение вполне обоснованное — до того, как загрузчик сможет загрузить драйвер, умеющий это обходить, потребуется загрузить очень много другого и наверняка с секторов с абсолютными номерами больше чем 63.

Одновременно с введением ретрансляции средствами BIOS или специальных драйверов было начато предоставлять возможность отказаться от CHS адресации вообще для тех, кто на это способен. В частности, для многих unix систем, не использующих MSDOS partitioning вообще, это было избавлением от бессмысленного промежуточного уровня. Аналогично начала работать и Windows NT (а позднее — Windows 95OSR2, 98 и ME, но только в protected режиме). Это состояло из двух интерфейсов:

Здесь LBA адресация (не путать с LBA трансляцией!) означает Linear Block Access — доступ к блокам диска по их линейному (абсолютному) номеру, а не по фиктивной комбинации C/H/S. В современных BIOSʼах, она может использоваться и для LBA трансляции.

В ATA-6 появилась поддержка 48-битной LBA адресации, кроме прежней 28-битной. Она используется для дисков объемом более 128G. (Для сравнения, BIOS вызовы группы d-134X изначально поддерживают 64 бита номера блока.)

Барьер 1024 цилиндров — барьер ограничений BIOS и MSDOS — не преодолевается старыми средствами BIOS; для его преодоления нужны как минимум функции группы d-134X (по номенклатуре Ральфа Брауна). Для BIOSʼов, не умеющих ретрансляцию геометрии, он наступил на границе 504(528)MB; диски объемом больше чем этот граничный нельзя использовать в полном объеме для MSDOS и наследников, если BIOS не поддерживает ретрансляцию геометрии или поддерживает ее иначе, чем тот, на котором диск был форматирован на логическом уровне (записана partition table). Если BIOS поддерживает стандартную LBA ретрансляцию, то этот барьер наступает при достижении диском размера 8G.

Барьер 8G — барьер 1024 цилиндров при выборе LBA ретрансляции в BIOSʼе. Предельный адресуемый размер диска средствами старых вызовов BIOS и при стандартной интерпретации MSDOS partition table — 1024*255*63 блока, или 8.422 GB.

Преодоление барьера в 1024 цилиндра потребовало ряда специальных мер. Так как BIOS не дает использовать CHS адресацию для цилиндров более 1024, ОС вынуждены использовать LBA адресацию — через вызовы d-134X или через свой драйвер — или же производить ретрансляцию в шинную геометрию своими силами, но тоже через свой драйвер, потому что BIOS этого не позволяет. (Но второй вариант реально не использовался, все ведущие производители заложились на доступ по линейному адресу.) Загрузочные разделы, при использовании старого загрузчика в MBR, не могут выходить за границы первых 1024 цилиндров. В MSDOS partition table потребовались специальные меры для обозначения разделов за пределами первых 1024 цилиндров, потому что стандартные обозначения непригодны. Для этого были взяты поля записей, которые ранее всегда писались, но не использовались MSDOS и потомками: абсолютный адрес начала раздела и абсолютная длина размера; оба — в блоках диска и 32 бита (то есть перестанут удовлетворять по достижению объема диска в 2TB). В старые поля (C,H,S) стали писаться фиктивные параметры: или правильный C/H/S адрес начала (конца), но с цилиндром обрезанным выше младших 10 битов, или специальное значение 1023/head_max/sector_max (чаще всего 1023/254/63). Чтобы избежать конфликта со старыми правилами понимания partition table, были введены новые типы разделов:

- для которых интерпретируются только абсолютные адрес начала и длина. Для систем, иных, чем DOS/Win9x/WinME, проблема опознания границ раздела была изначально решена в пользу абсолютных номеров (это относится к WinNT, Linux, FreeBSD и так далее), поэтому для их разделов новый тип не требовался.

Барьер 32G (для некоторых дисков он был при немного меньшем объеме) - барьер в 65536 цилиндров для шинной геометрии. Как сказано выше, для шинной геометрии пределом считалось — 16 головок и 63 сектора (а не 256 и не 255, потому что вмешивается совместимость с BIOS и загрузчиками). Для дисков больше чем 32G потребовалось рапортовать более чем 65536 цилиндров, например, для IBM IC35L040AVER07 (40G) это 79780*16*63, при том, что LBA геометрия в этом случае — 5005*255*63. Превышение границы в 65536 цилиндров дало два эффекта:

Немного о других границах (в порядке убывания) и проблемах от их пересечения.

С 2010-2011 года появилась проблема в виде увеличения фактического размера физического сектора на диске; производители договорились на хранение секторами по 4KB. (Об этом говорилось также в начале статьи, тут описывается ещё набор последствий.) При этом (на начало 2012) размер того, что называется "блоком" на шине, осталось, у большинства производителей, байт (фактически, отраслевое соглашение сошлось на том, что логический размер блока 4KB допускается только для "серверных" дисков). Вследствие этого, запись одного такого блока шины приводит к тому, что диск должен прочитать сектор с диска, изменить его часть, и записать заново. Одиночные операции с блоками такого размера становятся существенно дороже и медленнее. Операционным системам настоятельно рекомендуется узнавать фактический размер блока на диске и просить операции чтения/записи размером не менее физического блока и с соответствующим выравниванием. В интерфейсах (ATA и SCSI) предусмотрен метод получить эти данные — размер физического блока и граница выравнивания.

Начиная с этого момента, меняются требования к разбиению диска на разделы. Если до Advanced Format нормальным было то, что раздел с файловой системой начинается с блока 63 (потому что для совместимости с MS-DOS начало соответствует 0:1:1), то по новому требованию эта граница должна быть кратна 8 512-байтным блокам. Практически основные ОС устанавливают выравнивание на границу мегабайта (2048 таких блоков). Для Windows, например, такая разметка стала обычной начиная с версии 7. Некоторые производители (например, Western Digital) предусматривают режим совместимости (устанавливаемый переключателем на диске) для случая старой ОС с разделом от блока 63 (тогда физическому блоку соответствуют не 0-7,8-15,...,56-63,64-71..., а 0-6,7-14,...,55-62,63-70...)

Что у нас на 2024 год? Фактически, все описанные проблемы ушли (повторю с суммированием то, что упомянуто в начале статьи):

Итого, все геометрические особенности ушли в историю. Возможно ещё ожидать каких-то последствий на старом оборудовании или не на x86, но мне крайне слабо верится.




Ссылки по теме:



(C) 2002-2005,2012,2015,2024 Valentin Nechayev. License: CC BY-SA 4.0.
Разрешается полное или частичное копирование, цитирование. При полном или частичном копировании ссылка на оригинал обязательна.