§ Устройство MBR

Начнем с того, что бутсектор должен располагаться в MBR. Дело в том, что после разметки диска, начиная с 446-го байта и заканчивая 512-м, на диске уже есть разметка 4 primary разделов. По этой причине, код бутсектора для диска (hd) а не флоппи (fd), должен быть не более 446 байт. Это очень важно. Сам же код сектора загружается биосом по адресу 0000h:7C00h (CS=0000h, IP=7C00h) в реальном режиме работы процессора. Это так всегда происходит. Наша задача что-то сделать с этим.
000 Программный код бут загрузчика
1BE Дескриптор 1-го раздела диска (16 байт)
1CE Дескриптор 2-го раздела диска (16 байт)
1DE Дескриптор 3-го раздела диска (16 байт)
1EE Дескриптор 4-го раздела диска (16 байт)
1FE Сигнатура 0xAA55 (или 55h AAh)
Сама же структура раздела такая
00 1 Признак активности раздела
01 1 Начало раздела — головка
02 1 Начало раздела — сектор (биты 0—5), цилиндр (биты 6, 7)
03 1 Начало раздела — цилиндр (старшие биты 8, 9 хранятся в байте номера сектора)
04 1 Код типа раздела
05 1 Конец раздела — головка
06 1 Конец раздела — сектор (биты 0—5), цилиндр (биты 6, 7)
07 1 Конец раздела — цилиндр (старшие биты 8, 9 хранятся в байте номера сектора)
08 4 Смещение первого сектора
0C 4 Количество секторов раздела
В современных дисках головка, сектор и цилиндр вообще ни к чему. К тому же, даже смещение или первого сектора количество секторов на диске, описанных через 4 байта, может быть не таким большим. Ну сколько он может быть? Допустим, сектор занимает 512 байт, а максимально адресуемый размер диска получится 2^32*2^9 = 2^41 байт. Так как 1 гигабайт = 2^30 байт, то тогда 2^41/2^30 = 2^11 гигабайт (2048 Гб), что равно 2 терабайта. Сейчас диски есть на 4 Тб, какой там 2 Тб. И вот как с этим справляется наш герой? Все на просмотр картины второй! (Шутка) На самом деле для больших дисков используется GPT-механизм, который только в UEFI есть, а в старом BIOS этого нет. Никто не знал, что 4Тб диски вообще будут в природе. Но поскольку мои диски более 512 Гб не особо превышают, то мне норм.

§ Обновление сектора

Я думаю, что нужно написать простой makefile для обновления сектора
all:
	rm -f *.lock
	fasm boot.asm
	dd conv=notrunc if=boot.bin of=disk.img bs=446 count=1
	bochs -f c.bxrc -q > /dev/null 2>&1
Сначала удаляются лок-файлы, если они были, потом ассемблируется файл boot.asm, далее с помощью утилиты dd заменяются первые 446 байта на диске и запускается bochs.
Сам же код boot.asm максимально прост:
        org     7C00h
        cld     ; На всякий случай
        sti     ; Чтобы реагировал на CTRL+ALT+DEL
        xor     ax, ax
        mov     ds, ax
        mov     es, ax
        mov     ss, ax
        mov     sp, 7C00h
        jmp     $
В этом коде просто устанавливаются сегментные регистры в 0 и стек ставится под кодом бут-сектора.
Напишу Hello World, используя функцию BIOS INT 10h
        mov     si, ab    ; Ссылка на строку
@@:     mov     ah, 0Eh   ; 0Eh печать символа в терминале
        lodsb             ; Загрузка символа из DS:SI
        and     al, al    ; Проверка AL на 0
        je      $         ; Если 0, остановить процессор
        int     10h       ; Напечатать символ
        jmp     @b        ; Перейти к следующему

ab:     db "Hello World",0
Чтобы выгрузить данный бут-сектор на реальную флешку, можно воспользоваться такой командой
sudo dd conv=notrunc if=boot.bin of=/dev/sdX bs=446 count=1
Где /sdX - это устройство флешки, например, sdd или sde, это надо узнать через команду df -h, там будет выведен список подключенных устройств.
Я вот проверил свой код, все работает хорошо.
2 окт, 2020
© 2007-2022 Жесть в том, что Алиса плывет под водой