0

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動作するようです...

4

0 に答える 0