OSDev.org https://forum.osdev.org/ |
|
[RESOLVED] IDT doesn't work when linking above 0xa0000 https://forum.osdev.org/viewtopic.php?f=1&t=33750 |
Page 1 of 1 |
Author: | pm [ Sat Jun 29, 2019 4:07 pm ] |
Post subject: | [RESOLVED] IDT doesn't work when linking above 0xa0000 |
IDT doesn't work when part of the .data section gets loaded above 0xa0000. I am using GRUB. I have set up my own GDT. Source code here. Changing line 6 of kernel.ld from 0x80000 to anything above 0x9c160 will cause the CPU to jump to 0xe05b on "int $3" instead of the correct interrupt handler. I tried linking the kernel way higher (at 4M and 100M) and it doesn't work as well. Code: OUTPUT_ARCH(i386) I imagine 0xe05b is a GRUB interrupt handler. I want to know if that is an issue with my linker script, or if I am missing something with the GRUB setup. Also, I would like to know where I can learn more about linking the kernel/linkers in general.ENTRY(_start) SECTIONS { . = 0x80000; // Changing to anything above 0x9c160 will cause part of the .data section to go above 0xa0000. .text : { *(.multiboot) *(.text) } .data ALIGN(4096) : { *(.data .rodata*) } .bss ALIGN(4096) : { *(.bss) } } My environment: Code: i386-elf-gcc (GCC) 9.1.0
GNU i386-elf-ld (GNU Binutils) 2.32 qemu-system-i386 version 4.0.0 grub-mkrescue (GRUB) 2.03.6~manjaro xorriso 1.5.0 |
Author: | MichaelPetch [ Sat Jun 29, 2019 5:06 pm ] |
Post subject: | Re: IDT doesn't work when linking above 0xa0000 |
f000:e05b is indicative your kernel triple faulted and returned back to real mode. You should be using . = 0x100000; in your linker script as the multiboot spec doesn't actually say it will support loading anywhere else except at 0x100000 . |
Author: | MichaelPetch [ Sat Jun 29, 2019 6:30 pm ] |
Post subject: | Re: IDT doesn't work when linking above 0xa0000 |
I had a chance to look at the code. It will fault on your interrupts because the IDT descriptors have been built incorrectly in make_interrupt_gate. You have: Code: static inline uint64_t make_interrupt_gate(const uintptr_t interrupt) { I think it should be more like:const uint64_t interrupt_low = interrupt; const uint64_t interrupt_high = interrupt >> 16; uint64_t idt_entry = 0; idt_entry |= interrupt_low; idt_entry |= interrupt_high << 48; idt_entry |= KERNEL_CODE_SELECTOR << 16; // Interrupt type and attributes. idt_entry |= (uint64_t)0x8e << 40; return idt_entry; } Code: static inline uint64_t make_interrupt_gate(const uint64_t interrupt) {
uint64_t idt_entry = 0; idt_entry |= (interrupt & 0xffff); idt_entry |= (interrupt & 0xffff0000) << 32; idt_entry |= (uint64_t)KERNEL_CODE_SELECTOR << 16; // Interrupt type and attributes. idt_entry |= (uint64_t)0x8e << 40; return idt_entry; } |
Author: | pm [ Sat Jun 29, 2019 6:44 pm ] |
Post subject: | Re: IDT doesn't work when linking above 0xa0000 |
MichaelPetch wrote: I had a chance to look at the code. It will fault on your interrupts because the IDT descriptors have been built incorrectly in make_interrupt_gate. Indeed, that was the case. Thank you very much for this and the previous reply.
|
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |