![загрузчик ядра в эмуляторе qemu](https://ulteam8.ru/wp-content/uploads/2019/11/booting.png)
Добрый день, уважаемые читатели. В статье я расскажу про процесс включения компьютера с процессором на базе архитектуры x86 и про загрузчик ядра. Как только электричество подалось на плату в оперативную память загружается специальная программа, хранящаяся в ПЗУ, под названием BIOS. Эта аббревиатура расшифровывается Basic Input Output System или, если на русском языке, базовая система ввода-вывода.
BIOS выполняет несколько задач:
- Проверка оборудования
- Настройка оборудования
- Предоставление программных интерфейсов для работы с оборудованием
- Загрузка ядра операционной системы
Пропустим три пункта и сразу перейдем к последнему.
Сначала, конечно, BIOS должна найти загрузчик операционной системы на всех указанных носителях и в порядке очереди. Упростим ситуацию и будем считать, что из устройств у нас есть только один диск.
Для определения что диск является загрузочным система читает первый сектор (цилиндр 0, головка 0, сектор 0).
![схема устройства жесткого диска](https://ulteam8.ru/wp-content/uploads/2019/11/dvip02-140.png)
Размер сектора равен 512 байт. Если 511 байт равен 0x55, а 512 – 0xAA, то значит данный диск загрузочный. После этого BIOS передает управление на адрес начала, загруженного сектора. 0x55AA – магическое число!
(Я всегда знал, что без магии не обошлось!!!)
![загрузчик ядра в машинных кодах](https://ulteam8.ru/wp-content/uploads/2019/11/machine_code.png)
Это простейший загрузочный сектор в машинных кодах. Трудновато читать. Покажу как этот код выглядит в ассемблере:
; Бесконечный цикл (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
Ура! Получилось. Наше ядро здоровается со всем миром:
![загрузчик ядра говорит привет](https://ulteam8.ru/wp-content/uploads/2019/11/hello_world.png)