首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bootloader奇怪行为

Bootloader奇怪行为
EN

Stack Overflow用户
提问于 2012-03-12 00:22:43
回答 2查看 617关注 0票数 7

我一直试图设计一个简单的操作系统,只有引导扇区,和16位真正的模式中断。我终于能够制作OS / bootloader,我在虚拟盒中进行了测试,并且成功了。

然后,我将映像刻录到CD上,然后用奔腾4、BIOS修订版A05和1GB内存将其引导到我的旧桌面上,它工作得非常完美--一个简单的操作系统在屏幕顶部打印一个“头”,它所做的一切都允许您键入屏幕,并注册几个键来导航光标。

然后,我用i5处理器和2.6GB内存以及A05 BIOS修订版将光盘插入我的1岁的笔记本电脑中,光标似乎随机移动,高速打印随机字符,最后停在anscii字符235 (扩展字符表的一部分),此时键盘工作正常,指定移动光标的键工作良好,只是头键。这是我测试过的电脑,把它压在上面,写在上面,然后用它烧了CD。(我使用Linux 12操作系统)

我已经跳过了所有我认为我需要做的“圈”:制作了一个iso映像,遵循El Torito‘无仿真’的引导标准,引导签名,512字节,并写入正确的扇区。

这是我的代码出了问题吗?我没有做什么吗?还是这是正常的?

这是我的代码(NASM x86语法):

代码语言:javascript
复制
    ;**************************
    ; 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

供参考(我参考的东西):

安氏表:http://www.asciitable.com/

El信息:http://wiki.osdev.org/El-Torito

编辑:这是我编写的钥匙和它们的功能:

输入-移动光标右减-将光标移动到前一行的开头\-“软重新启动”几乎跳到加载程序的开始。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-12 06:19:52

问题在于:

代码语言:javascript
复制
[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以外的某个段读取字节,并且可能存在一些垃圾,而不是您的问候消息的副本。

另外,有些BIOSes使用0:0x7C00的地址跳转到您的代码,而另一些则使用0x7C0:0,这意味着即使CS也不一定有固定的值。

我要做的是:

代码语言:javascript
复制
[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
EN

Stack Overflow用户

发布于 2012-03-12 00:30:16

哇,这是个沉重的问题!

在现实中,它太通用的编程问题,在这里真的工作在堆栈溢出,但只是抛弃一些东西,希望你是有帮助的!

如果你到了一点,它甚至在移动你的光标,尽管是随机的,那么我想你的引导加载程序是可以的;但是要明确的是-它甚至在I5上显示‘头’吗?

我在这里要看的是中断向量/地址行/etc,您可以使用这些中断向量/地址行/etc来使光标四处移动。您确定int10操作是完全通用的吗?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9660315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档