Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Исследуем процесс загрузки Linux

(C) В.А.Костромин, 2007
(версия файла от 16.12.2007 г.)


Назад Оглавление Вперед

Этап 2: Master Boot Record и Boot Record

Итак, BIOS нашел загрузочное устройство и передал управление программе, которая находилась в самом первом секторе этого диска или дискеты (физический адрес: цилиндр 0, головка 0, сектор 1). Теперь эта программа загружена в память и именно она управляет ходом дальнейшей загрузки. Со времен MS-DOS эту программу принято называть загрузочной записью (Boot Record), а первый сектор любого диска или дискеты - загрузочным сектором (Boot Sector).

Примечание: На всех стандартно отформатированных дискетах, даже на тех, которые не являются загрузочными, Boot Sector содержит исполняемый код. Этот код необходим хотя бы для выдачи на экран информационого сообщения. Текст этого сообщения различается в зависимости от того, в какой операционной системе форматировалась дискета. В MS-DOS это было сообщение "Non-system disk or disk error" (вероятно знакомое вам). Жесткий диск, отформатированный в NT (несистемный), сообщал "NTLDR is missing".

Как известно, размер сектора на устройствах долговременного хранения данных для IBM-совместимых компьютеров равен всего-навсего 512 байтам. В принципе существует возможность записать в эти 512 байт программу, обеспечивающую загрузку ядра операционной системы. Как сказано в книге Т.Айвазяна [8], существует три варианта загрузки ядра Linux:

  • с помощью загрузочного сектора Linux, загружающего непосредственно ядро (этот загрузочный сектор подробно рассмотрен в [8]);
  • с помощью специального загрузчика типа LILO или GRUB;
  • с помощью программ, загружающих Linux из другой ОС (например, MS-DOS или Windows), типа loadlin и т.п.

    Мы будем далее рассматривать только второй вариант, как наиболее распространенный.

    С появлением жестких дисков большого объема, которые стали разбивать на разделы, небольшой загрузчик, размещаемый в загрузочном секторе и загружающий непосредственно ядро, перестал справляться с возросшим объемом задач. Ведь теперь надо было не просто загрузить файл с определенного физического адреса, а вначале найти загрузочный раздел. К тому же часть места, отведенного для загрузочной записи, отняла таблица разделов жесткого диска. Поэтому старая загрузочная запись была перенесена в первый сектор так называемого "активного" раздела, а в самый первый сектор на жестком диске стали записывать другую программу, задачей которой было найти "активный" раздел и загрузить программу из этого раздела. Первый сектор жесткого диска стали называть главным загрузочным сектором (а соответствующую программу - главной загрузочной записью или Master Boot Record, MBR). На жёстком диске MBR находится по тому же физическому адресу, что и BOOT-сектор на дискете (цилиндр 0, сторона 0, сектор 1). Его структура представлена в табл. 1

    Таблица 1. Структура главного загрузочного сектора.

    Смещение

    Размер

    Содержание

    0x000

    446 байт

    Главная загрузочная запись (Master Boot Record)

    0x1BE

    64 байта

    Таблица разбиения диска

    0x1FE

    2 байта

    "Магическое число" (0x55AA)

    "Магическое число" 0x55AA, как мы уже знаем, является признаком того, что диск является загрузочным. Содержащаяся в MBR такого диска таблица разбиения определяет 4 первичных раздела жесткого диска (подробнее о ее устройстве вы можете прочитать в статье [9]). А первые 446 байт MBR содержат небольшую программу (которая нас в данный момент интересует), а также текст сообщений об ошибках, которые могут возникнуть в ходе ее выполнения.

    Основная задача главной загрузочной записи состоит в том, чтобы найти и загрузить в оперативную память собственно загрузчик операционной системы. MBR сканирует таблицу разделов (partition table) в поисках первого (обычно он и единственный) активного раздела (раздела, помеченного как "загрузочный"). Если в таблице разделов активный раздел не обнаружен или хотя бы один раздел содержит неправильную метку, а также если несколько разделов помечены как активные, выдаётся соответствующее сообщение об ошибке. Когда активный раздел найден, программа считывает в оперативную память первый сектор активного раздела.

    Примечания: 1. Ход дальнейших действий несколько различается в зависимости от того, с какого устройства считан этот сектор. Мы сейчас будем рассматривать только "основную" ветку - когда первым обнаруженным загрузочным устройством оказался жесткий диск и загрузка производится с него. Варианты загрузки с дискеты, CD-ROM или flash-диска пока не рассмотриваются. Если будет время и желание, я вернусь к этому вопросу позже, в отдельном разделе.

    2. Задание таблицы разделов в MBR (как и использование стандартных BIOS) уже давно ограничивает возможности операцтонных систем. Поэтому фирма Intel разработала Extensible Firmware Interface (EFI, Расширяемый Микропрограммный Интерфейс) - стандарт, призванный придти на смену отжившего свой век PC BIOS. Частью этого стандарта является GPT призван стать стандартным форматом размещения таблицы разделов на физическом жестком диске. Частью этого стандарта является GUID Partition Table (GPT) - новый формат таблицы разделов жесткого диска. GPT призван стать стандартным форматом размещения таблицы разделов на физическом жестком диске. Подробнее о GPT читайте в заметке "GUID Partition Table (новая таблица разделов)". Однако в настоящем обзоре EFI не рассматривается, мы будем исследовать традиционный способ загрузки ОС с использованием MBR, который пока что преодладает в реальной жизни.

    3. Поскольку загрузочная запись каждого диска содержит исполняемый код, сохраняется возможность заражения загрузочными вирусами компьютера, на котором установлена ОС Linux. Главная загрузочная запись имеет один и тот же формат для всех PC-совместимых компьютеров. И если эта программа содержит код, который считывает самый последний сектор жесткого диска и выполняет содержащийся в нем код, а затем заставляет систему выполнить код из первого сектора активного раздела, вы вряд ли заметите сразу, что что-то идет не так, как надо. Вирусы, которые ведут себя подобным образом, принято называть "загрузочными", именно потому, что они размещаются в загрузочной записи и могут нанести какой-то вред вашей системе только в том, случае, если вы попытаетесь загрузиться с зараженного диска. Этот тип вируса может воздействовать на любой PC-совместимый компьютер. Некоторые типы компьютеров (точнее, некоторые типы BIOS) обеспечивают защиту от данного вида вирусов тем, что запись в загрузочный сектор может быть запрещена. Однако эта мера позволяет защититься только от старых типов загрузочных вирусов, поскольку более новые научились изменять CMOS, разрешая запись в MBR. Что касается Linux-компьютеров, то опасность "подцепить" загрузочный вирус существует только в том случае, если по какой-то причине начинается загрузка с дискеты (скорее всего, случайно оставленной в дисководе). То есть, необходимо быть внимательным и при включении компьютера позаботиться о том, чтоб в дисководе не было дискет.

    Практически все загрузчики современных операционных систем состоят из двух частей: загрузчика первого этапа (или первичного загрузчика), который имеет достаточно малый размер, чтобы разместиться в загрузочном секторе, и значительно большего по объему загрузчика 2-го этапа (или вторичного загрузчика), который может храниться уже где угодно на загрузочном носителе, обычно в разделе, содержащем корневую файловую систему. Загрузчик первого этапа может быть размещен как в главном загрузочном секторе диска, так и в загрузочном секторе активного раздела. Если вам приходилось устанавливать Linux, вы знаете, что программа инсталляции предоставляет пользователю такой выбор. Будем пока для определенности считать, что загрузчик 1-го этапа мы поместили в первый сектор активного раздела.

    Итак, главная загрузочная запись отыскала активный раздел и загрузила из него в память загрузчик первого этапа, который теперь отвечает за продолжение процесса загрузки. Загрузчик первого этапа имеет такой же небольшой размер, как и код загрузочной записи диска, то есть не более 446 байт. Поэтому и сделать он может не больше, а именно - только загрузить основной загрузчик. Еще более затрудняет ситуацию то, код загрузчика первого этапа пока не имеет доступа к файловой системе и, следовательно, определяет расположение программ на диске, используя только информацию о физических секторах и низкоуровневые вызовы BIOS. Поэтому эта крохотная программа имеет единственной целью своего существования загрузку и запуск на выполнение загрузчика второго этапа.

    (Если вы не хотите читать приводимое ниже дополнение про загрузку в NT, то вперед...).


    Дополнение. В случае, когда первичный загрузчик от Linux установлен не в MBR, а в загрузочный сектор одного из разделов, в MBR, скорее всего осталась программа первичной загрузки, создаваемая программой FDISK от Microsoft. Поэтому приведу в качестве дополнения описание того, как работает первичный загрузчик Windows-систем (заимствованное из статьи [5]), которое помогает понять, как происходит процесс загрузки.

    Код, содержащийся в главной загрузочной записи, выполняет следующие действия:

    • сканирует таблицу разделов (partition table) в поисках первого (обычно он и единственный) активного раздела (раздела, помеченного как "загрузочный"). Если в таблице разделов активный раздел не обнаружен или хотя бы один раздел содержит неправильную метку, а также если несколько разделов помечены как активные, выдаётся соответствующее сообщение об ошибке;
    • когда активный раздел найден, программа запоминает его физическое размещение на диске, используя запись в соответствующей строке таблицы разделов диска;
    • затем программа первичного загрузчика перемещает свой код по адресам от 0600 до 07FF (если вы помните, первоначально она размещалась по смещению 7C00) и продолжает выполняться оттуда;
    • код загрузочного сектора раздела (это уже код загрузчика файловой системы, размещенной в этом разделе) загружается в память по смещению 7C00 (до 7DFF).
    • управление передается загрузчику файловой системы (по адресу 7C00).

    В MS DOS программа из загрузочного сектора активного раздела просматривает блок параметров BIOS в поисках расположения корневого каталога, а затем копирует из него в память системный файл IO.SYS (который, по сути, является частью DOS) и передаёт ему управление.

    В системе Windows NT код из загрузочного сектора активного раздела ищет расположение на диске файла NTLDR, делая это следующим образом:

    • Ищет блок параметров BIOS (the BIOS Parameter Block) и расширенный блок параметров BIOS (Extended BIOS Parameter block). Использует эти данные для того, чтобы найти NTLDR на первом ("загрузочном") диске.
    • Загружает NTLDR в память.
    • Запускает его.

    Если NTLDR не найден, выдается сообщение "Could not find NTLDR".

    Обратите внимание! Местоположение NTLDR ищется на первом диске, даже если код загрузочного сектора хранится на другом диске (что может иметь место в тех случаях, когда используется MBR не от Microsoft). Хотя это выглядит достаточно просто, следствием того факта, что NTLDR ищется на первом диске, является то, что если вы пытаетесь установить NT на второй диск и процедура инсталляции не находит на первом диске свободного места для установки загрузочного сектора, файла NTLDR и других файлов (что может иметь место, если на первом диске уже установлена другая ОС, которую NT не может распознать), будет выдано примерно такое сообщение об ошибке: "xxxx MB disk0 at id0 on bus0 on atapi does not contain a partition suitable for starting Windows NT". (Для SCSI-дисков слова немного отличаются, но суть та же). Это сообщение можно перевести на более понятный язык примерно следующим образом: "Были использованы данные из блока параметров BIOS, но загрузка с того раздела диска, на который указывает ссылка, невозможна".



    Назад Оглавление Вперед