Как написать свой BIOS: полное руководство

Прежде чем приступить к написанию собственного BIOS, важно понять: это не тот проект, который можно завершить за один вечер. Ошибка в коде на раннем этапе приводит к нерабочей материнской плате, которую придется восстанавливать программатором. Начинать стоит не с написания кода, а с выбора подходящей архитектуры и изучения документации чипсета вашей платы — без этого любой код превратится в бесполезный набор инструкций.

Современный BIOS (или UEFI) — это сложная система инициализации оборудования, которая включает десятки модулей: от работы с памятью до загрузки операционной системы. Однако написать минимально рабочую версию, способную инициализировать процессор, память и вывести сообщение на экран, — задача реальная. Для этого потребуется компилятор C или ассемблер, документация Intel/AMD по архитектуре и утилиты для прошивки микросхемы SPI Flash.

Выбор архитектуры и инструментов для разработки

Для старта рекомендуется выбрать классический подход с использованием ассемблера NASM и языка C с кросс-компилятором GCC. Это позволяет контролировать каждую инструкцию и точно понимать, что происходит в каждый момент времени. Альтернативный путь — использовать открытый проект coreboot, который предоставляет каркас для создания собственной прошивки, но он требует глубокого понимания устройства платформы.

Вам понадобятся следующие инструменты:

  • 🛠️ Кросс-компилятор i686-elf-gcc для сборки кода без зависимости от системных библиотек
  • 📝 Ассемблер NASM для написания загрузочного сектора и низкоуровневых процедур
  • 🔗 Линкер-скрипт, который правильно разместит секции кода и данных в образе прошивки
  • 💾 Программатор CH341A или аналогичный для записи результата на микросхему SPI Flash
  • 📖 Документация Intel Platform Controller Hub (PCH) для вашего чипсета

Не пытайтесь сразу писать код для современной платформы. Начните с эмулятора QEMU, который поддерживает отладку BIOS через порт отладки и позволяет тестировать код в безопасной среде. Только после того как прошивка стабильно работает в эмуляторе, можно думать о переносе на реальное железо.

⚠️ Внимание: прошивка непроверенного кода на реальную материнскую плату может навсегда вывести её из строя. Всегда имейте резервную копию оригинальной прошивки и программатор для её восстановления.

Структура минимального BIOS

Минимальная прошивка должна выполнять несколько обязательных шагов: переход в 32-битный защищенный режим, настройка сегментных регистров, инициализация контроллера памяти и вывод символов на экран через порт VGA. Для этого достаточно около 512 байт кода, если не учитывать таблицы и данные.

Типичная последовательность инициализации выглядит так:

  • 🔍 Выключение прерываний командой cli и сброс флага направления cld
  • ⚙️ Переход в защищенный режим через установку бита PE в регистре CR0
  • 📐 Загрузка глобальной таблицы дескрипторов (GDT) с корректными сегментами
  • 🖥️ Настройка видеорежима через порты VGA (обычно режим 0x03 — 80x25 текст)
  • 🚀 Вывод приветственного сообщения в видеобуфер по адресу 0xB8000

Начните с простого: заставьте код выводить один символ на экран. Затем добавьте очистку экрана, затем — строку текста. Каждый этап тестируйте отдельно в QEMU, используя make для автоматизации сборки и запуска.

; Пример вывода символа в QEMU

mov ax, 0xB800

mov es, ax

mov byte [es:0], 'H' ; символ

mov byte [es:1], 0x07 ; атрибут (белый на черном)

☑️ Чек-лист перед началом разработки BIOS

Выполнено: 0 / 5

Инициализация памяти: критический этап

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

В QEMU этот этап пропускается, так как эмулятор автоматически настраивает память. Поэтому для реального железа лучше использовать готовые библиотеки инициализации от проекта coreboot или AGESA (для платформ AMD). Самостоятельная инициализация DDR4/DDR5 требует знания десятков спецификаций и занимает месяцы работы.

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

📊 С чего вы планируете начать разработку BIOS?
С изучения ассемблера и архитектуры
С использования готового coreboot
С написания загрузочного сектора в QEMU
С покупки программатора и изучения железа

Работа с прерываниями BIOS

Классические прерывания int 10h, int 13h и int 16h — это наследие 16-битного режима. Если вы пишете современный 32-битный или 64-битный BIOS, эти прерывания недоступны без переключения в реальный режим. Однако для совместимости с загрузчиками операционных систем (например, GRUB) вам придется реализовать их эмуляцию или использовать специальный интерфейс.

На практике для загрузки ОС достаточно реализовать функцию чтения секторов с диска и передать управление загрузчику. В UEFI это делается через протоколы EFI_DISK_IO и EFI_LOADED_IMAGE_PROTOCOL. В классическом BIOS — через прерывание int 13h с параметрами в регистрах.

Отладка прошивки без реального железа

QEMU предоставляет мощные средства отладки BIOS: порт отладки 0x402 для вывода сообщений, возможность подключения GDB к процессору и логирование всех операций ввода-вывода. Используйте эти возможности на каждом этапе разработки.

Для вывода отладочной информации в QEMU достаточно записать байт в порт 0x402, и он появится в консоли эмулятора. Это аналог printf, но работающий без драйверов и инициализации.

Метод отладки Инструмент Уровень сложности
Порт 0x80 (POST-коды) Любой анализатор Низкий
Порт 0x402 (QEMU) Консоль QEMU Низкий
GDB-отладка GDB + QEMU Средний
Логирование I/O QEMU с опцией -d Высокий

Обязательно настройте систему сборки с автоматическими тестами. Скрипт, который собирает прошивку, запускает QEMU и проверяет вывод в порт 0x402, сэкономит вам часы ручной работы. Такой подход позволяет быстро выявлять регрессии при изменении кода.

Прошивка на реальную плату: риски и меры предосторожности

Когда код стабильно работает в QEMU, можно думать о реальном железе. Однако перед этим убедитесь, что у вас есть: исправный программатор CH341A с переходником под вашу микросхему, полная резервная копия оригинальной прошивки и документация по расположению контактов SPI Flash на вашей материнской плате.

Процесс прошивки включает несколько обязательных шагов:

  • 📸 Создание резервной копии текущей прошивки минимум в двух экземплярах
  • 🔌 Отключение питания и извлечение батарейки CMOS
  • 🧲 Снятие микросхемы SPI Flash (если она в корпусе DIP-8) или подключение к контактным площадкам
  • 💾 Запись нового образа с помощью flashrom или утилиты от производителя программатора

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

⚠️ Внимание: никогда не прошивайте BIOS на ноутбуке без возможности извлечь микросхему. В большинстве современных ноутбуков SPI Flash распаяна на плате, и восстановление требует пайки или специального адаптера с прижимными контактами.

Переход к UEFI: современный подход

Классический BIOS устарел, и для новых платформ (Intel 6-го поколения и новее) его поддержка отсутствует. Если вы хотите написать прошивку для современного компьютера, изучайте спецификацию UEFI 2.x и используйте открытую реализацию EDK II от Intel. Это огромный фреймворк, но он предоставляет готовые драйверы для большинства чипсетов.

UEFI работает в 64-битном режиме и использует протоколы вместо прерываний. Это усложняет разработку, но открывает доступ к современным возможностям: Secure Boot, драйверам для NVMe и графического вывода с высоким разрешением. Написание полноценного UEFI-приложения — это отдельная большая тема, которая требует знания C и структуры PE-файлов.

Спойлер

Что такое DXE-фаза в UEFI:Фаза DXE (Driver Execution Environment) — это этап загрузки, на котором выполняются драйверы устройств. Каждый драйвер — это PE-образ, который загружается в память и регистрирует свои протоколы. Именно в этой фазе инициализируются контроллеры USB, SATA и видеокарты.

FAQ: частые вопросы о написании BIOS

Сколько времени занимает написание минимального BIOS?

Минимальная прошивка, которая инициализирует процессор, память и выводит сообщение на экран, занимает от недели до месяца при условии, что вы уже знаете ассемблер и архитектуру x86. Полноценный BIOS с поддержкой дисков и загрузкой ОС — это 6-12 месяцев работы.

Можно ли использовать Rust для написания BIOS?

Да, Rust поддерживает разработку без стандартной библиотеки (no_std), и существуют проекты, использующие его для UEFI-приложений. Однако для классического BIOS на ассемблере и C пока больше готовых примеров и документации.

Что делать, если после прошивки система не запускается?

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

Чем BIOS отличается от UEFI?

BIOS работает в 16-битном режиме, использует прерывания и имеет ограничение на загрузку дисков объемом до 2 ТБ. UEFI работает в 64-битном режиме, использует протоколы и поддерживает современные файловые системы и Secure Boot.

Написание собственного BIOS — это глубокое погружение в архитектуру x86, которое дает уникальное понимание работы компьютера. Начните с малого: загрузочный сектор в QEMU, затем — инициализация видеовыхода, затем — чтение секторов с диска. Каждый этап приближает вас к полноценной прошивке. Главное — не торопиться и всегда иметь план восстановления для реального железа.

Для закрепления материала попробуйте модифицировать существующий открытый BIOS для виртуальной машины и проследить, как изменения в коде влияют на поведение системы. Этот практический опыт ценнее любого теоретического руководства.