Hey guys, I have spent quite a few hours here trying to get interrupts working. But for some reason I get keeping the error in bochs:
Code: Select all
00005742028i[BIOS ] IDE time out
00017843905i[BIOS ] Booting from 07c0:0000
00017916169i[MEM0 ] allocate_block: block=0x1 used 0x3 of 0x20
00018521821e[CPU0 ] interrupt(long mode): not accessible or not code segment
00018521821e[CPU0 ] interrupt(long mode): not accessible or not code segment
00018521821e[CPU0 ] interrupt(long mode): not accessible or not code segment
00018521821i[CPU0 ] CPU is in long mode (active)
00018521821i[CPU0 ] CS.mode = 64 bit
00018521821i[CPU0 ] SS.mode = 64 bit
00018521821i[CPU0 ] EFER = 0x00000500
00018521821i[CPU0 ] | RAX=00000000000b8000 RBX=000000000000002e
00018521821i[CPU0 ] | RCX=0000000000000000 RDX=00000000000000a1
00018521821i[CPU0 ] | RSP=0000000000008018 RBP=0000000000000000
00018521821i[CPU0 ] | RSI=0000000000000000 RDI=000000000010054c
00018521821i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00018521821i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00018521821i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00018521821i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00018521821i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf ZF af PF cf
00018521821i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00018521821i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | DS:0000( 0000| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | SS:0000( 0000| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | ES:0000( 0000| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | FS:0000( 0000| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | GS:0000( 0000| 0| 0) 00000000 00000000 0 0
00018521821i[CPU0 ] | MSR_FS_BASE:0000000000000000
00018521821i[CPU0 ] | MSR_GS_BASE:0000000000000000
00018521821i[CPU0 ] | RIP=00000000001001c1 (00000000001001c1)
00018521821i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000000000
00018521821i[CPU0 ] | CR3=0x00001000 CR4=0x00000020
(0).[18521821] [0x0000001001c1] 0008:00000000001001c1 (unk. ctxt): jmp .-2 (0x00
000000001001c1) ; ebfe
00018521821e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
My code for interrupts looks like this:
Code: Select all
align 16
GDTR64: ; Global Descriptors Table Register
dw gdt64_end - gdt64 - 1 ; limit of GDT (size minus one)
dq 0x0000000000001000 ; linear address of GDT
gdt64: ; This structure is copied to 0x0000000000001000
SYS64_NULL_SEL equ $-gdt64 ; Null Segment
dq 0x0000000000000000
SYS64_CODE_SEL equ $-gdt64 ; Code segment, read/execute, nonconforming
dq 0x0020980000000000 ; 0x00209A0000000000
SYS64_DATA_SEL equ $-gdt64 ; Data segment, read/write, expand down
dq 0x0000900000000000 ; 0x0020920000000000
gdt64_end:
IDTR64: ; Interrupt Descriptor Table Register
dw 256*16-1 ; limit of IDT (size minus one) (4096 bytes - 1)
dq 0x0000000000000000 ; linear address of IDT
IDTR64_Content: Times 4095 db 0
IDT_Setup:
mov qword[IDTR64+2], IDTR64_Content ;Set the IDT Pointer
;First clear interrupts.
cli ;Just to make sure.
;Set all the IDT Entrys! Well just the ones we will need for the
;ISR.
push 0
push isr0
call IDT_Set
push 1
push isr1
call IDT_Set
push 2
push isr2
call IDT_Set
push 3
push isr3
call IDT_Set
push 4
push isr4
call IDT_Set
push 5
push isr5
call IDT_Set
push 6
push isr6
call IDT_Set
push 7
push isr7
call IDT_Set
push 8
push isr8
call IDT_Set
push 9
push isr9
call IDT_Set
push 10
push isr10
call IDT_Set
push 11
push isr11
call IDT_Set
push 12
push isr12
call IDT_Set
push 13
push isr13
call IDT_Set
push 14
push isr14
call IDT_Set
push 15
push isr15
call IDT_Set
push 16
push isr16
call IDT_Set
push 17
push isr17
call IDT_Set
push 18
push isr18
call IDT_Set
push 19
push isr19
call IDT_Set
push 20
push isr20
call IDT_Set
push 21
push isr21
call IDT_Set
push 22
push isr22
call IDT_Set
push 23
push isr23
call IDT_Set
push 24
push isr24
call IDT_Set
push 25
push isr25
call IDT_Set
push 26
push isr26
call IDT_Set
push 27
push isr27
call IDT_Set
push 28
push isr28
call IDT_Set
push 29
push isr29
call IDT_Set
push 30
push isr30
call IDT_Set
push 31
push isr31
call IDT_Set
;IRQs
;Must set the PIC though..
push 0x20
push 0x11
call IOPort_Write_8
push 0xA0
push 0x11
call IOPort_Write_8
push 0x21
push 0x20
call IOPort_Write_8
push 0xA1
push 0x28
call IOPort_Write_8
push 0x21
push 0x04
call IOPort_Write_8
push 0xA1
push 0x02
call IOPort_Write_8
push 0x21
push 0x01
call IOPort_Write_8
push 0xA1
push 0x01
call IOPort_Write_8
push 0x21
push 0x0
call IOPort_Write_8
push 0xA1
push 0x0
call IOPort_Write_8
;Now actually set the IRQs
push 32
push irq0
call IDT_Set
push 33
push irq1
call IDT_Set
push 34
push irq3
call IDT_Set
push 35
push irq4
call IDT_Set
push 36
push irq5
call IDT_Set
push 37
push irq6
call IDT_Set
push 38
push irq7
call IDT_Set
push 39
push irq8
call IDT_Set
push 40
push irq9
call IDT_Set
push 41
push irq10
call IDT_Set
push 42
push irq11
call IDT_Set
push 43
push irq12
call IDT_Set
push 44
push irq13
call IDT_Set
push 45
push irq14
call IDT_Set
push 46
push irq15
call IDT_Set
lidt[IDTR64] ;Load the IDT in.
sti
call Main
;Input:
; - (int) Index
; - (int) Address
;Description Sets an IDT Entry.
IDT_Set_Return: dq 0
IDT_Set:
pop qword[IDT_Set_Return] ;Save the return address
pop rax ;Address
pop rdi ;Index
shl rdi, 4 ;Multiply by 16
add rdi, IDTR64_Content
;Offset Low
push rax ;Save it
;and rax, 0x0000ffff
stosw
pop rax
;Selector
push rax
mov ax, 0x8
stosw
pop rax
;Type And Attributes and Zero
push rax
mov ax, 0x8E00
stosw
pop rax
;Offset High
push rax ;Save it
shr rax, 16
;and rax, 0x0000ffff
stosw
pop rax
;Offset High Extra
shr rax, 32
;and rax, 0xffffffff
stosd
;Reserved
mov rax, 0
stosd
push qword[IDT_Set_Return] ;Restore the return address
ret ;Return
My 64 bit kernel code:
Code: Select all
[BITS 64]
Kernel64:
cli ; Clear the interrupt flag.
xor rax, rax ; aka r0
xor rbx, rbx ; aka r3
xor rcx, rcx ; aka r1
xor rdx, rdx ; aka r2
xor rsi, rsi ; aka r6
xor rdi, rdi ; aka r7
xor rbp, rbp ; aka r5
mov rsp, 0x8000 ; aka r4
xor r8, r8
xor r9, r9
xor r10, r10
xor r11, r11
xor r12, r12
xor r13, r13
xor r14, r14
xor r15, r15
mov ds, ax ; Clear the legacy segment registers
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax
;Now we want to create a stack for the Kernel
;mov rax, EndCode
;mov rbp, rax
;add rax, 4000
;mov rsp, rax
xor rax, rax
lgdt [GDTR64] ; Reload the GDT
call PIC_Setup
push 100
call PIT_Setup
jmp IDT_Setup
Main:
mov rax, 0xB8000
mov byte[rax], 'h'
jmp os_hang
I cannot figure out what's wrong, weather its the GDT, or the IDT. I would assume IDT but I used the Bochs debugger and no luck there. Thanks, Matt
Though my best hint, would be that there is something wrong with storing the entry address, I think that might be the problem but there really isn't any docs on storing that.