gpt4 book ai didi

assembly - 简单内核无法在 GRUB 中启动

转载 作者:行者123 更新时间:2023-12-02 11:08:24 34 4
gpt4 key购买 nike

我正在从 OSDev.org 学习一些操作系统开发知识。我有一个内核,我正在尝试使用 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

所以你可以看到我提到的数字几乎匹配。问题是 .bss 的开头不是 100044,而是 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 的文件,pad 是任何 750 字节的文件(因此 stage1+stage2+pad 的文件大小为 102400 字节或 200 个 block ,这就是我使用内核 200+9 启动的原因)。

最后,我在 qemu 中运行内核:

qemu-system-x86_64 -fda floppy.img

最佳答案

对于包含所有详细信息的好问题+1,谢谢。

至少在我的机器上,生成的 kernel.bin 大小为 4869 字节,仅适合 10 个扇区,而不是 9 个。此外,VGA 文本内存位于 0xb8000 不是 0xb800 (多一个零 - 0xb800 是实模式段,必须乘以 16)。通过这些小小的调整,它在这里工作得很好。

关于assembly - 简单内核无法在 GRUB 中启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14311761/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com