Bootloader Странное поведение - PullRequest
7 голосов
/ 12 марта 2012

Я пытался разработать простую ОС, только загрузочный сектор и 16-битный реальный режим с прерываниями.Я наконец-то смог создать OS / bootloader, который я тестировал в виртуальной коробке, и он заработал.

Затем я записал образ на CD и загрузил его на свой старый рабочий стол с Pentium 4., BIOS ревизии A05 и 1 ГБ ОЗУ, и она работала отлично - простая ОС, которая печатает «заголовок» в верхней части экрана, все, что она позволяет печатать на экране, с несколькими зарегистрированными клавишами для навигациикурсор.

Затем я подключил диск к своему 1-летнему ноутбуку с процессором i5, 2,6 ГБ ОЗУ и ревизией A05 BIOS, и курсор, кажется, перемещается случайным образом, печатая случайные символы навысокие скорости, в конце концов остановка на символе 235 anscii (часть расширенной таблицы символов), после чего клавиатура работает нормально, клавиши, предназначенные для перемещения курсора, работают нормально, только заголовок.Это компьютер, на котором я его тестировал, компилировал, писал и записывал компакт-диск.(Я использовал ОС Linux Mint 12)

Я перепрыгнул через все «обручи», которые, как мне казалось, мне нужно было сделать: сделал ISO-образ, соответствующий стандарту загрузки El Torito «без эмуляции», подпись загрузки, 512байт и записывается в правильный сектор.

Это проблема с моим кодом, я что-то не сделал или это просто нормально?

Вот мой код (синтаксис NASM x86):

    ;**************************
    ; Note OS, Experimental OS
    ;**************************
    [org 0x7C00]
    [bits 16]
    start:
    jmp loader                           ;jump to the actual start of bootloader
    times 8 - ($ - $$) db 0          ;pad eight bytes

    ;*********************
    ;El Torito Boot Info Table
    ;*********************

    ;in nasm, I couldn't figure out how to reserve bytes, in the middle of .text
    ;so I zeroed it out.
    times 56 db 0

    loader:
    call cls                ;clear the screen
    mov si, head1           ;setup page headers
    call printf 
    mov si, head2
    call printf
    jmp note                ;start note program

    cls:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
    ret

    printf:
    .loop                   ;our function that loops
    mov al, [si]            ;load byte
    cmp al, 0               ;if null, end
    je .end
    mov ah, 0x0E            ;function 0E
    mov bh, 0x00            ;page 0x00
    mov bl, 0x0F            ;white text on black background
    int 0x10                ;print
    inc si                  ;increment source index
    jmp .loop               ;repeat
    .end
    ret                     ;return

    ;*******************
    ; Note 'Program'
    ;*******************

    note:
    mov ah, 0x00            ;function 00
    int 0x16                ;get character
    cmp al, '`'             ;go up line?
    je setcur
    cmp al, 0x0D            ;enter?
    je setent
    cmp al, '+'             ;plus?
    je setplu
    cmp al, '-'             ;minus?
    je setminu
    cmp al, '\'             ;reset?
    je loader
    cmp al, 0x08            ;backspace?
    je setback
    mov ah, 0x0E            ;function 0E
    mov bh, 0x00            ;page 00
    mov bl, 0x0F            ;white on black
    int 0x10                ;print
    jmp note                ;repeat

    setcur:
    mov ah, 0x03            ;get cur pos
    mov bh, 0x00            ;page 00
    int 0x10                ;get pos
    cmp dh, 0x00            ;are we at top of page?
    je .begin               ;just reset cursor if so
    sub dh, 0x01            ;go up one line
    .begin
    mov dl, 0x00            ;set to beginning of line
    mov ah, 0x02            ;set cursor function
    mov bh, 0x00            ;page 00
    int 0x10                ;set position
    jmp note                ;read next character

    setent:
    mov ah, 0x0E            ;write character
    mov al, 0x0A            ;begin line
    mov bh, 0x00            ;page 00
    mov bl, 0x0F            ;white on black
    int 0x10                ;print

    setplu:
    mov ah, 0x03            ;get cursor pos
    mov bh, 0x00            ;page 0x00
    int 0x10                ;get pos
    mov ah, 0x02            ;set cursor pos
    add dl, 0x01            ;add one to column
    int 0x10                ;set new pos
    jmp note                ;get next char

    setminu:
    mov ah, 0x03            ;get cursor pos
    mov bh, 0x00            ;page 00
    int 0x10                ;get pos
    mov ah, 0x02            ;set cursor pos
    sub dl, 0x01            ;sub one to column
    int 0x10                ;set new pos
    jmp note                ;get next char

    setback:
    mov ah, 0x03            ;get cursor pos
    mov bh, 0x00            ;page 00
    int 0x10                ;get pos
    mov ah, 0x02            ;set cursor pos
    sub dl, 0x01            ;sub one column
    int 0x10                ;set pos
    mov ah, 0x0E            ;write char
    mov al, ' '             ;write space
    mov bh, 0x00            ;page 00
    mov bl, 0x0F            ;white on black
    int 0x10
    mov ah, 0x02            ;reset cur pos
    int 0x10                ;reset
    jmp note

    ;******************
    ; Our Page Headers
    ;******************
    head1: db '- Note OS Version 1.2-', 0x0A, 0x0D, 0
    head2: db '=======================', 0x0A, 0x0D, 0x0A, 0x0D, 0

    times 510 - ($ - $$) db 0
    dw 0xAA55

Для справки (Вещи, на которые я ссылался):

Таблица Anscii: http://www.asciitable.com/

Информация об Эль-Торито: http://wiki.osdev.org/El-Torito

РЕДАКТИРОВАТЬ: Вот ключи, которые я запрограммировал и что они делают:

enter - теперь работает нормально, backspace - работает теперь нормально plus + - перемещает курсор вправо минус - перемещает курсор влево `- перемещает курсор в начало предыдущей строки \ -«мягкие перезагрузки» переходят почти к началу загрузчика

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Проблема здесь:

[org 0x7C00]
...
start:
jmp loader                           ;jump to the actual start of bootloader
...
loader:
call cls                ;clear the screen
mov si, head1           ;setup page headers
call printf 
...
printf:
.loop                   ;our function that loops
mov al, [si]            ;load byte

Вы ожидаете CS=DS=0 при запуске вашего кода.Значение DS не гарантируется равным 0. Поэтому, когда оно отлично от нуля, mov al, [si] читает байты из какого-то сегмента, отличного от сегмента 0, и может быть некоторый мусор, а не копия вашего приветственного сообщения.

Кроме того, некоторыеBIOS переходят к вашему коду, используя адрес 0:0x7C00, в то время как другие используют 0x7C0:0, что означает, что даже CS не гарантированно будет иметь фиксированное значение.

Вместо этого я бы сделал следующее:

[org 0x7C00]
[bits 16]
start:
jmp loader                           ;jump to the actual start of bootloader
...
loader:
jmp 0:loader2 ; this far jump guarantees CS=0

loader2:
push cs
pop ds ; this guarantees DS=0

; the rest of the code goes here
2 голосов
/ 12 марта 2012

Wowsers; теперь это тяжелый вопрос!

На самом деле, это слишком общий вопрос программирования, чтобы по-настоящему работать здесь над переполнением стека, а просто бросить что-то на вас, в надежде быть полезным!

Если вы попадаете в точку, в которой он вообще перемещает курсор, хотя и случайно, тогда, я думаю, ваш загрузчик в порядке; но, чтобы быть ясным - он даже отображает «заголовок» на I5?

То, на что я здесь смотрю, это векторы прерываний / адресные строки / и т. Д., Которые вы используете, чтобы курсор вообще перемещался. Вы уверены, что операции int10 являются полностью общими?

...