§ Загрузка BIOS

И вот как раз именно после всех инициализации, условно будем называть это биосом (efi, uefi, bios, у него куча разных названий сейчас появилось), вызывает первый сектор (Master Boot Record, если не по-нашему) с какого-нибудь диска, даже с сети может, неважно, и укладывает этот сектор адресу в памяти 0000h : 7C00h. Понятное дело, что размер сектора равен 512 байтам. Попробуй развернись в этом количестве байт и сделай что-то! Нет, находятся умельцы, которые и кубы крутят, и шахматы мутят.
§ Что делать дальше
Чем заняться после загрузки в память? Конечно, надо что-то инициализировать, как же без инициализации, все инициализируют, а я что, хуже что ли? Я тоже буду.org 7C00h ; Указываем ассемблеру, что код начинается с 7C00h cli ; IF=0 теперь прерывания не вызываются cld ; DF=0 теперь все lods/movs/stos/etc возрастают xor ax, ax ; AX=0000 mov ds, ax ; DS=0000 mov es, ax ; ES=0000 mov ss, ax ; SS=0000 mov sp, 7C00h ; SP=7C00 ; ... остальной код ... times (7C00h-$)+510 db 255 ; Заполнить FFh оставшиеся 510 байт dw 0xAA55 ; Сигнатура бутсектораЗамечу, что если у бутсектора не будет в конце сектора 2 байта с сигнатурой
55 AA
, то такой бутсектор будет считаться биосом не бутсектором, а мусором и ничего он не загрузит.А где же
CS=0000
? Он и так ноль, так что все в порядке. После инициализации, конечно, интересно узнать, а как же этот бутсектор записать, чтобы он вообще как-нибудь заработал? И вот тут начинаются проблемы вселенского масштаба.Как и обычно, надо ассемблер включить. Он всегда находится под рукой и называется flat assembler. Очень удобный.
После сложных установок, настроек, калибровки, интеграции и инкапсуляции в хост-систему, можно будет написать приблизительно такой запускной файл, например, makefile:
fasm boot.asm boot.binС помощью этого набора команд будет сформирован новый файл
boot.bin
, в котором и будет содержаться бутсектор.§ Отладчик bochs
Про этот отладчик я узнал очень давно, еще когда сидел наwindows xp
, а не в линуксе, как сейчас, и потому пользоваться я им, конечно, не научился толком, но кое-что загружать получалось. Как настроить отладчик, я уже сто раз писал везде где ни попадя. Настраиваю я его под winxp, конечно же. А как же линукс? Какой еще линукс? Нет никакого линукса, есть винда и она навсегда.Проблема следующая. Файловую систему разметить с помощью винды мне не удастся, потому придется изобретать свои велосипеды на языке программирования
php
, чем далее я и буду заниматься после того, как бутсектор напишу.Для того, чтобы загрузить сектор, надо диск создать. Утилита bximage в этом мне поможет хотя бы:
- Тип диска — hd
- Способ записи — flat
- Количество мегабайт — 256 (сойдёт для сельской местности)
- Имя диска — c.img
"c.img", mode=flatata0-master: type=disk, path=Поэтому эту строку можно добавить в файл конфигурации c.bxrc.
megs: 32 romimage: file=c:/bochs/BIOS-bochs-latest vgaromimage: file=c:/bochs/VGABIOS-lgpl-latest ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=disk, path="c.img", mode=flat, biosdetect=auto, translation=auto boot: c display_library: win32, options="gui_debug" log: bochsout.txt mouse: type=ps2, enabled=0, toggle=ctrl+mbutton cpu: ips=15000000 clock: sync=both keyboard: keymap=c:/bochs/keymaps/x11-pc-us.map magic_break: enabled=1Тут есть зависимая конфигурация keymap, если она находится в другом месте, надо поправить путь. Тут есть такая опция как
magic_break
, если она активирована, то отладчик будет останавливаться на инструкции xchg bx,bx
что просто крайне полезно, потому что без этого отладка почти что невозможна.Запускать этот файл надо так (предварительно в makefile какой-нибудь оформить или bat-файл):
bochsdbg -f c.bxrc -qЯ сейчас проверил, у меня все заработало. Конечно, чтобы это все заработало, надо, чтобы все было правильно настроено. Без точной настройки ничего работать не будет.
§ Как запустить загрузчик
Есть несколько идей, как это сделать. Первая — велосипедом, вторая... не знаю. Придется велосипедом. Создам файлmain.cc
, например:#include <stdlib.h> #include <stdio.h> int main(int argc, char* argv[]) { return 0; }Компилировать известно как:
g++ main.cc -o bootwriter
. Должно заработать. Makefile будет выглядеть примерно так:all: $(NAME) fasm boot.asm boot.bin $(NAME): main.cc g++ main.cc -o $(NAME) strip $(NAME)NAME=bootwriter.exe То есть, если нет файла bootwriter.exe, то он его создает. На линуксе это может и не будет работать, не проверял — страшно.
Вопрос такой — как нарисовать сову? Делается очень легко! Сначала сделайте два кружочка. Если два кружочка готовы, нарисуйте сову целиком. Сова готова! Следующий код для
main.cc
будет это правило демонстрировать:unsigned char buf[512] = {0}; if (argc < 3) return -1; // Аргументов должно быть 2 // Открыть файл на чтение и второй файл на запись FILE* fr = fopen(argv[1], "rb"); FILE* fw = fopen(argv[2], "rb+"); // Если один из них открыть не удалось if (fr == NULL || fw == NULL) return -2; // Прочесть и записать 446 байт (не 512!) fread(buf, 1, 446, fr); fwrite(buf, 1, 446, fw); // Подготовить 55 AA и записать в последние 2 байта первого сектора buf[0] = 0x55; buf[1] = 0xAA; fseek(fw, 510, SEEK_SET); fwrite(buf, 1, 2, fw); // Закрыть файлы fclose(fr); fclose(fw);Что делает этот код?
$(NAME) boot.bin c.imgЕсли его запустить так, то код перепишет первые 446 байт в первый сектор и запишет сигнатуру, чтобы биос распознал этот сектор. Вот теперь можно уже попробовать написать что-нибудь, например, Hello World, в самом main.asm:mov si, Hello ; Ссылка на строку Hello @@: lodsb ; Загрузка нового символа в AL and al, al ; Проверить AL на 0 je $ ; Если 0, то остановить процессор mov ah, 0Eh ; AH=0Eh код печати символа int 10h ; Печать символа jmp @b ; Повтор Hello: db "Hello World",0Осталось только скомпилировать и запустить. У меня все нормально получилось.

Самое главное в программировании, это конечно, написать "HELLO WORLD". Если этого не будет, то зачем тогда программировать?
Файл как обычно, можно скачать: hello-world.zip