【发布时间】:2011-02-01 15:57:23
【问题描述】:
我们正在开展一个项目来学习如何编写内核并了解其中的来龙去脉。我们编写了一个引导加载程序,它似乎可以工作。但是,我们在内核加载方面遇到了问题。我将从第一部分开始:
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 binnasm 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 字节编译。内核应该在下一个扇区。
【问题讨论】:
-
我非常怀疑你的意思是
cp kernel.sys /dev/fd0,它会从一开始就覆盖软盘设备。即使您不粘贴它,您能否描述一下您的引导加载程序应该从哪里将内核加载到内存中? -
嗯,是的,这就是我的意思。这是我将文件复制到设备的示例。应该不一样吗?我对 Linux 方式非常陌生 - 从 3.0 开始我就一直在使用 Windows。
-
您的
dd将bootloader.bin的一个扇区写入软盘的第一个扇区。然后你的cp将kernel.sys直接复制到软盘,覆盖它...也许你的意思是dd seek=1,开始将kernel.sys放在软盘的第二个扇区?需要有关您的引导加载程序的更多详细信息,以确定这是否是您想要的。
标签: assembly kernel nasm opensuse bootstrapping