I've written a kernel which starts in 16-Bit Mode, than enters 32-Bit Mode and loads a GDT and IDT (both work perfectly) and finaly switches to long mode and load a valid 64-Bit GDT and IDT. So far so good. I print some characters on the screen to verify, that long mode ist working. But now I've a problem.
GDT64 is working perfectly and IDT64 seems to be valid, because the CPU doesn't generates a fault. But my IRQ handling doesn't seem to work in long mode. If I force a protection fault to test handling nothing happens: the system just hangs, doesn't execute the handler code and doesn't reboot.
I don't know where the problem could be.
Code: Select all
;some 16 Bit code here
.
.
.
call InitA20
xor ebx,ebx
mov bx,ds ; BX=segment
shl ebx,4 ; BX="linear" address of segment base
mov eax,ebx
mov [gdt2 + 2],ax ; set base address of 32-bit segments
mov [gdt3 + 2],ax
mov [gdt4 + 2],ax
mov [gdt5 + 2],ax
mov [gdt1_x64 + 2],ax ; set base address of 64-bit segments
mov [gdt2_x64 + 2],ax
shr eax,16
mov [gdt2 + 4],al
mov [gdt3 + 4],al
mov [gdt4 + 4],al
mov [gdt5 + 4],al
mov [gdt1_x64 + 4],al
mov [gdt2_x64 + 4],al
mov [gdt2 + 7],ah
mov [gdt3 + 7],ah
mov [gdt4 + 7],ah
mov [gdt5 + 7],ah
mov [gdt1_x64 + 7],ah
mov [gdt2_x64 + 7],ah
lea eax,[gdt + ebx]
mov [gdtr + 2],eax
lea eax,[gdt_x64 + ebx]
mov [gdtr_x64 + 2],eax
lea eax,[start_of_idt + ebx]
mov [idt_pointer + 2],eax
lea eax,[start_of_idt_X64 + ebx]
mov [idt_pointer_X64 + 2],eax
; Enbaling Protected Mode, init pic, testing interrupts, init IA32e-Mode and jumping to a 64-Bit Segment
.
.
.
jmp SYS_CODE_SEL_X64:do_long
[BITS 64]
do_long:
xor edi,edi
xor esi,esi
mov ax, SYS_DATA_SEL_X64
mov ds, ax
mov ss, ax
mov ax,LINEAR_SEL_X64
mov es,ax
mov rsp, 0x0000000000010000
lidt[idt_pointer_X64] ; load IDT register
mov byte [0xB8000], 'L' ;works
; generate protection fault to test irq handling
mov ax, 0x1234
mov es, ax
hang_x64:
hlt
jmp hang_x64
;***********************
;* Include Files x64 *
;***********************
%include "./system/x64/basic/idt.inc"
Code: Select all
%macro mkirqring0_x64 2 ;make interrupt for ring 0 (operatingsystem)
dw %1 ;offset (the handler are all below 0x10000)
dw %2 ;selector
db 0
db 10001110b
dw 0
dd 0
%endmacro
;*************************************
;* Die IDT mit und ihre Deskriptoren *
;*************************************
start_of_idt_X64:
;*****************************
;* Interrupts für Exceptions *
;*****************************
mkirqring0_x64 IRQ_00h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_01h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_02h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_03h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_04h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_05h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_06h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_07h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_08h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_09h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0ah_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0bh_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0ch_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0dh_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0eh_x64,SYS_CODE_SEL_X64
dq 0 ;Interrupt 0f reserved
dq 0
mkirqring0_x64 IRQ_10h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_11h_x64,SYS_CODE_SEL_X64
TIMES 28 dq 0 ;ignore 14 Intel reserved interrupts
;*******************************
;* Interrupts für die Hardware *
;*******************************
mkirqring0_x64 IRQ_20h_x64,SYS_CODE_SEL_X64 ; Timer
mkirqring0_x64 IRQ_21h_x64,SYS_CODE_SEL_X64 ; Keyboard
mkirqring0_x64 IRQ_22h_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_23h_x64,SYS_CODE_SEL_X64 ; Com 2
mkirqring0_x64 IRQ_24h_x64,SYS_CODE_SEL_X64 ; Com 1
mkirqring0_x64 IRQ_25h_x64,SYS_CODE_SEL_X64 ; LPT 2
mkirqring0_x64 IRQ_26h_x64,SYS_CODE_SEL_X64 ; FDD
mkirqring0_x64 IRQ_27h_x64,SYS_CODE_SEL_X64 ; LPT 1
mkirqring0_x64 IRQ_28h_x64,SYS_CODE_SEL_X64 ; CMOS Real Time Clock
mkirqring0_x64 IRQ_29h_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_2ah_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_2bh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_2ch_x64,SYS_CODE_SEL_X64 ; PS / 2 Mouse
mkirqring0_x64 IRQ_2dh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_2eh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x64 IRQ_2fh_x64,SYS_CODE_SEL_X64 ; unbenutzt
end_of_idt_X64:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; now for the IDT pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
idt_pointer_X64:
dw end_of_idt_X64 - start_of_idt_X64 - 1
dq start_of_idt_X64
;exceptions
IRQ_00h_x64:
mov byte [0xB8000], 'X'
jmp $
.
.
.
;Hardware Interrupts
IRQ_21h_x64:
mov byte [0xB8000], '+'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iret
.
.
.