I am trying to switch from GRUB 0.97 (stage2_eltorito) to GRUB 2, generating an ISO image that boots the operating system. However, I am facing a peculiar error. Just to give some context, I have recently set up some exception handling ISRs and two IRQs: one for keyboard input, one for timer ticks. When booted with GRUB Legacy, the kernel works fine, and the keyboard input also works. When booting with GRUB 2, for some reason, the kernel catches a General Protection Fault exception and halts the system. I have proofread my code multiple times and I cannot find an error in it anywhere that may cause this GPF error. What is my problem, and how can it be fixed? Here is the Assembly entry point of the kernel, including the Multiboot header:
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
(I don't think this a Multiboot issue, as the kernel actually loads perfectly in both cases) The load_gdt and associated labels mentioned here (as I think this may be part of the issue)
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
The init() function that sets the OS up (before I make an initrd, of course)
#include <kernel.h>
void init()
{
interrupt_disable();
terminal_init(LGREEN, BLACK);
idt_install();
isr_install();
irq_install();
interrupt_enable();
timer_install();
keyboard_install();
return;
}
And of course, my 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");};
}
Thanks in advance!
(Note: multiboot_info_t is defined in the Multiboot header which I use to access the memory map, a pointer to its type is passed as a parameter to kmain by pushing EBX to the stack in kernel.asm)
P.S: kvm -kernel
seems to work...