Виктор Костромин - Linux для пользователя
Как вы знаете, при включении компьютера вначале запускается программа POST (Power On Self Test). Она определяет количество доступной памяти, тестирует ее, определяет наличие других компонент (клавиатура, винчестер…), инициализирует карты адаптеров. На экране обычно появляются сообщения о количестве памяти, о ее тестировании, перечень обнаруженных устройств (гибкие и жесткие диски, процессор, COM-порты и т. д.).
После завершения тестирования POST вызывает Int 19h, которое пытается найти загрузочное устройство. Поиск производится в том порядке, который определен в Setup BIOS, и осуществляется путем опроса нулевых секторов соответствующих устройств. Если диск является загрузочным, то в его нулевом секторе находится главная загрузочная запись - Master Boot Record (MBR). Последние два байта MBR - это "магическое число", которое является признаком того, что данный сектор есть MBR, а, следовательно, диск является загрузочным. Кроме "магического числа" MBR содержит таблицу разделов диска, о которой уже было сказано выше, и маленькую программу - первичный загрузчик, объемом всего 446 (0x1BE) байт.
В табл. 2.1 представлена структура главного загрузочного сектора, создаваемого при инсталляции Windows.
Таблица 2.1. Структура главного загрузочного сектора.
Смещение Содержание 0x000 Код первичного загрузчика 0x1BE Таблица разбиения диска 0x1FE "Магическое число" (0xAA55)MS-DOS, Windows95 и NT записывают DOS MBR при инсталляции. Стандартное для MS содержимое MBR можно также записать командой fdisk /mbr.
Но вернемся к описанию процесса загрузки. Прерывание 19h BIOS загружает первичный загрузчик в память компьютера и передает управление этой программе. Но такой маленькой программе не под силу загрузить ОС; все, что она может сделать - это загрузить в память более мощную программу - вторичный загрузчик.
Для этого она ищет в таблице разделов активный раздел и считывает в память вторичный загрузчик, который располагается начиная с первого логического сектора активного раздела. Обратите внимание на слово "начиная". Дело в том, что вторичный загрузчик в разных системах имеет разную длину.
В разделе, отформатированном под файловую систему FAT, вторичный загрузчик занимает один сектор (512 байт). В разделе, отформатированном под файловую систему NTFS, вторичный загрузчик занимает уже несколько секторов.
Вторичный загрузчик загружает первый слой программ, необходимых для запуска операционной системы. В случае MS DOS программа-загрузчик загружает IO.SYS по адресу 700h, затем MSDOS.SYS и передает управление разделу SYSINIT модуля IO.SYS.
Если по каким-либо причинам на диске не найден активный раздел, процесс загрузки продолжается обработкой прерывания 18h. Эта ветвь реально используется очень редко, но такая возможность может быть очень полезна в некоторых ситуациях. При удаленной загрузке, когда операционная система загружается с сервера, это прерывание перенаправляется программой POST на ROM сетевой карты.
Для других ОС от Microsoft процесс загрузки происходит аналогично
• Windows95 загружается так же, как и DOS, но заменяет IO.SYS и MSDOS.SYS своими файлами. Файлы DOS сохраняются под именами IO.DOS и MSDOS.DOS соответственно. Когда вы выбираете загрузку сохраненного DOS, Windows95 переименовывает свои файлы в файлы с расширением w40 и восстанавливает первоначальные имена системных файлов DOS. Процесс продолжается с загрузки DOS-овского IO.SYS. Таким образом, загрузочные сектора DOS и Windows95 одинаковые.
• Windows NT4 использует MBR DOS, но заменяет загрузочную запись активного раздела таким образом, что вместо IO.SYS загружается NTLDR. Это уже мощная программа, которая многое может сделать. В частности, она находит файл boot.ini и, если параметр timeout больше 0, предлагает меню загрузки.
Каждая строка секции [operating systems] файла boot.ini определяет один из вариантов загрузки и строится по следующему шаблону
адрес_вторичного_загрузчика="название_варианта"
Адресом вторичного загрузчика может являться указание на конкретный раздел диска или на файл загрузчика. Вот пример файла boot.ini:
[operating systems]
multi(0)disk(0)rdisk(0)partition(3)WINNT="Windows NT Workstation 4.00 RUS"
multi(0)disk(0)rdisk(0)partition(3)WINNT="Windows NT Workstation 4.00 RUS [VGA mode]" /basevideo /sos
C:="Microsoft Windows"
C:BOOTSECT.LNX="Linux"
Если пользователь выбирает NT, то выполняется загрузка по адресу раздела, указанному в первой строке раздела. В строке, соответствующей Microsoft Windows, указан просто диск "C:", так как имя загрузочного файла берется по умолчанию: bootsect.dos. Файл грузится в память и загрузка продолжается так, как если бы загрузочная запись раздела была загружена программным кодом из MBR.
Для загрузки других систем можно воспользоваться таким же приемом. Для этого в boot.ini нужно добавить строки, содержащие ссылки на другие загрузочные файлы. При выборе такой строки будет загружаться соответствующая ОС. В приведенном выше примере этим способом обеспечивается загрузка Linux. Для этого в файле C:BOOTSECT.LNX должно быть предварительно записано содержимое загрузочной записи, создаваемой Linux (точнее - LILO, стандартным загрузчиком Linux).
2.3.4. Проблемы с большими дисками
В MS-DOS и первых версиях Windows доступ к дискам был организован через прерывание 13 (Int 13h) BIOS (в том числе на этапе начальной загрузки ОС). При этом использовалась адресация секторов на диске на основе указания номеров цилиндра, головки и сектора на дорожке (C/H/S). Точнее:
• AH - выбор операции;
• CH - младшие 8 бит номера цилиндра;
• CL - 7-6 биты соответствуют старшим битам номера цилиндра, 5-0 биты соответствуют номеру сектора;
• DH - номер считывающей головки;
• DL - номер диска (80h или 81h).
(Заметим в скобках, что нумерацию физических цилиндров и дорожек принято начинать с 0, а сектора на дорожке нумеруют, начиная с 1). Однако практически головок было не более 16-ти, а число секторов на дорожке - не более 63, и хотя для указания цилиндра использовалось 10 бит, все равно BIOS не мог работать с дисками объемом более 1024*63*16*512 = 528 Мбайт.
Для преодоления этого ограничения стали применять разные хитрые приемы (подробнее об этом вы можете узнать из [П4.2]). Например, Extended CHS (ECHS) или "Large disk support" (иногда обозначается просто как "Large") использует еще три незанятых бита номера головки для увеличения числа адресуемых цилиндров. Это позволило использовать "фальшивую геометрию диска" в 1024 цилиндра, 128 считывающих головок и 63 сектора/дорожку. Трансляцию Extended CHS в реальный CHS-адрес (который может иметь до 8192 цилиндров) осуществляет BIOS. Это позволяет работать с дисками, объемом до 8192*16*63*512 = 4 227 858 432 байт или 4,2 Гбайт.
Но разработчики все увеличивали плотность записи на диск, число пластин и дорожек, изобретали другие способы увеличения объема дисков. В частности, число секторов на дорожках стало разным (на более длинных дорожках, расположенных ближе к краю пластин, число секторов стали увеличивать). В результате три числа C/H/S уже перестали правильно отражать "геометрию диска", а старые версии BIOS перестали обеспечивать доступ ко всему дисковому пространству.
Тогда придумали другой прием для работы с большими дисками через Int 13h - линейную адресацию блоков ("Linear Block Addressing" или LBA). Если не вдаваться в подробности, то можно сказать, что все сектора на диске нумеруются последовательно, начиная с первого сектора на нулевой дорожке нулевого цилиндра. Вместо CHS-адреса каждый сектор получает логический адрес - просто его порядковый номер в общем массиве секторов. Нумерация логических секторов начинается с нуля, причем нулевой сектор содержит главную загрузочную запись (MBR). В Setup BIOS поддержка преобразования линейного номера в CHS-адрес обозначается как "поддержка LBA". Таким образом, в новых версиях BIOS обычно имеется выбор из трех вариантов: "Large", "LBA" и "Normal" (последнее означает, что трансляция адресов не производится).
Но и в режиме LBA обращение к физическому диску все равно осуществляется через функции Int 13h, которые используют 3D нотацию (C,H,S). В силу этого возникает ограничение на возможный объем диска: BIOS, и, следовательно, MS-DOS и ранние версии Windows, не могли адресовать диски объемом более 8,4 Гбайт.
Надо заметить, что указанное ограничение относится только к дискам с интерфейсом IDE. В контроллерах SCSI-дисков номер сектора переводится в команды SCSI, а далее сам диск находит нужную позицию, поэтому такого ограничения на объем диска не возникает.
Еще раз хочется отметить, что все перечисленные ограничения существенны только на этапе загрузки ОС, поскольку сама Linux и последние версии Windows при работе с дисками уже не используют прерывание 13 BIOS, а используют собственные драйвера для работы с дисками. Но, прежде чем система сможет использовать собственный драйвер, она должна как минимум его загрузить. Поэтому на этапе начальной загрузки любая система вынуждена пользоваться BIOS. Это и вызывает ограничения на размещение многих систем за пределами 8 Гбайт, они не могут оттуда загружаться, хотя после успешной загрузки могут работать с дисками гораздо большего объема. Для того, чтобы понять, как можно обойти эти ограничения, нам потребуются некоторые знания о том, как происходит загрузка ОС Linux.