Interrupts aren't working after liballoc porting
Interrupts aren't working after liballoc porting
I'm decided to port liballoc. Everything compiled, I've linked it with my kernel, but now interrupts aren't working. Exceptions and IRQs are doing nothing, my system calls reset the system. Bochs telled me that it's a triple fault, and it caused by int 0x80. I'm installing all exception, IRQ and system call handlers.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Interrupts aren't working after liballoc porting
That reads like a form of self-deception. Bochs has a good debugger, have you checked what the IDT, GDT and TSS entries are really like when things crash, and perhaps what they are when you "install" them? I would have expected that to be done as the first thing.it's a triple fault
(...)
I'm installing all exception, IRQ and system call handlers.
Re: Interrupts aren't working after liballoc porting
Looks like everything is good. So I don't know, where's the problem.
Code: Select all
<bochs:6> sreg
es:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x0008, dh=0x00cf9b00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
gdtr:base=0x000000000167af53, limit=0xffff
idtr:base=0x000000000166a640, limit=0x7ff
<bochs:7>
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Interrupts aren't working after liballoc porting
Is your liballoc ported in kernel or userland ?
i'll assume its the first.
Some hints:
* Check liballoc is correctly initialised. It has some global symbols . Either follow the wiki about CRT.o files, either create a function that reset their values.
* I"d avoid doing syscalls in your kmalloc function. Especially if some of yours syscalls needs to malloc some memory.
* Check your CR2 register. if it's not null you may have a page fault somewhere.
* Check the functions that gives/takes pages to liballoc are working and give present pages. if it's okay, you probably have a buffer overflow somewhere.
* if you have 2MB pages, check you give 1 page at the time ( the default is 16 if I recall). Bochs gives only 32Mb if you don't change that setting.
Good luck. I use liballoc for my 64bit kernel and it works well.
i'll assume its the first.
Some hints:
* Check liballoc is correctly initialised. It has some global symbols . Either follow the wiki about CRT.o files, either create a function that reset their values.
* I"d avoid doing syscalls in your kmalloc function. Especially if some of yours syscalls needs to malloc some memory.
* Check your CR2 register. if it's not null you may have a page fault somewhere.
* Check the functions that gives/takes pages to liballoc are working and give present pages. if it's okay, you probably have a buffer overflow somewhere.
* if you have 2MB pages, check you give 1 page at the time ( the default is 16 if I recall). Bochs gives only 32Mb if you don't change that setting.
Good luck. I use liballoc for my 64bit kernel and it works well.
Re: Interrupts aren't working after liballoc porting
There's my liballoc's u365.c:
Code: Select all
/*
U365 compatibility code for liballoc.
Liballoc needs these function as a "glue"
to make porting more simple.
*/
//First we have a system call functions - we need them, so we can "talk" with system.
void* alloc_pages(int cnt)
{
void* ret=0;
//System calls in U365 are accessed using interrupt vector 0x80, so we need some assembly code.
asm("mov $2, %%eax;\
mov %1, %%ebx;\
int $0x80;\
mov %%edx, %0;" : "=g" (ret) : "g" (cnt));
return ret;
}
static int page_size = -1;
int liballoc_lock() //We have no multitasking/threading, so just return.
{
return 0;
}
int liballoc_unlock() //We have no multitasking/threading, so just return.
{
return 0;
}
int getpagesize()
{
int ret=0;
//System calls in U365 are accessed using interrupt vector 0x80, so we need some assembly code.
asm(".intel_syntax noprefix;\
mov eax, 1;\
int 0x80;\
mov %0, ebx;\
.att_syntax prefix" : "=g" (ret));
return ret;
}
void* liballoc_alloc( int pages )
{
if ( page_size < 0 ) page_size = getpagesize();
return alloc_pages(pages);
}
int liballoc_free( void* ptr, int pages )
{
return 0;
}
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Interrupts aren't working after liballoc porting
I don't have paging yet. Yes, I've ported liballoc in kernel and linked it with other kernel files. And I can use my OS without any crashes before I'll call malloc.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Interrupts aren't working after liballoc porting
GCC can and will generate bad code around this. You must use appropriate constraints on your inline assembly.catnikita255 wrote:Code: Select all
asm("mov $2, %%eax;\ mov %1, %%ebx;\ int $0x80;\ mov %%edx, %0;" : "=g" (ret) : "g" (cnt));
I am not an expert on inline assembly, so there may be other problems that I did not see, but the correct code looks similar to this:
Code: Select all
asm("int $0x80;" : "=d" (ret) : "a" (2), "b" (cnt));
This inline assembly has the same problem.catnikita255 wrote:Code: Select all
asm(".intel_syntax noprefix;\ mov eax, 1;\ int 0x80;\ mov %0, ebx;\ .att_syntax prefix" : "=g" (ret));
Again, I am not an expert, but the correct code looks like this:
Code: Select all
asm("int $0x80;" : "=b" (ret) : "a" (1));
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Interrupts aren't working after liballoc porting
A triple fault in bochs is one of the easiest thing to debug absolutely. You get error messages, you get the crashing instruction, you can inspect the exact CPU state, and you have full lists of causes for any exception and pseudocode on how exceptions get handled, as well as individual instructions.
Perform your int 0x80 by hand. No guesswork allowed at any step, No shortcuts allowed at any step. Do exactly what the manual says should happen and compare every step with what you would expect to happen. That's what debugging is. That is what you should be able to do as an OS developer.
What you really should not do is dump random segment registers in response to a request for GDT contents. That's just demonstrates that there's something stuck between keyboard and chair with a lack of reading ability, and that your memory management stinks and misaligns your GDT. You can do better than that.
Perform your int 0x80 by hand. No guesswork allowed at any step, No shortcuts allowed at any step. Do exactly what the manual says should happen and compare every step with what you would expect to happen. That's what debugging is. That is what you should be able to do as an OS developer.
What you really should not do is dump random segment registers in response to a request for GDT contents. That's just demonstrates that there's something stuck between keyboard and chair with a lack of reading ability, and that your memory management stinks and misaligns your GDT. You can do better than that.
Re: Interrupts aren't working after liballoc porting
int 0x80 doesn't work in any cases. When I calling exception handlers by hand - nothing. But int 0x80 triple-faults.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Interrupts aren't working after liballoc porting
So single-step it in a debugger and see where it is going wrong. You've probably screwed up your stack; that's a popular source of triple faults.
Re: Interrupts aren't working after liballoc porting
Something is wrong with code segment. There's a Bochs output:
So, something is wrong with my GDT.
Code: Select all
00157995456e[CPU0 ] interrupt(): not accessible or not code segment cs=0x0008
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Interrupts aren't working after liballoc porting
Code: Select all
gdtr:base=0x000000000167af53, limit=0xffff
If a trainstation is where trains stop, what is a workstation ?
Re: Interrupts aren't working after liballoc porting
It's not required.gerryg400 wrote:Try aligning your gdt on a 8 byte boundary.Code: Select all
gdtr:base=0x000000000167af53, limit=0xffff
Re: Interrupts aren't working after liballoc porting
I know. However some years ago there was a thread where someone discovered that it was required on one of the emulators - maybe Bochs but I'm not sure.alexfru wrote:It's not required.gerryg400 wrote:Try aligning your gdt on a 8 byte boundary.Code: Select all
gdtr:base=0x000000000167af53, limit=0xffff
If a trainstation is where trains stop, what is a workstation ?
Re: Interrupts aren't working after liballoc porting
Perhaps not required, but it is so easy to do that it is silly to kill performance by not doing so. It's important enough that Intel make a point of recommending it.alexfru wrote:It's not required.gerryg400 wrote:Try aligning your gdt on a 8 byte boundary.Code: Select all
gdtr:base=0x000000000167af53, limit=0xffff