Page 2 of 3
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 7:48 pm
by MichaelPetch
The fact it is ignoring -T *is* a serious problem. As a result The linker script (Linker.ld) you are specifying is being ignored. What happens when you remove `-z`. That `-z` is bogus but the `-T` after it is not.
You can believe whatever you want about whatever options you are using but I can tell you this - Until you ultimately fix your linker options you are going to tear you hair out trying to fix that 0x804xxxxxx address causing all kinds of problem. Your triple fault right now is because you are telling the processor to go to a bogus memory address that doesn't actually have a service routine at it. I will make you a bet that you have a bunch of 0x804..... addresses in your kernel where mine looks like this:
Code: Select all
objdump -x _build/iso/System/Kernel/NovaVita.kernel
_build/iso/System/Kernel/NovaVita.kernel: file format elf32-i386
_build/iso/System/Kernel/NovaVita.kernel
architecture: i386, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x00101288
Program Header:
LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12
filesz 0x00001000 memsz 0x00001000 flags r--
LOAD off 0x00002000 vaddr 0x00101000 paddr 0x00101000 align 2**12
filesz 0x00004004 memsz 0x0000d000 flags rwx
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rwx
Sections:
Idx Name Size VMA LMA File off Algn
0 .multiboot 00001000 00100000 00100000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00002000 00101000 00101000 00002000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00001000 00103000 00103000 00004000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .eh_frame 000000fc 00104000 00104000 00005000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .data 00000f08 001040fc 001040fc 000050fc 2**2
CONTENTS, ALLOC, LOAD, DATA
5 .gdt 00000ffc 00105004 00105004 00006004 2**0
ALLOC
6 .bss 00008000 00106000 00106000 00006004 2**12
ALLOC
7 .comment 0000003d 00000000 00000000 00006004 2**0
CONTENTS, READONLY
8 .gnu_debuglink 0000001c 00000000 00000000 00006044 2**2
CONTENTS, READONLY
SYMBOL TABLE:
no symbols
You'll note I don't have addresses that start with 0x804.... and this is what happens every time a timer interrupt fires is:
Code: Select all
0: v=08 e=0000 i=0 cpl=0 IP=0008:001012a2 pc=001012a2 SP=0010:0010a000 env->regs[R_EAX]=001032f0
When I press a key I get an interrupt and it doesn't triple fault and it looks like this:
Code: Select all
v=09 e=0000 i=0 cpl=0 IP=0008:001012a2 pc=001012a2 SP=0010:0010a000 env->regs[R_EAX]=001032f0
Once you remap the PIC(s) and create proper entries in your IDT and service routines for them you are going to still encounter triple faults. You can ignore the problem I am telling you about and you will be back here asking why it is still faulting on you.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 7:51 pm
by austanss
Alright, so I wrote the PIC controller configuration function. As it is C++ code, do I extern it as C and call it from assembly? Or would I ideally call it in loadGDT/loadIDT?
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 7:57 pm
by Octocontrabass
It doesn't matter too much when you call it, as long as you call it before you set the interrupt flag. (You probably can't call it before your global constructors if it's C++ code.)
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 7:59 pm
by austanss
MichaelPetch wrote:The fact it is ignoring -T *is* a serious problem. As a result The linker script (Linker.ld) you are specifying is being ignored. What happens when you remove `-z`. That `-z` is bogus but the `-T` after it is not.
You can believe whatever you want about whatever options you are using but I can tell you this - Until you ultimately fix your linker options you are going to tear you hair out trying to fix that 0x804xxxxxx address causing all kinds of problem. Your triple fault right now is because you are telling the processor to go to a bogus memory address that doesn't actually have a service routine at it. I will make you a bet that you have a bunch of 0x804..... addresses in your kernel where mine looks like this:
Code: Select all
objdump -x _build/iso/System/Kernel/NovaVita.kernel
_build/iso/System/Kernel/NovaVita.kernel: file format elf32-i386
_build/iso/System/Kernel/NovaVita.kernel
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00101278
Program Header:
PHDR off 0x00000034 vaddr 0x000ff034 paddr 0x000ff034 align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags r--
INTERP off 0x000050fc vaddr 0x001040fc paddr 0x001040fc align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x000ff000 paddr 0x000ff000 align 2**12
filesz 0x00002000 memsz 0x00002000 flags r--
LOAD off 0x00002000 vaddr 0x00101000 paddr 0x00101000 align 2**12
filesz 0x00004094 memsz 0x0000d000 flags rwx
DYNAMIC off 0x00006004 vaddr 0x00105004 paddr 0x00105004 align 2**2
filesz 0x00000090 memsz 0x00000090 flags rw-
EH_FRAME off 0x0000513c vaddr 0x0010413c paddr 0x0010413c align 2**2
filesz 0x00000044 memsz 0x00000044 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rwx
Dynamic Section:
GNU_HASH 0x00104124
STRTAB 0x00104120
SYMTAB 0x00104110
STRSZ 0x00000001
SYMENT 0x00000010
DEBUG 0x00000000
REL 0x00104180
RELSZ 0x00000a40
RELENT 0x00000008
TEXTREL 0x00000000
FLAGS 0x0000000c
FLAGS_1 0x08000001
RELCOUNT 0x00000148
Sections:
Idx Name Size VMA LMA File off Algn
0 .multiboot 00001000 00100000 00100000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00002000 00101000 00101000 00002000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00001000 00103000 00103000 00004000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .eh_frame 000000fc 00104000 00104000 00005000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .interp 00000013 001040fc 001040fc 000050fc 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynsym 00000010 00104110 00104110 00005110 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .dynstr 00000001 00104120 00104120 00005120 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.hash 00000018 00104124 00104124 00005124 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .eh_frame_hdr 00000044 0010413c 0010413c 0000513c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rel.dyn 00000a40 00104180 00104180 00005180 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .data 00000444 00104bc0 00104bc0 00005bc0 2**2
CONTENTS, ALLOC, LOAD, DATA
11 .dynamic 00000090 00105004 00105004 00006004 2**2
CONTENTS, ALLOC, LOAD, DATA
12 .gdt 00000f6c 00105094 00105094 00006094 2**0
ALLOC
13 .bss 00008000 00106000 00106000 00006094 2**12
ALLOC
14 .comment 0000003d 00000000 00000000 00006094 2**0
CONTENTS, READONLY
15 .gnu_debuglink 0000001c 00000000 00000000 000060d4 2**2
CONTENTS, READONLY
SYMBOL TABLE:
no symbols
You'll note I don't have addresses that start with 0x804.... and this is what happens every time a timer interrupt fires is:
Code: Select all
0: v=08 e=0000 i=0 cpl=0 IP=0008:001012a2 pc=001012a2 SP=0010:0010a000 env->regs[R_EAX]=001032f0
When I press a key I get an interrupt and it doesn't triple fault and it looks like this:
Code: Select all
v=09 e=0000 i=0 cpl=0 IP=0008:001012a2 pc=001012a2 SP=0010:0010a000 env->regs[R_EAX]=001032f0
Once you remap the PIC(s) and create proper entries in ISR.asm you are going to still encounter triple faults. You can ignore the problem I am telling you about and you will be back here asking why it is still faulting on you.
You Are A Legend. I Love You. Thank You So Much.
The triple faults are gone, however the interrupts don't work. Most likely because of my handler logic.
My hate for you used to be agonizing, but now you have exposed me to my flaws, and your righteousness.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 8:23 pm
by austanss
Octocontrabass wrote:It doesn't matter too much when you call it, as long as you call it before you set the interrupt flag. (You probably can't call it before your global constructors if it's C++ code.)
Sorry for a dumb question, but what are the parameters I am supposed to pass? The parameters are
offset1 and
offset2, both of type
int.
Got the function from https://wiki.osdev.org/8259_PIC#Program ... e_8259_PIC
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 8:32 pm
by Octocontrabass
The page you copied the code from explains what those parameters are and gives an example for how you might set them.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 8:34 pm
by austanss
Octocontrabass wrote:The page you copied the code from explains what those parameters are and gives an example for how you might set them.
In the hacker land, these people are referred to as script kiddies, the most annoying and intolerable known to man.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 8:56 pm
by Octocontrabass
There are also links to other pages
like this one that might explain it more clearly.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 9:16 pm
by austanss
Octocontrabass wrote:There are also links to other pages
like this one that might explain it more clearly.
I still don't know what I'm supposed to set those parameters as...
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 9:19 pm
by Octocontrabass
Code: Select all
/*
arguments:
offset1 - vector offset for master PIC
vectors on the master become offset1..offset1+7
offset2 - same for slave PIC: offset2..offset2+7
*/
You're supposed to set each one to the vector offset for each PIC.
Pick the vector offset based on which interrupt vectors you want to use for each PIC.
It's common to use 0x20 and 0x28 since those are the first available vectors after the ones reserved for exceptions, but it's your OS so you can choose whatever you want.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 9:54 pm
by austanss
Octocontrabass wrote:Code: Select all
/*
arguments:
offset1 - vector offset for master PIC
vectors on the master become offset1..offset1+7
offset2 - same for slave PIC: offset2..offset2+7
*/
You're supposed to set each one to the vector offset for each PIC.
Pick the vector offset based on which interrupt vectors you want to use for each PIC.
It's common to use 0x20 and 0x28 since those are the first available vectors after the ones reserved for exceptions, but it's your OS so you can choose whatever you want.
I did all this, fine and dandy, I configure PIC and all. I wrote a simple IRQ handler that prints a keycode if possible. Not sure if it worked, but either way I wrote the function to print the interrupt number code. When attempting to trigger an interrupt (e.g. pressing the keyboard) I get no response. Not sure about the keyboard, as I'm using QEMU, and a USB keyboard, and my driver only supports PS/2, and I'm unsure if QEMU (from command line, no established VM) uses PS/2 emulation by default. Either way, nothing is happening from the IRQ handler. I've made sure that the IRQ handler is externed as C.
Relevant: the repo - files "GDT.cpp" and "ISR.asm"
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 10:02 pm
by Octocontrabass
Did you set the interrupt flag?
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 10:05 pm
by austanss
Octocontrabass wrote:Did you set the interrupt flag?
No, I suppose I should do that... uh, how do I do that?? I thought it happened automatically, but in hindsight I didn't really see an attributes or anything on the handler function.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 10:09 pm
by Octocontrabass
The STI instruction sets the interrupt flag. If the interrupt flag is clear, the CPU will not receive any interrupts from external hardware.
Re: Very lost on botched interrupts causing triple fault
Posted: Mon Oct 12, 2020 10:13 pm
by austanss
Octocontrabass wrote:The STI instruction sets the interrupt flag. If the interrupt flag is clear, the CPU will not receive any interrupts from external hardware.
oh i uh. i already have that instruction.
from Boot.S
Code: Select all
_start:
/* stack */
mov $stack_top, %esp
cli
call loadGDT
mov %cr0, %eax
or 1, %al
mov %eax, %cr0
call loadIDT
call configurePIC
jmp $0x8, $protectedModeMain
protectedModeMain:
sti
/* here we call kernel_main */
call kernel_main