Error when loading IDT in Long Mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yByonic
Posts: 13
Joined: Mon Aug 24, 2020 2:25 pm

Error when loading IDT in Long Mode

Post by yByonic »

Hi everyone, I am developing a 64bit operating system. Right now I'm trying to create an Interrupt Descriptor Table (IDT), but I get an error that I can't get over. Someone can help me? Thanks!

The kernel.cpp:

Code: Select all

#include "textPrint.cpp"
#include "idt.cpp"

extern "C" void _start(){
    setCursorPosition(positionFromCoords(0,0));
    InitializeIDT();
    return;
}
The idt.cpp:

Code: Select all

#pragma once
#include "types.cpp"

/*Interrupt descriptor Table*/
struct IDT64{
	uint_16 offset_low;
	uint_16 selector;
	uint_8 ist;
	uint_8 types_attr;
	uint_16 offset_mid;
	uint_32 offset_high;
	uint_32 zero;
};
extern IDT64 _idt[256];
extern uint_64 isr1; 
extern "C" void LoadIDT();

void InitializeIDT(){
	for (uint_64 t = 0; t < 256; t++){
		_idt[t].zero = 0;
		_idt[t].offset_low = (uint_16)(((uint_64)&isr1 & 0x000000000000ffff));
		_idt[t].offset_mid = (uint_16)(((uint_64)&isr1 & 0x00000000ffff0000) >> 16);
		_idt[t].offset_high = (uint_32)(((uint_64)&isr1 & 0xffffffff00000000) >> 32);
		_idt[t].ist = 0;
		_idt[t].selector = 0x08;
		_idt[t].types_attr = 0x8e;
	}	
	outb(0x21, 0xfd);
	outb(0xa1, 0xff);
	LoadIDT();
}

extern "C" void isr1_handler(){
	printString(HexToString(inb(0x60)));
	//uint_8 scanCode = inb(0x60);
	outb(0x20, 0x20);
	outb(0xa0, 0x20);
}
The idt.asm

Code: Select all

[extern _idt]
idtDescriptor:
  dw 4095
  dq _idt

  %macro PUSHALL 0
  	push rax
  	push rcx
  	push rdx
  	push r8
  	push r9
  	push r10
  	push r11
  %endmacro

  %macro POPALL 0
  	pop r11
  	pop r10
  	pop r9
  	pop r8
  	pop rdx
  	pop rcx
  	pop rax
  %endmacro

[extern isr1_handler]
isr1:
  PUSHALL
  call isr1_handler
  POPALL
  iretq
  GLOBAL isr1

LoadIDT:
  lidt[idtDescriptor]
  sti
  ret
  GLOBAL LoadIDT
O erro acontece quando, no idt.asm, rodo a função lidt, se apagar esta linha o erro não acontece, mas a idt também não é ativada. A minha idt é inválida? Na consola de debug do Bochs (no ficheiro anexo) parace-me que o código salta para um "void":
read() on floppy image returns 0
Por outro lado parece-me que a idt é de facto inválida:
interrupt(long mode): gate descriptor is not valid sys seg
report.txt
The Bochs Report
(38.72 KiB) Downloaded 67 times
The Github Repo: https://github.com/Jmallone/os-dev/tree ... Sector%201
davmac314
Member
Member
Posts: 121
Joined: Mon Jul 05, 2021 6:57 pm

Re: Error when loading IDT in Long Mode

Post by davmac314 »

In GDT.ASM:

Code: Select all

gdt_codedesc:
	dw 0xFFFF 	; Limit 
	dw 0x0000	; Base(low)
	db 0x00		; base(medium)
	db 10011010b; Flags
	db 11001111b; Flags + upper limit
	db 0x00		; Base(high)
The "flags + upper limit" is wrong for a long mode code segment. bit 7 should be clear, bit 6 ("L") should be set. The correct value would be 10101111b.
Post Reply