I am developing an operating system as an hobby, and I'm having a strange issue when handling keyboard IRQ, I don't know why but I'm getting an Invalid Op Code ISR when too few string is presents in the code, and a breakpoint ISR when adding a little more string.
If I add a sufficient amount of string, the code works as excepted, and nothing goes wrong, but I can't just add string in the code and ignore the problem without understanding it...
Here is my ISR/IRQ handler (first argument of the macro is "isr" or "irq", second argument is the c handler, third argument is present only if handling irq)
%macro handler_macro 2-3
handle_%+%1:
pusha
mov ax, ds
push eax ; save data segment
mov esi, eax
mov ax, 0x10
mov ds, ax
mov es, ax
mov gs, ax
mov fs, ax ; set data segments
push esp ; push the stack for the first arg of the c function
call %2
pop esp ; pop the pushed stack
%if %0 = 3
pop ebx
mov ebx, esi
mov ds, bx
mov es, bx
mov gs, bx
mov fs, bx
%else
pop eax
mov eax, esi
mov ds, ax
mov es, ax
mov gs, ax
mov fs, ax ; restore data segments
%endif
popa
add esp, 8 ; Remove the 2 params that's left in the stack
sti ; reenable interrupts
iret
%endmacro
And there is the C handler for irq
/*
Structure in .h:
typedef struct reg_s {
unsigned int eax_save;
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
unsigned int code;
unsigned int error;
//unsigned int eip, cs, eflags, useresp, ss;
} reg_t;
*/
void irq_handler(reg_t *test)
// Getting ISR 6 when all printfs are commented
//printf("IRQ: %d\n", test->code); Uncommenting this one adds keeps on ISR 6
//printf(""); Same
//printf(""); Same
//printf(""); Uncommenting this one make the program works
if (handler_fun[test->code] != NULL) {
void (*fun)(void) = (void (*)(void)) handler_fun[test->code];
//printf("Fun: %p\n", fun);
fun();
}
pic_send_eio(test->code);
}
In case this could help the value of the fun pointer doesn't change from one test to another, and a difference that could (maybe?) change something is that by uncommenting the 4 printfs, the number of sector readed from disk switch from 45 to 46
In case anyone stumble on this, I found where this was comming from.
This was a really poor error just based on where I loaded the kernel in memory.
Basically, at some point when I added some bytes, gcc optimized the program to align the address of the functions correctly in memory, which caused the program to grow slightly more.
This slight increase in the kernel size made the kernel overwrite the stack a bit, which caused a panic in the system.
So for anyone who stumble on the same thing : Just check that your kernel and stack are correctly placed (and also that your kernel doesn't overwrite the bootloader by error before you perfom the far jump)
And another advice that I would give to avoid this dumb kind of error : Just write a multi-stage bootloader, this way you will be able to unlock more memory, put your kernel above the 1MB bareer, and in addition to have a more advanced bootloader, you will not stumble into this kind of error.