Написал загрузчик с ext2. С драйвером фс проблем нет, всё в порядке. Но
загрузить систему не получается. Загрузчик поделён на две части: первая
находится в MBR, она грузит два сектора с начала указанного ей раздела. Там
в ext2fs выделено место для второго загрузчика. Второй представляет из себя
примерно такую вещь:
/* монтирование файловой системы */
/* открытие файла /boot/cmdline */
/* чтение одного блока и копирование 255 байт в 0x9900:0 */
/* открытие файла /boot/vmlinuz */
// здесь уже поподробнее:
mov si, vmlinuz+0x7c00 ; в ds 0
call fopen
mov bx, 0xa00 ; сегмент, куда читать
xor eax, eax
call read_file_block
xor ah, ah
mov byte al, [0xa000+0x1f1] ; setup_sects
inc al
/* итак, setup_sects+1 находится в ax. дальше идёт чтение этих секторов в 0x9000:0 */
/* Дальше выставляем нужные переменные (некоторые ставить необязательно, я
пробовал убирать, но это, по-моему, не так важно) */
mov bx, 0x9000
push ds
mov ds, bx
mov ax, 0xfffd
mov word [0x1fa], ax ; video mode
mov byte [0x210], ah ; type_of_loader
mov al, 0x81
mov byte [0x211], al ; loadflags
mov ax, 0x9000-0x200
mov word [0x224], ax ; heap_end_ptr
mov eax, 0x99000
mov dword [0x228], eax ; cmd_line_ptr
mov eax, 0x100000
mov dword [0x214], eax ; code32_start - пробовал ставить 0x18, как
написано в /usr/src/linux/Documentation/i386/boot.txt, но не помогло; пока
оставил 0x100000
pop ds
/* сдесь высчитывается, сколько блоков надо прочитать на 64 килобайта и
сохраняется в памяти */
pop ax ; в стеке было сохранено setup_sects+1
shl ax, 5 ; ax *= 0x20
mov bx, 0x1000
sub bx, ax
mov word [0x8019], bx ; в [0x8019] сохраняется 0x1000-(количество
16-битных кусков на setup и bootsector). Это сегмент, куда будет читаться ядро.
Такой подсчёт требуется для того, чтобы не читать real-mode часть ядра в high
memory; функция move перемещает 64K-куски в high mem из 0x1000:0
xor eax, eax ; чтение с нулевого сектора
xor cx, cx ; счётчик
reading_the_kernel:
call read_file_block
inc cx
inc eax
cmp word cx, [0x8017]
jz read64K
add word bx, [0x8015]
jmp short reading_the_kernel
read64K:
pushad
call 0x7c0:move ; это вместо int 0x15
popad
cmp eax, edx ; в edx подсчитано количество блоков
jae allread
mov word bx, [0x8019]
xor cx, cx
jmp short reading_the_kernel
allread:
mov ax, 0x9000
mov ss, ax
mov sp, 0x9000
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp 0x9020:0
Всё, при попытке загрузить идёт перезагрузка. Драйвер фс проверен! Я
посмотрел setup, перезагрузка идёт уже после прыжка в 0:0x100000.
В чём же проблема?
PS: Если кому-нибудь интересно, могу привести код полностью.