IDT
IDT
Hi,
I have had problems with the idt (software interrupts specifically) while using c for a while. I know assembly and have built a handler in assembly and when I call a interrupt(s) in assembly from a assembly kernel it does what I want it to do but, when I use most of the same code for my C kernel it doesn't work (just tripple faults). So, after spending weeks trying to fix it I went to the James Molloy Kernel Development tutorial and looked at how they implemented the idt. I then coded a similer version of it for my os just to see if it worked and it didn't. If you answer this question here is some more info:
I used nasm not another assembler or inline asm
I am coding the kernel in c (compilier is gcc)
For those of you who say "The OSDev.org wiki - Got a question? Search this first" to answer your question yes I have looked at it and I do understand what the tutorials are saying. I would appreciate it if you would answer the question of what you think the problem with implimenting the idt in asm and calling a interrupt in c and how to fix it.
Thank you,
Jackson
I have had problems with the idt (software interrupts specifically) while using c for a while. I know assembly and have built a handler in assembly and when I call a interrupt(s) in assembly from a assembly kernel it does what I want it to do but, when I use most of the same code for my C kernel it doesn't work (just tripple faults). So, after spending weeks trying to fix it I went to the James Molloy Kernel Development tutorial and looked at how they implemented the idt. I then coded a similer version of it for my os just to see if it worked and it didn't. If you answer this question here is some more info:
I used nasm not another assembler or inline asm
I am coding the kernel in c (compilier is gcc)
For those of you who say "The OSDev.org wiki - Got a question? Search this first" to answer your question yes I have looked at it and I do understand what the tutorials are saying. I would appreciate it if you would answer the question of what you think the problem with implimenting the idt in asm and calling a interrupt in c and how to fix it.
Thank you,
Jackson
Re: IDT
There's nothing wrong with what you're doing. You have a bug. I would recommend some code review.I would appreciate it if you would answer the question of what you think the problem with implimenting the idt in asm and calling a interrupt in c and how to fix it.
If a trainstation is where trains stop, what is a workstation ?
Re: IDT
I don't think that's important with respect to your problem with your C kernel.sds2017 wrote:Well I have tested the code in my assembly kernel and it worked flawlessly.
My feeling is that you haven't supplied enough information to guarantee that others can help you. I recommended code-review. One method of code review is to post your code.
If a trainstation is where trains stop, what is a workstation ?
Re: IDT
Okay here's the code it's lengthy but pretty simple I know that I can make macro's but the sake of testing I did this:
I understand your point of the code but if you can explain to me why it doesn't work in C then your right. The only reason I say it has something to do with C is because it works in assembly. the way I impliment this code is by this in C:
and in the hal init function
Code: Select all
%define base_addr 0x100000
msg db "Exeption Handler: an unhandled interrupt has occured...", 0xA, 0
;Hardware Interrupts
EnableIrq:
;ICW1
mov al, 0x11 ;00010001
out 0x20, al
out 0xA0, al
;ICW2
mov al, 0x20
out 0x21, al ;(0x21 & 0xA1)port for all the other ICW's, 0x20 (32) because there are 31 hardware ints
mov al, 0x28
out 0xA1, al ;0x28(40) because there are 8 irqs per PIC is
;ICW3(Only allows keyboard interrupts)
mov al, 0x4
out 0x21, al ;00000100
mov al, 0x2
out 0xA1, al ;010
;ICW4
mov al, 0x1
out 0x21, al ;000001
out 0xA1, al ;000001
mov al, 0
out 0x21, al
out 0xA1, al
ret
;Software Interrupts
isr0:
cli
push byte 0
push byte 0
jmp handler
isr1:
cli
push byte 0
push byte 1
jmp handler
isr2:
cli
push byte 0
push byte 2
jmp handler
isr3:
cli
push byte 0
push byte 3
jmp handler
isr4:
cli
push byte 0
push byte 4
jmp handler
isr5:
cli
push byte 0
push byte 5
jmp handler
isr6:
cli
push byte 0
push byte 6
jmp handler
isr7:
cli
push byte 0
push byte 7
jmp handler
isr8:
cli
push byte 8
jmp handler
isr9:
cli
push byte 0
push byte 9
jmp handler
isr10:
cli
push byte 10
jmp handler
isr11:
cli
push byte 11
jmp handler
isr12:
cli
push byte 12
jmp handler
isr13:
cli
push byte 13
jmp handler
isr14:
cli
push byte 14
jmp handler
isr15:
cli
push byte 0
push byte 15
jmp handler
isr16:
cli
push byte 0
push byte 16
jmp handler
isr17:
cli
push byte 0
push byte 17
jmp handler
isr18:
cli
push byte 0
push byte 18
jmp handler
isr19:
cli
push byte 0
push byte 19
jmp handler
isr20:
cli
push byte 0
push byte 20
jmp handler
isr21:
cli
push byte 0
push byte 21
jmp handler
isr22:
cli
push byte 0
push byte 22
jmp handler
isr23:
cli
push byte 0
push byte 23
jmp handler
isr24:
cli
push byte 0
push byte 24
jmp handler
isr25:
cli
push byte 0
push byte 25
jmp handler
isr26:
cli
push byte 0
push byte 26
jmp handler
isr27:
cli
push byte 0
push byte 27
jmp handler
isr28:
cli
push byte 0
push byte 28
jmp handler
isr29:
cli
push byte 0
push byte 29
jmp handler
isr30:
cli
push byte 0
push byte 30
jmp handler
isr31:
cli
push byte 0
push byte 31
jmp handler
irq0:
cli
push byte 0
push byte 32
jmp irq_handler
irq1:
cli
push byte 0
push byte 33
jmp irq_handler
irq2:
cli
push byte 0
push byte 34
jmp irq_handler
irq3:
cli
push byte 0
push byte 35
jmp irq_handler
irq4:
cli
push byte 0
push byte 36
jmp irq_handler
irq5:
cli
push byte 0
push byte 37
jmp irq_handler
irq6:
cli
push byte 0
push byte 38
jmp irq_handler
irq7:
cli
push byte 0
push byte 39
jmp irq_handler
irq8:
cli
push byte 0
push byte 40
jmp irq_handler
irq9:
cli
push byte 0
push byte 41
jmp irq_handler
irq10:
cli
push byte 0
push byte 42
jmp irq_handler
irq11:
cli
push byte 0
push byte 43
jmp irq_handler
irq12:
cli
push byte 0
push byte 44
jmp irq_handler
irq13:
cli
push byte 0
push byte 45
jmp irq_handler
irq14:
cli
push byte 0
push byte 46
jmp irq_handler
irq15:
cli
push byte 0
push byte 47
jmp irq_handler
irq_handler:
pusha
mov ax, ds
push eax
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebx, msg
call Print32
mov al, 0x20
out 0xA0, al
out 0x20, al
pop ebx
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa
add esp, 8
sti
iret
handler:
pusha
mov ax, ds
push eax
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebx, msg
call Print32
pop ebx
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa
add esp, 8
sti
iret
[GLOBAL InstallIDT]
InstallIDT:
cli
pusha
lidt [load]
popa
ret
_CurY db 0
_CurX db 0
%define VIDMEM 0xB8000
%define COLS 80
%define LINES 25
%define CHAR_ATTRIB 0x02
PrintChar32:
pusha
mov edi, VIDMEM
xor eax, eax
mov ecx, COLS*2
mov al, byte [_CurY]
mul ecx
push eax
mov al, byte [_CurX]
mov cl, 2
mul cl
pop ecx
add eax, ecx
xor ecx, ecx
add edi, eax
cmp bl, 0x0A
je .Row
cmp bl, 0x08
je .Backspace
mov dl, bl
mov dh, CHAR_ATTRIB
mov word [edi], dx
inc byte [_CurX]
jmp .done
.Backspace:
cmp byte [_CurX], 2
je .done
dec byte [_CurX]
mov bl, " "
call PrintChar32
dec byte [_CurX]
jmp .done
.Row:
mov byte [_CurX], 0
inc byte [_CurY]
.done:
popa
ret
Print32:
pusha
push ebx
pop edi
.loop:
mov bl, byte [edi]
cmp bl, 0
je .done
call PrintChar32
inc edi
jmp .loop
.done:
mov bh, byte [_CurY]
mov bl, byte [_CurX]
call MovCur
popa
ret
MovCur:
pusha
xor eax, eax
mov ecx, COLS
mov al, bh
mul ecx
add al, bl
mov ebx, eax
mov al, 0x0f
mov dx, 0x03D4
out dx, al
mov al, bl
mov dx, 0x03D5
out dx, al
xor eax, eax
mov al, 0x0e
mov dx, 0x03D4
out dx, al
mov al, bh
mov dx, 0x03D5
out dx, al
popa
ret
GotoXY:
pusha
mov [_CurX], al
mov [_CurY], ah
popa
ret
idt_data:
dw (base_addr + isr0 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr1 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr2 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr3 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr4 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr5 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr6 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr7 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr8 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr9 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr10 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr11 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr12 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr13 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr14 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr15 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr16 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr17 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr18 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr19 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr20 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr21 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr22 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr23 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr24 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr25 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr26 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr27 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr28 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr29 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr30 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
dw (base_addr + isr31 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + handler - $$) >> 16
;irq0
dw (base_addr + irq0 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq0 - $$) >> 16
;irq1
dw (base_addr + irq1 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq1 - $$) >> 16
;irq2
dw (base_addr + irq2 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq2 - $$) >> 16
;irq3
dw (base_addr + irq3 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq3 - $$) >> 16
;irq4
dw (base_addr + irq4 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq4 - $$) >> 16
;irq5
dw (base_addr + irq5 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq5 - $$) >> 16
;irq6
dw (base_addr + irq6 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq6 - $$) >> 16
;irq7
dw (base_addr + irq7 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq7 - $$) >> 16
;irq8
dw (base_addr + irq8 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq8 - $$) >> 16
;irq9
dw (base_addr + irq9 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq9 - $$) >> 16
;irq10
dw (base_addr + irq10 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq10 - $$) >> 16
;irq11
dw (base_addr + irq11 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq11 - $$) >> 16
;irq12
dw (base_addr + irq12 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq12 - $$) >> 16
;irq13
dw (base_addr + irq13 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq13 - $$) >> 16
;irq14
dw (base_addr + irq14 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq14 - $$) >> 16
;irq15
dw (base_addr + irq15 - $$) & 0xFFFF
dw 0x8
db 0x0
db 0x8E
dw (base_addr + irq15 - $$) >> 16
end_of_idt:
load:
dw end_of_idt - idt_data - 1
dd idt_data
Code: Select all
extern void InstallIDT();
Code: Select all
void init_hal()
{
InstallGDT
InstallIDT
}
Last edited by Brendan on Mon Jan 09, 2012 9:19 pm, edited 1 time in total.
Reason: Code tags..
Reason: Code tags..
Re: IDT
I haven't actually read any of your code, but you do realize the code you posted does nothing at all:
This doesn't call any functions and, really, doesn't do anything. You should really compile with all warnings enabled and it should warn about this. Either that or you didn't copy your code properly, in which case there's a reason to read the rest of your code .
Code: Select all
void init_hal()
{
InstallGDT
InstallIDT
}
Re: IDT
actually i did put InstallIDT(); and the warnings are enabled I just accidentally wrote that because I had been working on other functions in the Hal function so I just wrote that part in the forum Sorry about that... Here's what it actually looked like:
#include <HAL.h>
#include <console.h>
extern void InstallIDT();
void init_hal()
{
InstallGDT();
InstallIDT();
}
I promise you I've looked at this code since Thanksgiving.
#include <HAL.h>
#include <console.h>
extern void InstallIDT();
void init_hal()
{
InstallGDT();
InstallIDT();
}
I promise you I've looked at this code since Thanksgiving.
Re: IDT
It tripple faults when a interrupt is occurs. It works fine if you don't call a interrupt. Also idt_data is just the start to the end of the code of the idt (It's the function after GotoXY). As I said in earlier posts it works when I call it from assembly but when I declare a external function in c and call it their it doesn't.
Re: IDT
I understand where the idt_data is, but is it a physical address? E.g. are you using "org 0" for this source file? Because lidt expects the address to be physical, not virtual.sds2017 wrote:It tripple faults when a interrupt is occurs. It works fine if you don't call a interrupt. Also idt_data is just the start to the end of the code of the idt (It's the function after GotoXY). As I said in earlier posts it works when I call it from assembly but when I declare a external function in c and call it their it doesn't.
If not, put a magic breakpoint before the interrupt call, then have a look at the gdt and idt to see if they are what you expect them to be.
Re: IDT
No I didn't put org because the assembler wouldn't let me but, still how could the idt work in an assembly kernel; my assembly kernel doesn't use org in it anywhere. So logically yes, it does use the physical address. My asm kernel uses my custom bootloader and my c uses grub, in my c kernel I tried to load the idt in the entry file but grub didn't like that so it didn't boot saying that you cannot do that.
Re: IDT
I like this one! I just spent a week, day and night finding a bug related with interrupts.berkus wrote:2. debug till you bleed
I'm writing a toy os and my current goal is to resemble, simplify and understand the linux kernel. In the early stage, it's designed to be a UP/UMA preemptive kernel and will be extended to support SMP/NUMA etc in the future.
Re: IDT
sds2017 wrote:Hi,
I have had problems with the idt (software interrupts specifically) while using c for a while. I know assembly and have built a handler in assembly and when I call a interrupt(s) in assembly from a assembly kernel it does what I want it to do but, when I use most of the same code for my C kernel it doesn't work (just tripple faults). So, after spending weeks trying to fix it I went to the James Molloy Kernel Development tutorial and looked at how they implemented the idt. I then coded a similer version of it for my os just to see if it worked and it didn't. If you answer this question here is some more info:
I used nasm not another assembler or inline asm
I am coding the kernel in c (compilier is gcc)
For those of you who say "The OSDev.org wiki - Got a question? Search this first" to answer your question yes I have looked at it and I do understand what the tutorials are saying. I would appreciate it if you would answer the question of what you think the problem with implimenting the idt in asm and calling a interrupt in c and how to fix it.
Thank you,
Jackson
1, Make sure you're familiar with interaction between assembly code and c code
2, Check every byte and every bit within IDT. Trust me.
3, Be careful when you enable or disable local interrupts using sti or cli.
I'm writing a toy os and my current goal is to resemble, simplify and understand the linux kernel. In the early stage, it's designed to be a UP/UMA preemptive kernel and will be extended to support SMP/NUMA etc in the future.
Re: IDT
Sorry about that I just realized that code only works on a flat binary which is what my asm kernel was compiled to while my c kernel was compiled to elf. I've recoded the thing in C and I've got it to work. Thank you for your help.