Assembly 用grub引导汇编编写的内核

Assembly 用grub引导汇编编写的内核,assembly,boot,osdev,grub,Assembly,Boot,Osdev,Grub,我知道,对于这么小的一个简单内核,我实际上不需要用GRUB启动它,但我正在尝试在我的内核变大之前学习如何启动它。我已经使用OSDev.org上的实模式汇编教程编写了一个带有汇编的简单内核。我试图启动它,但GRUB给了我一个错误,它找不到多重启动头。我查看了C裸体教程的汇编代码。我需要把所有的东西都放在这一部分吗?你能告诉我如何启动这个代码吗。(这段代码不是我写的,我把代码留在家里的机器上,现在在学校,我只是从OSDev那里借了这段代码,所以请不要给我任何恶意评论说我偷了别人的代码。) 我可以使用

我知道,对于这么小的一个简单内核,我实际上不需要用GRUB启动它,但我正在尝试在我的内核变大之前学习如何启动它。我已经使用OSDev.org上的实模式汇编教程编写了一个带有汇编的简单内核。我试图启动它,但GRUB给了我一个错误,它找不到多重启动头。我查看了C裸体教程的汇编代码。我需要把所有的东西都放在这一部分吗?你能告诉我如何启动这个代码吗。(这段代码不是我写的,我把代码留在家里的机器上,现在在学校,我只是从OSDev那里借了这段代码,所以请不要给我任何恶意评论说我偷了别人的代码。)

我可以使用BIOS启动和打印吗?或者我必须使用堆栈吗

;====================================

[ORG 0x7c00]      ; add to offsets
xor ax, ax    ; make it zero
mov ds, ax   ; DS=0
mov ss, ax   ; stack starts at 0
mov sp, 0x9c00   ; 200h past code start

mov ax, 0xb800   ; text video memory
mov es, ax

mov si, msg   ; show text string
call sprint

mov ax, 0xb800   ; look at video mem
mov gs, ax
mov bx, 0x0000   ; 'W'=57 attrib=0F
mov ax, [gs:bx]

mov  word [reg16], ax ;look at register
call printreg16

hang:
jmp hang

----------------------
dochar:   call cprint         ; print one character
sprint:   lodsb      ; string char to AL
cmp al, 0
jne dochar   ; else, we're done
add byte [ypos], 1   ;down one row
mov byte [xpos], 0   ;back to left
ret

cprint:   mov ah, 0x0F   ; attrib = white on black
mov cx, ax    ; save char/attribute
movzx ax, byte [ypos]
mov dx, 160   ; 2 bytes (char/attrib)
mul dx      ; for 80 columns
movzx bx, byte [xpos]
shl bx, 1    ; times 2 to skip attrib

mov di, 0        ; start of video memory
add di, ax      ; add y offset
add di, bx      ; add x offset

mov ax, cx        ; restore char/attribute
stosw              ; write char/attribute
add byte [xpos], 1  ; advance to right

ret

;------------------------------------

printreg16:
mov di, outstr16
mov ax, [reg16]
mov si, hexstr
mov cx, 4   ;four places
hexloop:
rol ax, 4   ;leftmost will
mov bx, ax   ; become
and bx, 0x0f   ; rightmost
mov bl, [si + bx];index into hexstr
mov [di], bl
inc di
dec cx
jnz hexloop

mov si, outstr16
call sprint

ret

;------------------------------------

xpos   db 0
ypos   db 0
hexstr   db '0123456789ABCDEF'
outstr16   db '0000', 0  ;register value string
reg16   dw    0  ; pass values to printreg16
msg   db "What are you doing, Dave?", 0
times 510-($-$$) db 0
db 0x55
db 0xAA
;==================================

先谢谢你

如果要编写实模式内核(16位),则不能使用GRUB。GRUB只能加载32位内核

您应该考虑这样一个事实,即BIOS中断不能仅在32位模式下使用

MultiBoot规范()描述了GRUB所需的文件格式

当然这对初学者来说没什么

如果您想在没有GRUB的情况下引导内核(并且您的操作系统大于510字节),那么您的引导扇区必须使用中断0x13从磁盘加载其余的操作系统


此时,计算机以16位实模式运行。

通过多重启动,内核以保护模式启动

“CR0”位31(PG)必须清除。必须设置位0(PE)。其他位 都没有定义

Grub可以引导16位内核,因为Linux以16位启动。但这是为了方便Linux、FreeBSD、NetBSD和OpenBSD。及

不支持多引导且没有 GRUB中的特定支持(Linux提供特定支持, FreeBSD、NetBSD和OpenBSD)必须进行链加载,这涉及 加载另一个引导加载程序并在实模式下跳转到它


我很抱歉代码是如何格式化的这是我在forumLinux上的第一个编码问题以实模式启动
;====================================

[ORG 0x7c00]      ; add to offsets
xor ax, ax    ; make it zero
mov ds, ax   ; DS=0
mov ss, ax   ; stack starts at 0
mov sp, 0x9c00   ; 200h past code start

mov ax, 0xb800   ; text video memory
mov es, ax

mov si, msg   ; show text string
call sprint

mov ax, 0xb800   ; look at video mem
mov gs, ax
mov bx, 0x0000   ; 'W'=57 attrib=0F
mov ax, [gs:bx]

mov  word [reg16], ax ;look at register
call printreg16

hang:
jmp hang

----------------------
dochar:   call cprint         ; print one character
sprint:   lodsb      ; string char to AL
cmp al, 0
jne dochar   ; else, we're done
add byte [ypos], 1   ;down one row
mov byte [xpos], 0   ;back to left
ret

cprint:   mov ah, 0x0F   ; attrib = white on black
mov cx, ax    ; save char/attribute
movzx ax, byte [ypos]
mov dx, 160   ; 2 bytes (char/attrib)
mul dx      ; for 80 columns
movzx bx, byte [xpos]
shl bx, 1    ; times 2 to skip attrib

mov di, 0        ; start of video memory
add di, ax      ; add y offset
add di, bx      ; add x offset

mov ax, cx        ; restore char/attribute
stosw              ; write char/attribute
add byte [xpos], 1  ; advance to right

ret

;------------------------------------

printreg16:
mov di, outstr16
mov ax, [reg16]
mov si, hexstr
mov cx, 4   ;four places
hexloop:
rol ax, 4   ;leftmost will
mov bx, ax   ; become
and bx, 0x0f   ; rightmost
mov bl, [si + bx];index into hexstr
mov [di], bl
inc di
dec cx
jnz hexloop

mov si, outstr16
call sprint

ret

;------------------------------------

xpos   db 0
ypos   db 0
hexstr   db '0123456789ABCDEF'
outstr16   db '0000', 0  ;register value string
reg16   dw    0  ; pass values to printreg16
msg   db "What are you doing, Dave?", 0
times 510-($-$$) db 0
db 0x55
db 0xAA
;==================================