Добрый день, уважаемые читатели. В статье я расскажу про процесс включения компьютера с процессором на базе архитектуры x86 и про загрузчик ядра. Как только электричество подалось на плату в оперативную память загружается специальная программа, хранящаяся в ПЗУ, под названием BIOS. Эта аббревиатура расшифровывается Basic Input Output System или, если на русском языке, базовая система ввода-вывода.
BIOS выполняет несколько задач:
- Проверка оборудования
- Настройка оборудования
- Предоставление программных интерфейсов для работы с оборудованием
- Загрузка ядра операционной системы
Пропустим три пункта и сразу перейдем к последнему.
Сначала, конечно, BIOS должна найти загрузчик операционной системы на всех указанных носителях и в порядке очереди. Упростим ситуацию и будем считать, что из устройств у нас есть только один диск.
Для определения что диск является загрузочным система читает первый сектор (цилиндр 0, головка 0, сектор 0).
Размер сектора равен 512 байт. Если 511 байт равен 0x55, а 512 – 0xAA, то значит данный диск загрузочный. После этого BIOS передает управление на адрес начала, загруженного сектора. 0x55AA – магическое число!
(Я всегда знал, что без магии не обошлось!!!)
Это простейший загрузочный сектор в машинных кодах. Трудновато читать. Покажу как этот код выглядит в ассемблере:
; Бесконечный цикл (e9 fd ff) loop: jmp loop ; Заполнить (510 - размер предыдущего кода) байт нулями times 510-($-$$) db 0 ; Магическое число dw 0xAA55
Комментарии очевидны и говорят сами за себя. Программа при запуске, загрузчик ядра покажет экран, примерно похожий на тот, который в заголовке статьи. После этого зависнет.
Отлично! Может быть стоит сделать что-нибудь более интересное. Например поздороваться со всем миром! 🙂 Программисты очень любят это делать.
org 0x7c00 mov bx, HELLO start: mov al, [bx] cmp al, 0 je done mov ah, 0x0E int 0x10 add bx, 1 jmp start done: jmp $ HELLO: db 'Hello, World!', 0 times 510 - ($-$$) db 0 dw 0xAA55
Количество строк увеличилось, но сложности, по существу, это не добавило. Посмотрим что делает этот код.
В регистр bx помещается адрес первого символа текстовой строки. Я пометил ее меткой HELLO. Далее идет цикл. В начале проверяется достигли ли мы конца строки. Конец строки это символ с кодом 0. Если это не конец строки, тогда надо вывести очередной символ. Вывод осуществляется с помощью прерывания BIOS — 0x10. В конце увеличиваем регистр bx на единицу.
Теперь нужно скомпилировать проект. Это делается в командной строке с помощью Nasm:
nasm -fbin boot_hello.asm -o boot_hello.bin
Запускаем полученный файл: boot_hello.bin в эмуляторе qemu
qemu-system-i386 boot_hello.bin
Ура! Получилось. Наше ядро здоровается со всем миром: