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

Сигнал сброса заставляет процессор начать работу с одного жёстко заданного адреса

В момент подачи питания блок питания и материнская плата ждут, пока напряжение на всех линиях стабилизируется, и только после этого снимают сигнал RESET с процессора. До этого момента ядро физически заблокировано и не выполняет никакого кода. Как только сигнал снят, процессор архитектуры x86 переходит в реальный режим и обращается по фиксированному адресу FFFFFFF0h, это шестнадцать байт до границы четырёх гигабайт адресного пространства. Регистр CS получает видимое значение F000h, а IP выставляется в FFF0h, но обычная арифметика реального режима, умножение CS на шестнадцать и сложение с IP, дала бы адрес в границах первого мегабайта, а не нужные почти четыре гигабайта. Адрес FFFFFFF0h получается за счёт скрытой части регистра CS, теневой базы, в которую при аппаратном сбросе процессор принудительно записывает значение FFFF0000h, и именно она в сумме с FFF0h даёт итоговый адрес. Как только выполняется первый дальний переход, эта теневая база сбрасывается до обычной, и адресация возвращается в пределы мегабайта. По этому адресу лежит не сама прошивка, а короткая инструкция перехода, которая передаёт управление в основной код BIOS или UEFI, физически расположенный в микросхеме SPI флеш-памяти на материнской плате. Чипсет платы декодирует это обращение процессора и перенаправляет его именно на флеш-чип, а не на оперативную память, которая на этой стадии ещё даже не инициализирована.

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

Сразу после перехода в код прошивки начинается процедура POST, Power On Self Test. Она последовательно проверяет процессор, контроллер памяти, видеоподсистему и базовые шины ввода-вывода. На современных платах с UEFI этот этап делится на две фазы: PEI, инициализация процессора, памяти и чипсета, и DXE, среда исполнения драйверов, где параллельно активируются остальные компоненты платы, включая контроллеры накопителей и сетевые адаптеры. Именно на фазе PEI происходит тренировка памяти, определение реальных тайминг задержек модулей ОЗУ, что на некоторых платах с разогнанной памятью может занимать заметную часть общего времени включения. Если проверка обнаруживает критическую неисправность, например отсутствие модулей памяти, прошивка останавливает процесс и подаёт код ошибки через звуковой сигнал динамика или через светодиодный индикатор POST-кодов на самой плате, и до операционной системы дело в таком случае просто не доходит.

Прошивка ищет загрузочное устройство и читает таблицу разделов диска

После успешного самотестирования прошивка обращается к списку устройств, помеченных как загрузочные в её настройках. Для старой схемы BIOS это означает чтение нулевого сектора диска, который называется MBR, Master Boot Record. Этот сектор занимает ровно 512 байт и содержит таблицу из четырёх разделов, а также флаг активного раздела, с которого и должна начаться загрузка. Современные системы работают иначе: UEFI не выполняет код из MBR вообще, вместо этого используется таблица разделов GPT, поддерживающая до ста двадцати восьми основных разделов и диски объёмом более двух терабайт, а сам загрузчик находится на отдельном разделе ESP, EFI System Partition, отформатированном в FAT32. На этом разделе по стандартному пути хранится исполняемый файл загрузчика операционной системы, и именно к нему прошивка обращается напрямую, минуя классическую схему с загрузочным сектором.

Код из первого сектора диска получает управление и передаёт эстафету дальше

На платах с BIOS происходит момент, который обычно и называют загрузкой с загрузочного сектора в узком смысле слова. Прошивка через прерывание INT 13h копирует в оперативную память по физическому адресу 0x7C00 весь нулевой сектор целиком, все 512 байт, и передаёт туда управление. Из них первые 446 байт это исполняемый машинный код загрузчика, а оставшиеся 66 байт занимают таблица разделов и сигнатура 55AAh, подтверждающая, что сектор действительно загрузочный. Таблица разделов при этом остаётся в памяти по смещению 0x01BE от начала блока, и именно туда обращается код загрузчика, чтобы определить активный раздел. Задача этого крошечного фрагмента кода предельно узкая: найти активный раздел и передать управление коду в его первом секторе, который называется VBR, Volume Boot Record, или загрузочным сектором раздела. Именно здесь начинается код, специфичный для конкретной операционной системы, и для Windows этот код указывает на следующий, куда более крупный компонент.

Диспетчер загрузки Windows выбирает операционную систему по данным конфигурации

Следующим в цепочку вступает диспетчер загрузки Windows, файл bootmgr на дисках с MBR или bootmgr.efi на разделе ESP при UEFI. Этот компонент читает хранилище данных конфигурации загрузки, BCD, файл со структурой, похожей на куст реестра, который заменил собой старый текстовый boot.ini из прежних версий Windows. В BCD записано, какие версии операционной системы установлены на диске, где физически расположены их файлы и какие параметры загрузки нужно применить, включая режим восстановления или безопасный режим при необходимости. Если на компьютере несколько установленных систем или профилей загрузки, именно диспетчер выводит меню выбора, а затем передаёт управление следующему модулю, отвечающему уже непосредственно за запуск ядра выбранной системы. Если компьютер перед этим уходил в спящий режим, вместо обычного загрузчика диспетчер вызывает отдельный модуль восстановления сохранённого состояния из файла гибернации.

Загрузчик операционной системы проверяет подписи драйверов и запускает ядро

Дальше в дело вступает файл winload.exe, которого на дисках с UEFI соответствует winload.efi. Он последовательно решает три задачи: загружает в память образ ядра ntoskrnl.exe, подгружает библиотеку абстрагирования оборудования HAL, отвечающую за низкоуровневую работу с конкретной платформой, и инициализирует минимальный набор драйверов, без которых система физически не может продолжить старт, включая драйвер файловой системы и контроллера накопителя. На этом же этапе, если в прошивке материнской платы включена функция Secure Boot, происходит криптографическая проверка цифровой подписи каждого загружаемого компонента, а при наличии модуля TPM дополнительно измеряется и сверяется хэш состояния загрузки, что не даёт запустить систему с изменённым или заражённым загрузочным кодом. Порядок ключевых участников этой цепочки можно свести к короткому списку:

  1. MBR или GPT определяет структуру дисковых разделов и активный раздел;
  2. VBR или загрузчик на разделе ESP передаёт управление коду операционной системы;
  3. bootmgr, он же диспетчер загрузки, читает BCD и выбирает систему для запуска;
  4. winload.exe загружает ядро, HAL и стартовые драйверы, проверяя их подписи;
  5. ntoskrnl.exe принимает управление и инициализирует собственно ядро системы.

Ядро принимает управление и запускает первые процессы пользовательского пространства

С момента, когда управление получает ntoskrnl.exe, заканчивается собственно загрузочная часть и начинается инициализация полноценной операционной среды. Ядро настраивает диспетчер памяти, планировщик потоков и объектный менеджер, после чего запускает системный процесс smss.exe, отвечающий за создание среды сеанса и подготовку подсистемы Win32. Далее стартует csrss.exe, обслуживающий графическую подсистему, и winlogon.exe, который выводит экран приветствия или сразу переходит к рабочему столу, если включён автоматический вход. Именно на этом отрезке пользователь впервые видит анимацию логотипа или крутящийся индикатор загрузки, хотя к этому моменту процессор, прошивка, загрузочный сектор и диспетчер загрузки уже успели выполнить основную и куда менее заметную часть работы. Всё, что описано выше, от снятия сигнала сброса до передачи управления ядру, на современном железе с твердотельным накопителем и включённым быстрым запуском укладывается в интервал от одной до трёх секунд, а на старых механических дисках с классическим BIOS этот же путь может растянуться на десять и более секунд именно из-за медленного механического позиционирования головок при чтении первых секторов.

Скорость прохождения всей описанной цепочки напрямую зависит от того, сколько раз системе приходится физически обращаться к накопителю. Каждое такое обращение на механическом жёстком диске означает время на позиционирование головки, обычно от пяти до пятнадцати миллисекунд, тогда как твердотельный накопитель отвечает на запрос за доли миллисекунды. Путь от MBR до ntoskrnl.exe включает как минимум четыре-пять отдельных чтений: сам загрузочный сектор, VBR, диспетчер загрузки, файл BCD и сам загружаемый образ ядра с драйверами. На механическом диске эти пять обращений суммарно могут добавить к общему времени старта до полусекунды-секунды только на позиционирование, не считая времени на само чтение данных. Дополнительно на скорость влияет объём проверок Secure Boot: чем больше компонентов подписано и чем длиннее цепочка доверия, тем больше криптографических операций нужно выполнить прошивке до передачи управления следующему звену, хотя современные процессоры справляются с этим за единицы миллисекунд благодаря аппаратному ускорению операций с ключами.

В Windows 8 и всех последующих версиях по умолчанию включена функция быстрого запуска, которая заметно меняет описанную выше последовательность при обычном выключении компьютера. При закрытии сеанса система не завершает работу ядра полностью, а переводит сессию пользователей в состояние выхода, сохраняя при этом образ ядра, драйверов и состояния оборудования в файл hiberfil.sys на системном разделе. При следующем включении диспетчер загрузки видит специальный флаг в BCD и вместо полной цепочки winload.exe и ntoskrnl.exe вызывает модуль winresume.exe, который просто разворачивает сохранённый образ обратно в оперативную память, минуя повторную инициализацию всех драйверов с нуля. Именно поэтому на одном и том же ноутбуке холодный запуск после полного выключения из настроек BIOS ощутимо дольше, чем обычное выключение кнопкой в меню Пуск с последующим включением, хотя пользователю оба сценария выглядят одинаково как выключение и включение. Полное отключение этой функции через команду powercfg -h off убирает файл hiberfil.sys целиком и возвращает систему к честной полной загрузке при каждом включении, что иногда используют для диагностики проблем именно на этапе инициализации железа.

Отдельного внимания заслуживает то, как прошивка сообщает о статусе каждого шага самотестирования. На большинстве материнских плат для настольных компьютеров распаян отдельный двухразрядный семисегментный индикатор или набор светодиодов, отображающих шестнадцатеричный код текущего этапа POST, от 00 до FF. Каждому диапазону значений соответствует конкретный узел: коды в районе 0x10-0x2F обычно связаны с инициализацией процессора и кэша, диапазон около 0x50-0x6F чаще всего указывает на память, а коды ближе к 0x90-0xA0 обычно означают инициализацию видеоадаптера и передачу управления его собственной прошивке. Если процесс останавливается и код зависает на одном значении дольше нескольких секунд, это надёжный признак аппаратной неисправности именно того узла, за который отвечает этот диапазон кодов, и такая диагностика оказывается быстрее, чем последовательная замена компонентов методом исключения. На платах без отдельного индикатора о характере неисправности сообщает последовательность коротких и длинных звуковых сигналов динамика, набор которых различается между производителями прошивок.

Если в настройках прошивки в качестве первого загрузочного устройства указана сетевая карта, обращение к MBR или разделу ESP локального диска вообще не происходит. Вместо этого сетевой контроллер отправляет широковещательный запрос по протоколу PXE, Preboot Execution Environment, и получает в ответ от сервера в локальной сети IP-адрес и путь к загрузочному образу, который затем скачивается по упрощённому протоколу передачи файлов TFTP и выполняется точно так же, как выполнялся бы код из VBR обычного диска. Этот механизм массово применяется при развёртывании операционной системы сразу на большое количество компьютеров в организациях, когда установочный образ не нужно переносить на каждую машину физически. Сам факт, что цепочка от диспетчера загрузки и до передачи управления ядру остаётся идентичной вне зависимости от источника загрузочного кода, локального диска или сети, показывает, насколько чётко разделены между собой этап поиска загрузочного носителя и этап собственно запуска операционной системы.

Эта цепочка выстраивалась десятилетиями и почти не менялась в своей логике: сначала аппаратный сброс и проверка железа, затем поиск загрузочного кода, затем передача управления по цепочке всё более крупных и всё более осведомлённых о конкретной операционной системе компонентов. Понимание этой последовательности пригождается не только из любопытства: именно на этих этапах возникают типичные проблемы вроде отсутствия загрузочного устройства, повреждённого BCD или конфликта режимов Secure Boot при переустановке системы, и зная, какой именно компонент за что отвечает, такие неполадки диагностируются в разы быстрее, чем при переустановке системы наугад.