OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Nov 12, 2019 12:52 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: [RESOLVED] IDT doesn't work when linking above 0xa0000
PostPosted: Sat Jun 29, 2019 4:07 pm 
Offline

Joined: Sat Jun 29, 2019 3:19 pm
Posts: 2
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)
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) }
}
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.

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


Last edited by pm on Sat Jun 29, 2019 7:39 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: IDT doesn't work when linking above 0xa0000
PostPosted: Sat Jun 29, 2019 5:06 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 492
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 .


Top
 Profile  
 
 Post subject: Re: IDT doesn't work when linking above 0xa0000
PostPosted: Sat Jun 29, 2019 6:30 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 492
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) {
  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;
}
I think it should be more like:
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;
}


Top
 Profile  
 
 Post subject: Re: IDT doesn't work when linking above 0xa0000
PostPosted: Sat Jun 29, 2019 6:44 pm 
Offline

Joined: Sat Jun 29, 2019 3:19 pm
Posts: 2
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], MSN [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group