简单的内核GRUB无法启动(Simple kernel won't boot in GRUB

2019-08-06 18:05发布

我学习了位操作系统的发展从OSDev.org 。 我有一个内核,我试图用QEMU GRUB遗产(0.97)来引导。 但是,当我输入kernel 200+9 ,我得到的消息

[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c]

这是我期待除外(坏)的一部分。 如果我输入boot现在GRUB只是挂起。

我认为这些数字的0x100000,0×44,0x4008立场的文本段的起始地址,存在.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的告诉我,我的部分是高于阈值的,所以我不知道什么是错。 无论如何,我会贴上我的代码下面,它是比较短的。 虽然我的问题可能是非常基本的,如果你以前做过的操作系统开发,所以代码可能是多余的。

;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是文件,垫任何750字节的文件(阶段1于是阶段2 + +垫有102400个字节,或200块的文件大小,这就是为什么我与内核200 + 9开机)。

最后,我在运行QEMU的内核:

qemu-system-x86_64 -fda floppy.img

Answer 1:

+1的所有细节有趣的问题,谢谢。

至少在我的机器所生成的kernel.bin出来作为4869个字节,其中仅装配在10个扇区不9.另外,VGA文本存储器在0xb80000xb800 (一个多个零- 0xb800是实模式的段,具有由16相乘)。 有了这些小调整在这里工作得很好。



文章来源: Simple kernel won't boot in GRUB