簡體   English   中英

簡單內核無法在GRUB中啟動

[英]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而不是0xb8000xb800一個零 - 0xb800是實模式段,必須乘以16)。 通過這些小調整,它在這里工作正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM