GRUB 0.97 (stage2_eltorito) から GRUB 2 に切り替えて、オペレーティング システムを起動する ISO イメージを生成しようとしています。しかし、私は独特のエラーに直面しています。状況を説明するために、最近、いくつかの例外処理 ISR と 2 つの IRQ をセットアップしました。1 つはキーボード入力用、もう 1 つはタイマー ティック用です。GRUB Legacy で起動すると、カーネルは正常に動作し、キーボード入力も機能します。GRUB 2 で起動すると、何らかの理由でカーネルが一般保護違反の例外をキャッチし、システムを停止します。コードを何度も校正しましたが、この GPF エラーを引き起こす可能性のあるエラーはどこにも見つかりません。私の問題は何ですか?どうすれば修正できますか? マルチブート ヘッダーを含む、カーネルのアセンブリ エントリ ポイントは次のとおりです。
extern toc
extern init
extern kmain
extern load_gdt
global start32
MBALIGN equ 1<<0
MEMINFO equ 1<<1
MAGIC_NUMBER equ 0x1BADB002
FLAGS equ MBALIGN | MEMINFO
CHECKSUM equ -(MAGIC_NUMBER + FLAGS)
section .text
align 4
dd MAGIC_NUMBER
dd FLAGS
dd CHECKSUM
start32:
call load_gdt
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x9c000
call init
push ebx
call kmain
(カーネルは実際には両方のケースで完全にロードされるため、これはマルチブートの問題ではないと思います)
global toc
global load_gdt
section .text
load_gdt:
lgdt[toc]
ret
section .rodata
gdt32:
dd 0
dd 0
dw 0x0FFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
dw 0x0FFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
toc:
dw gdt_end - gdt32 - 1
dd gdt32
OS をセットアップする init() 関数 (もちろん、initrd を作成する前に)
#include <kernel.h>
void init()
{
interrupt_disable();
terminal_init(LGREEN, BLACK);
idt_install();
isr_install();
irq_install();
interrupt_enable();
timer_install();
keyboard_install();
return;
}
そしてもちろん、私の kmain
#include <kernel.h>
#include <multiboot.h>
char logo[1024] = {
":::::::::::///oyhhyo//:::::::::::/:\n" \
"://////////+yNNmhysoo+////////////:\n" \
"::/://:://yNdy+//::::::+o/:://////:\n" \
"::////://sNdy+//::-:-:::++/://////:\n" \
"::::::://dmdyo/:::::--::++/::::::::\n" \
":::::::/+mdhhysoo+:/++//+y/::::::::\n" \
":::::::/oddyooo+/o//+so+/o/::::::::\n" \
"+ = = + + + +++++ Welcome to LunaOS!\n" \
"+ = = + + + +===+ A simple 32-bit operating system\n" \
"+ = = + + + + + Written soley by Safal Aryal\n" \
"++++++ = = = = + + + + All components of this OS,\n" \
":::::::/+hhyo///+s///::/+//:::::::: are in the public domain!\n" \
"::::::://oshs+/+hdhs+/////::::::::: (excluding the GRUB bootloader)\n" \
"::::::::/++so+shdyhys+////::::::::: Type `help` for a list of commands\n" \
"::::::::/+o++oosso++/+/:/::::::::::\n" \
":::::::/ossssysoso+//+/:/::::::::::\n" \
":::://ohysosysso+oo/:///:::::::::::\n" \
"::::--:/ssyoshhsoo+/::+:/-:::::::::\n" \
":::-----:+shysdyo/-.`-/::--:----:::\n" \
"--::------:+sssyo/.`.:/:----::-----\n" \
"-::/:--::-::---//////--------::----\n" \
};
void kmain(multiboot_info_t *mbd, uint32_t magic)
{
uint32_t mmap;
if((mbd->flags >> 6) & 1) {
mmap = mbd->mmap_addr;
}
terminal_puts(logo);
terminal_puts("SHELL> ");
for(;;){asm volatile("sti"); asm volatile ("hlt");};
}
前もって感謝します!(注: multiboot_info_t は、メモリ マップにアクセスするために使用するマルチブート ヘッダーで定義されます。その型へのポインターは、kernel.asm のスタックに EBX をプッシュすることにより、パラメーターとして kmain に渡されます)
PS:kvm -kernel
動作するようです...