我一直试图设计一个简单的操作系统,只有引导扇区,和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语法):
;**************************
; 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
编辑:这是我编写的钥匙和它们的功能:
输入-移动光标右减-将光标移动到前一行的开头\-“软重新启动”几乎跳到加载程序的开始。
发布于 2012-03-12 06:19:52
问题在于:
[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也不一定有固定的值。
我要做的是:
[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发布于 2012-03-12 00:30:16
哇,这是个沉重的问题!
在现实中,它太通用的编程问题,在这里真的工作在堆栈溢出,但只是抛弃一些东西,希望你是有帮助的!
如果你到了一点,它甚至在移动你的光标,尽管是随机的,那么我想你的引导加载程序是可以的;但是要明确的是-它甚至在I5上显示‘头’吗?
我在这里要看的是中断向量/地址行/etc,您可以使用这些中断向量/地址行/etc来使光标四处移动。您确定int10操作是完全通用的吗?
https://stackoverflow.com/questions/9660315
复制相似问题