简单的内核GRUB将无法启动 [英] Simple kernel won't boot in GRUB

查看:341
本文介绍了简单的内核GRUB将无法启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  [多引导小精灵,< 0x100000处:0x80的:0x4008>(坏),入境= 0x10000c]

这是我所期望的除外(坏)的一部分。如果键入启动现在GRUB只是挂起。

我觉得数字的0x100000,0x44进行,0x4008代表到.text段的起始地址,.bss中开始地址和.bss段的大小,分别为。我想,这是因为运行 objdump的-h 内核映像上给出了这样的输出:

  kernel.bin:文件格式ELF32-I386部分:
IDX名称大小VMA LMA文件ALGN关闭
  0的.text 00000044 00100000 00100000 00001000 2 ** 4
                  内容ALLOC,LOAD,只读,code
  1的.bss 00004008 00100044 00100044 00001044 2 2 **
                  ALLOC

所以,你可以看到,我几乎提到的数字相匹配。问题是,不是100044,.bss中的启动仅仅是44,我想这就是为什么GRUB是说不好的原因。我不能在内存(低内存)低于1 MB的部分。但objdump的告诉我,我的部分是上面的门槛,所以我不知道什么是错。无论如何,我会贴上我的code以下,就比较短。虽然我的问题可能是非常基本的,如果你做了OS开发之前,所以code可能是多余的。

 ; loader.s  - 包含多重引导头的平头,并调用主内核方法全球装载机;使得切入点可见链接
全球魔术;我们将在kmain使用
全球万桶;我们将在kmain使用EXTERN kmain; kmain在kmain.cpp定义;建立多重引导头 - 详见GRUB文档
MODULEALIGN EQU 1所述;℃下;对齐页面边界上加载的模块
meminfo的EQU 1 LT;< 1;提供内存映射
FLAGS EQU×03; MODULEALIGN | meminfo中;这是多引导标志字段
MAGIC EQU 0x1BADB002; 幻数让引导程序找到头
CHECKSUM EQU - (MAGIC +标志);需要校验.text段装载机:4对齐
    DD MAGIC
    DD FLAGS
    DD校验;保留最初的内核堆栈空间
STACKSIZE EQU 0x4000的;这是16K。    MOV ESP,堆栈+ STACKSIZE;设置堆栈
    MOV [魔力],EAX;多重幻数
    MOV [万桶],EBX;多重引导信息结构    调用kmain;调用适当的内核    CLI
。挂:
    HLT;停止机器应该内核回报
    JMP .hang.bss段4对齐
堆栈:RESB STACKSIZE;保留一个双字边界16K堆栈
魔术:RESD 1
MBD:RESD 1

  // kernel.c  - 包含主内核方法无效kmain(){
  的extern unsigned int类型的魔法;  如果(魔法!= 0x2BADB002){
    // 出了些问题
  }  挥发性无符号字符* videoram =(无符号字符*)0xB800;
  videoram [0] = 65;
  videoram [1] = 0×07;
}

下面是我的自定义链接脚本:

  ENTRY(装载机)SECTIONS {
    。 = 0x00100000;    ALIGN的.text(为0x1000):{
        *(。文本)
    }    .RODATA ALIGN(0x1000处):
    {
        *(* rodata)
    }    。数据ALIGN(0x1000处):
    {
        *(。数据)
    }    .bss段:
    {
        SBSS =。
        *(共同)
        *(BSS)
        EBSS =。
    }    /放弃/ {
        *(eh_frame)
        *(。评论)
    }
}

最后,我建立一个具有以下行内核:

  NASM -f精灵-o loader.o loader.s
GCC -c -o kernel.o kernel.c
LD -T linker.ld -o kernel.bin loader.o kernel.o
猫的stage1 stage2的垫kernel.bin> floppy.img

在哪里的stage1和stage2从GRUB传统和垫文件的750字节的文件(所以阶段1 +阶段2 +垫有102400个字节,或200块的文件大小,这就是为什么我与内核200 + 9开机)。

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

 的qemu-系统x86_64的-FDA floppy.img


解决方案

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

至少在我的机器上生成的 kernel.bin 出来为4869字节,只适合在10个行业没有9.此外,VGA文本存储在 0xb8000 不是 0xb800 (多一个零 - 0xb800 是真正的模式的段,有16相乘)。有了这些小调整,它工作在这里很好。

I'm learning a bit of OS development from OSDev.org. I have a kernel and I'm trying to boot in GRUB Legacy (0.97) using qemu. However, when I type kernel 200+9, I get the message

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

This is what I expect except for the (bad) part. If I type boot now GRUB just hangs.

I think the numbers 0x100000, 0x44, 0x4008 stand for the .text segment start address, the .bss start address, and the .bss section size, respectively. I think this because running objdump -h on the kernel image gives this output:

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

So you can see that the numbers I mentioned almost match up. The issue is that instead of 100044, the start of .bss is just 44. And I think this is the reason why GRUB is saying bad. I can't have a section below 1 MB in memory (low memory). But objdump is telling me my sections are above that threshold, so I don't know what's wrong. Anyway, I'll paste my code below, it's relatively short. Although my question is probably very basic if you've done OS dev before, so the code might be extraneous.

;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;
}

Below is my custom linker script:

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)
    }
}

And finally, I build the kernel with the following lines:

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

Where stage1 and stage2 are file from GRUB Legacy and pad is any 750 byte file (So stage1+stage2+pad have a file size of 102400 bytes, or 200 blocks, which is why I boot with kernel 200+9).

Finally, I run the kernel in qemu:

qemu-system-x86_64 -fda floppy.img

解决方案

+1 for nice question with all the details, thank you.

At least on my machine the generated kernel.bin comes out as 4869 bytes, which only fits in 10 sectors not 9. Also, the VGA text memory is at 0xb8000 not 0xb800 (one more zero - 0xb800 is the real mode segment, has to be multiplied by 16). With those little adjustments it works fine here.

这篇关于简单的内核GRUB将无法启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆