Ошибка загрузчика начальной загрузки и ядра

Мы работаем над проектом, чтобы научиться писать ядро ​​и изучить все тонкости. У нас есть загрузчик начальной загрузки, и он, похоже, работает. Однако у нас проблема с загрузкой ядра. Начну с первой части:

bootloader.asm:

    [BITS 16]
    [ORG 0x0000]
;
;    all the stuff in between
;
;    the bottom of the bootstrap loader

     datasector  dw 0x0000
     cluster     dw 0x0000
     ImageName   db "KERNEL  SYS"
     msgLoading  db 0x0D, 0x0A, "Loading Kernel Shell", 0x0D, 0x0A, 0x00
     msgCRLF     db 0x0D, 0x0A, 0x00
     msgProgress db ".", 0x00
     msgFailure  db 0x0D, 0x0A, "ERROR : Press key to reboot", 0x00

     TIMES 510-($-$$) DB 0
     DW 0xAA55

     ;*************************************************************************

Файл bootloader.asm слишком длинный для редактора, но при этом он не захлебывается. Кроме того, загрузчик и ядро ​​работают в bochs, поскольку мы получаем сообщение «Добро пожаловать в нашу ОС». В любом случае, на данный момент у нас есть следующее ядро.

kernel.asm:

[BITS 16]
[ORG 0x0000]

[SEGMENT .text]         ; code segment
    mov     ax, 0x0100          ; location where kernel is loaded
    mov     ds, ax
    mov     es, ax

    cli
    mov     ss, ax          ; stack segment
    mov     sp, 0xFFFF          ; stack pointer at 64k limit
    sti

    mov     si, strWelcomeMsg       ; load message
    call        _disp_str

    mov     ah, 0x00
    int     0x16                ; interrupt: await keypress
    int     0x19                ; interrupt: reboot

_disp_str:
    lodsb                       ; load next character
    or      al, al          ; test for NUL character
    jz      .DONE

    mov     ah, 0x0E            ; BIOS teletype
    mov     bh, 0x00            ; display page 0
    mov     bl, 0x07            ; text attribute
    int     0x10                ; interrupt: invoke BIOS

    jmp     _disp_str

.DONE:
    ret

[SEGMENT .data]                 ; initialized data segment
    strWelcomeMsg   db  "Welcome to our OS",    0x00

[SEGMENT .bss]              ; uninitialized data segment  

Используя nasm 2.06rc2, я компилирую как таковой:
nasm bootloader.asm -o bootloader.bin -f bin
nasm kernel.asm -o kernel.sys -f bin

Записываем на дискету bootloader.bin так:
dd if=bootloader.bin bs=512 count=1 of/dev/fd0

Записываем на дискету kernel.sys вот так:
cp kernel.sys /dev/fd0

Как я уже сказал, это работает в bochs. Но загрузившись с дискеты, мы получаем такой вывод:

Загрузка оболочки ядра
...........
ОШИБКА: нажмите клавишу для перезагрузки

Прочие особенности: OpenSUSE 11.2, рабочий стол GNOME, AMD x64. Любую другую информацию, которую я мог пропустить, не стесняйтесь спрашивать. Я старался собрать здесь все, что может понадобиться. Если мне нужно, я могу найти способ разместить где-нибудь весь файл bootloader.asm. Мы также не заинтересованы в использовании GRUB по нескольким причинам. Это может измениться, но мы хотим, чтобы эта загрузка прошла успешно, прежде чем мы действительно рассмотрим GRUB.

РЕДАКТИРОВАТЬ: Загрузчик начальной загрузки должен иметь 512 байт, записанных в загрузочный сектор (самый первый сектор) диска. Поверьте, загрузчик скомпилирован на 512 байт. Предполагается, что ядро ​​находится в следующем секторе.


person IAbstract    schedule 28.03.2010    source источник
comment
Я очень сомневаюсь, что вы действительно имеете в виду cp kernel.sys /dev/fd0, который с самого начала перезаписал бы дискету. Даже если вы его не вставляете, можете ли вы описать, откуда ваш загрузчик должен загружать ядро ​​в память?   -  person ephemient    schedule 28.03.2010
comment
Ну да, я именно это имел в виду. Это пример, который мне дали для копирования файла на устройство. Должно быть иначе? Я новичок в Linux - я использую Windows с версии 3.0.   -  person IAbstract    schedule 28.03.2010
comment
Ваш dd записывает один сектор bootloader.bin в первый сектор дискеты. Затем ваш cp копирует kernel.sys прямо на дискету, перезаписывая это ... возможно, вы имеете в виду dd seek=1, чтобы начать размещение kernel.sys во втором секторе дискеты? Нужна дополнительная информация о загрузчике, чтобы определить, хотите ли вы этого.   -  person ephemient    schedule 28.03.2010


Ответы (1)


Если вы хотите, чтобы kernel.sys начинался со второго сектора, используйте это вместо cp.

dd if=kernel.sys of=/dev/fd0 bs=512 seek=1

Или, если предположить, что bootloader.bin составляет ровно 512 байт, это тоже работает:

cat bootloader.bin kernel.sys > /dev/fd0
person ephemient    schedule 28.03.2010
comment
bootloader.bin точно 512 байт ... команда cat... поместит bootloader.bin в сектор 0 (загрузочный сектор) ??? - person IAbstract; 28.03.2010
comment
Он начнется с начала необработанного устройства (Linux удобен и позволяет неблокирующий доступ к блочным устройствам), которое действительно является сектором 0. - person ephemient; 28.03.2010
comment
Судя по всему, это проблема с записью в /dev/fd0. Очевидно, что даже с предоставленными вами образцами файл kernel.sys не записывается. Когда я создаю образ дискеты, он возвращает файл образа размером 1,4 Мб; однако на самом деле с помощью начальной загрузки записываются только первые 512 байтов. На образе отсутствует kernel.sys. - person IAbstract; 29.03.2010
comment
Я собираюсь пойти дальше и отметить это как ответ, потому что я думаю, что это все, что я могу, ТАК с этим. Думаю, остальную проблему придется решать на SU. - person IAbstract; 29.03.2010