[英]Simple kernel won't boot in GRUB
我正在從OSDev.org學習一些OS開發。 我有一個內核,我正在嘗試使用qemu在GRUB Legacy(0.97)中啟動。 但是,當我輸入kernel 200+9
,我收到了消息
[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c]
這是我所期望的,除了(壞)部分。 如果我現在鍵入boot
GRUB就會掛起。
我認為數字0x100000,0x44,0x4008分別代表.text段起始地址,.bss起始地址和.bss段大小。 我認為這是因為在內核映像上運行objdump -h
會產生以下結果:
kernel.bin: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000044 00100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00004008 00100044 00100044 00001044 2**2
ALLOC
所以你可以看到我提到的數字幾乎匹配。 問題是,而不是100044,.bss的開頭只有44個。我認為這就是GRUB說錯的原因。 我的內存不足1 MB(低內存)。 但objdump告訴我我的部分超過了這個門檻,所以我不知道出了什么問題。 無論如何,我會在下面粘貼我的代碼,它相對較短。 雖然我的問題可能是非常基本的,如果你以前做過OS開發,所以代碼可能是無關緊要的。
;loader.s - contains the multiboot header for grub and calls the main kernel method
global loader ; making entry point visible to linker
global magic ; we will use this in kmain
global mbd ; we will use this in kmain
extern kmain ; kmain is defined in kmain.cpp
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ 0x03;MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
loader:
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
mov esp, stack + STACKSIZE ; set up the stack
mov [magic], eax ; Multiboot magic number
mov [mbd], ebx ; Multiboot info structure
call kmain ; call kernel proper
cli
.hang:
hlt ; halt machine should kernel return
jmp .hang
section .bss
align 4
stack: resb STACKSIZE ; reserve 16k stack on a doubleword boundary
magic: resd 1
mbd: resd 1
。
// kernel.c - Contains the main kernel method
void kmain() {
extern unsigned int magic;
if (magic != 0x2BADB002) {
// Something went wrong
}
volatile unsigned char *videoram = (unsigned char *) 0xB800;
videoram[0] = 65;
videoram[1] = 0x07;
}
下面是我的自定義鏈接器腳本:
ENTRY (loader)
SECTIONS {
. = 0x00100000;
.text ALIGN (0x1000) : {
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata*)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
/DISCARD/ : {
*(.eh_frame)
*(.comment)
}
}
最后,我用以下幾行構建內核:
nasm -f elf -o loader.o loader.s
gcc -c -o kernel.o kernel.c
ld -T linker.ld -o kernel.bin loader.o kernel.o
cat stage1 stage2 pad kernel.bin > floppy.img
其中stage1和stage2是來自GRUB Legacy的文件,pad是任何750字節的文件(So stage1 + stage2 + pad的文件大小為102400字節,或200塊,這就是我用內核200 + 9啟動的原因)。
最后,我在qemu中運行內核:
qemu-system-x86_64 -fda floppy.img
+1以獲得所有細節的好問題,謝謝。
至少在我的機器上生成的kernel.bin
是4869字節,只適合10個不是9的扇區。另外,VGA文本內存是0xb8000
而不是0xb800
( 0xb800
一個零 - 0xb800
是實模式段,必須乘以16)。 通過這些小調整,它在這里工作正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.