Page 1 of 1
A mystery IDT/ISR issue!
Posted: Fri Jun 19, 2009 4:20 am
by ScorchOS
I have been coding a new kernel in FreeBASIC. The basic set of commands such as memset(), memsetw(), memcpy() and strlen work within temp_vital.bi and I have a fully functioning GDT in gdt.bi. The project originally started out as the FreeBASIC barebones tutorial but has changed a lot since!
I have become stumped on the IDT/ISR implementation. All source code is available here:
http://code.google.com/p/scorchos/sourc ... es/lantern
I have gone through the code within idt.bi and isr.bi eliminating all syntax errors (I discovered a rogue 'ret' statement in some inline assembly which was causing my test virtual machine to reset constantly for instance!).
Within the ISR I have broken down the ASM source for the ISRs you see in the bkerndev tutorial into FreeBASIC subroutines containing inline assembly followed by a call to a subroutine named 'isr_common_stub()' (containing yet more inline ASM). Could this potentially be the issue? (I am swotting up a bit on my ASM knowledge just in case!). Other than that I can't see what is wrong with the IDT/ISR code - I have an implementation for the structure of a stack frame and both an IDT entry and IDT pointer. The IDT loads successfully into 'lidt'.
The reason I know my IDT implementation doesn't work is because I have tried using:
Code: Select all
Dim i As Integer = 1
i = 1/0 'This should cause a div/0 error and trigger the relevant interrupt!
within 'kernel.bas' in the main() function and recieved no response what-so-ever on boot!
If anyone has a few moments spare to take a look at this code I would very much appreciate that. I will post any further developments here to try and eliminate further issues.
Re: A mystery IDT/ISR issue!
Posted: Fri Jun 19, 2009 4:45 am
by jal
ScorchOS wrote:The reason I know my IDT implementation doesn't work is because I have tried using: (...) recieved no response what-so-ever on boot!
If there's anything wrong with the IDT, almost always you get some exception, causing a triple fault. That nothing at all happens may point to some other problems.
JAL
Re: A mystery IDT/ISR issue!
Posted: Fri Jun 19, 2009 6:01 am
by kop99
ScorchOS, if you are using bochs, you could post log.
It can help us for debugging.
Re: A mystery IDT/ISR issue!
Posted: Fri Jun 19, 2009 4:19 pm
by Combuster
That's a floating point division (which you generally don't want in a kernel).... With the result being infinity converted back to a integer (which is not what you want at all)
try i \ 0 (integer division) rather than i / 0 (division with rounding)
Re: A mystery IDT/ISR issue!
Posted: Fri Jun 19, 2009 5:16 pm
by ScorchOS
@kop99: I'm using QEMU as my emulator at the moment (I've never tried Bochs), but if I continue to have problems I will try it out to see if it produces more useful output. Thanks for the tip
@combuster: I tried using your i = i\0. It does indeed work better (if you try i = 1\0 for instance the FreeBASIC compiler refuses to build the kernel on the basis it's a divide by zero). However, this currently just causes the machine to triple-fault and keep resetting rather than invoke an ISR. This suggests that I am causing a div\0 error but that my IDT is not linking to the ISRs properly?
@JAL: That is very true. It seems that now as I'm causing an error the ISR is not being invoked, which suggests a problem with the IDT. I will try experimenting to see if I'm not pointing to the functions correctly or whether there is a fundamental design issue with the IDT itself.
Thank you everyone for your help so far. I'm willing to welcome all ideas at this stage!
Re: A mystery IDT/ISR issue!
Posted: Sat Jun 20, 2009 1:54 am
by kop99
ScorchOS, here is your idt pointer structure.
Code: Select all
'...and pointer...
Type idt_ptr
size As UShort
baseAddr As UInteger
End Type
idt pointer structure is 6byte.
But in i386 arch, generally it might be 8byte aligned.
Make sure idt_ptr structure is 6byte aligned!
Re: A mystery IDT/ISR issue!
Posted: Sat Jun 20, 2009 4:51 pm
by ScorchOS
That would make a lot of sense! I've just checked here:
http://www.freebasic.net/index.php/deta ... y=rls&id=9
Apparently the default for FreeBASIC type-field varies between releases, but in the latest release they've elected to have them 4 Byte aligned by default!
The solution to this seems to be to make use of 'Field'. For instance:
Code: Select all
Type idt_ptr Field = 6
size As UShort
baseAddr As UInteger
End Type
Unfortunately however the machine still triple-faults and continues to reset
I'm also a little concerned, as I'm not even entirely sure if the GDT works (on the basis I haven't defined type-alignments there either!)
If on the other hand type-alignment is now correct there may be a more intrinsic design problem (or my bitwise maths is wrong somewhere!). Thanks for your help kop99.
If all else fails I'll try a recode using the knowledge acquired from this thread.
Re: A mystery IDT/ISR issue!
Posted: Sun Jun 21, 2009 1:10 am
by kop99
ScorchOS, you are right.
Your gdt_ptr structure is also not aligned.
Alignment problem might cause unpredictable crash.
Re: A mystery IDT/ISR issue!
Posted: Sun Jun 21, 2009 3:21 am
by Combuster
Field=1 means packed structures, Field=6 will most likely keep 4(!) bytes between size and offset in order to align the struct on a 6-byte boundary
And as far as the
documentation goes, said alignment is invalid.
Re: A mystery IDT/ISR issue!
Posted: Sun Jun 21, 2009 6:20 am
by ScorchOS
@combuster: Thanks for the tip! I have never used the 'Field' attribute before, hence the school-boy error
@kop99 - I have also byte-aligned the GDT UDTs and unfortunately still no joy
I have been rewriting the GDT (to eliminate that as an issue and to be more consistent with the IDT code). In so doing I have stumbled across a slight conundrum. The FreeBASIC compier does not appear to enjoy my use of bitwise OR:
Code: Select all
gdt(id).granularity = gdt(id).granularity Or (gran And &hF0)
which produces 'kernel.asm:98 Error: Invalid '[' in mnemonic'
I have uploaded the new GDT code to the SVN source as 'gdt2.bi' (requires a small edit in system.bi to include in the build). I have also taken a look at
this wiki article for the correct use of the Or operator.
(I have also tried manually declaring 'OR' as an operator:)
Code: Select all
Declare Operator Or (Byref lhs As gdt_entry, Byref rhs As UByte) As UByte
(I'm not sure however whether I have used the correct data types)
Re: A mystery IDT/ISR issue!
Posted: Sun Jun 21, 2009 7:13 am
by ScorchOS
RESOLVED! The key problem with the idea was my memset() calculation.
The diff output shows that the code which was:
Code: Select all
memset(@(idt(0)), 0, idtp.size + 1) 'Initialize all entries in the IDT
should have been:
Code: Select all
memset(@(idt(0)), 0, sizeof(idt_entry)*256) 'Initialize all entries in the IDT
IDTs now worked fine but the ISRs I was linking to was causing QEMU to crash, so I've now drastically simplified the file. There is now an isr_install() routine as before but now there is only one word of inline assembly used in one subroutine:
The GDT issue was actually a typo in some inline ASM
The div\0 error now works and I'm now coding up the rest of the ISR. Thanks everyone for your help!
Re: A mystery IDT/ISR issue!
Posted: Mon Jun 22, 2009 2:19 am
by jal
ScorchOS wrote:RESOLVED
Congrats.
JAL