我正在尝试使用grub(legacy)规范编写一个兼容多引导内核,以下是我的boot.s(使用gnu as编写)的内容
#include "boot.h"
.code32
.globl start
.type start, @function
.extern kernel_main
.type kernel_main, @function
.bss
.comm stack, STACK_SIZE
.section .mboot
.align 4
.long MBOOT_HEADER_MAGIC
.long MBOOT_HEADER_FLAGS
.long MBOOT_CHECKSUM
.text
start:
movl $(stack + STACK_SIZE) , %esp
cli
call kernel_main
sti
hlt
jmp .
boot.h文件包含grub的一些定义:
#ifndef _BOOT_H_
#define _BOOT_H_
#define MBOOT_PAGE_ALIGN 1<<0
#define MBOOT_MEM_INFO 1<<1
#define MBOOT_HEADER_MAGIC 0x1BADB002
#define MBOOT_HEADER_FLAGS MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
#define MBOOT_CHECKSUM -( MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)
#define STACK_SIZE 0x4000
#endif /* _BOOT_H_ */
我还设置了这样的链接器:
ENTRY(start)
OUTPUT_ARCH(i386)
OUTPUT_FORMAT("elf32-i386")
SECTIONS
{
. = 1M;
.mboot ALIGN(4K) :
{
*(.mboot)
}
.text ALIGN(4K) :
{
*(.text)
*(.rodata)
}
.data ALIGN(4K) :
{
*(.data)
}
.bss ALIGN(4K) :
{
*(.bss)
}
}
目前,我的kernel_main只是返回%eax寄存器中预期的值0x01,但当我使用执行内核时
qemu -kernel kernel.bin -monitor stdio
然后在qemu中发出命令info registers
,我总是为%eax找到一个值18。所以我的问题是:我的boot.s文件是否被正确定义为符合grub?为什么%eax中的值18而不是0x01?
您的图像很可能是正确的-如果不符合multiboot,QEMU将抛出错误。在调用kernel_main之后,中断处理程序可能会使用eax
,因为使用sti
可以启用中断。