Я написал загрузчик и перевел его, используя fasm для загрузки написанного ядра. Я запускаю все это через qemu, используя команду "qemu -fda bootsect.bin -fdb kernel.bin". В этом случае qemu говорит, что «Загрузка с дискеты .... Загрузка не удалась: не загрузочный диск». В чем причина?
Код bootsect.asm
use16
start:
cli
mov ax, cs ; Сохранение адреса сегмента кода в ax
mov ds, ax ; Сохранение этого адреса как начало сегмента данных
mov ss, ax ; И сегмента стека
mov sp, start ; Сохранение адреса стека как адрес первой инструкции этого кода. Стек будет расти вверх и не перекроет код.
sti
load_drive:
mov ax, 0x1000
mov es, ax
mov ax, 0x0
mov al, 0x18 ; sum of sectors to read
mov dl, 0x01 ; number of drive
mov dh, 0x00 ; number of head
mov ch, 0x00 ; number of track(cylinder)
mov cl, 0x01 ; number of sector
mov ah, 0x02 ; function for int 0x13
int 0x13 ; read data from 0x1000
enable_protected_mode:
cli ; off interrupts
lgdt [gdt_info] ; Загрузка размера и адреса таблицы дескрипторов
in al, 0x92 ; Включение адресной линии А20
or al, 0x02
out 0x92, al
mov eax, cr0 ; Установка бита PE регистра CR0 - процессор перейдет в защищенный режим
or al, 0x01
mov cr0, eax
jmp 0x8:protected_mode ; "Дальний" переход для загрузки корректной информации в cs
use32
protected_mode:
mov ax, 0x10 ; Загрузим регистры DS и SS селектором сегмента данных
mov es, ax
mov ds, ax
mov ss, ax
call 0x10000
gdt:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdt_info:
dw gdt_info - gdt
dw gdt, 0
times (512 - ($ - start) - 2)
db 0x55, 0xAA
Код kernel.asm
use32 ; 32-битный код
org 0x10000 ; Адрес, по которому будет загружен этот код загрузчиком ядра
mov edi, 0xb8000
mov esi, str_hello
call video_puts
; В регистр edi помещается адрес начала буфера
; В регистр esi помещается адрес начала строки
; Вызывается функция для видеовывода в буфер
infinite_loop:
; Перевод процессора в бесконечный цикл
hlt
jmp infinite_loop
video_puts:
; Функция выводит в буфер видеопамяти (передается в edi) строку,
; После завершения edi содержит адрес по которому можно продолжать
mov al, [esi]
test al, al
jz video_puts_end
mov ah, 0x07 ; Цвет символа и фона. Возможные варианты: 0x00 is
;black-on-black, 0x07 is lightgrey-on-black, 0x1F is white-on-blue
mov [edi], al
mov [edi+1], ah
add edi, 2
add esi, 1
jmp video_puts
video_puts_end:
ret
str_hello:
db "Welcome to HelloWorldOS (asm edition)!", 0