Still triple faults

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
sham1
Posts: 16
Joined: Wed Nov 30, 2011 12:44 pm
Libera.chat IRC: sham1

Still triple faults

Post by sham1 »

Yeah, it's still me after I have changed my name. My kernel reboots because I think there is triple fault. But this time I actually have managed to collect some logs about why it happens. But I myself can't for the life of me figure out how to solve it.

So here is the relevant part of the logs that Bochs gives me:

Code: Select all

00072305242e[CPU0 ] branch_far64: RIP > limit
00072305242e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00072305242e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00072305242i[CPU0 ] CPU is in protected mode (active)
00072305242i[CPU0 ] CS.d_b = 32 bit
00072305242i[CPU0 ] SS.d_b = 32 bit
00072305242i[CPU0 ] EFER   = 0x00000000
00072305242i[CPU0 ] | RAX=0000000000105ffa  RBX=0000000000010000
00072305242i[CPU0 ] | RCX=0000000000000000  RDX=00000000004f9200
00072305242i[CPU0 ] | RSP=0000000000105ff4  RBP=0000000000000000
00072305242i[CPU0 ] | RSI=0000000000000000  RDI=0000000000000000
00072305242i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00072305242i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00072305242i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00072305242i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00072305242i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf sf zf af pf cf
00072305242i[CPU0 ] | SEG selector     base    limit G D
00072305242i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00072305242i[CPU0 ] |  CS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  DS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  SS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  ES:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  FS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  GS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00072305242i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00072305242i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00072305242i[CPU0 ] | RIP=0000000000100304 (0000000000100304)
00072305242i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00072305242i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00072305242i[CPU0 ] 0x0000000000100304>> jmp far 0008:0010030b : EA0B0310000800
00072305242e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00072305242i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00072305242i[CPU0 ] cpu hardware reset
As we can see, it is because the gate descriptors are not valid system segments. Now, The fact that I was able to identify the problem is good step towards solving it but it still does not solve it. So I ask you guys who obviously are much more experienced at this.

Here are the GDT codes:

GDT.h
GDT.cpp
my GDT flushing codes.

And I think it is not just Bochs just making huge deal about having 3rd exception without resolution as this crashing also happens in Qemu.

I am gonna go and build my own version of Bochs now as I might be able to make it have gui debugger so I can maybe get something resolved.

EDIT: Also I have no clue why there are RAX and registers like that on the logs instead of having EAX and stuff. Maybe that has some effect on it but I am not sure.
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Still triple faults

Post by iansjack »

The RAX, etc. registers are because you are using 64-bit code. Did you construct your GDT with this in mind?

Edit: To be fair, I'm not familiar with Bochs. This may be someting to do with Bochs rather than your code. Presumably you are running a 64-bit OS. Are you building your code with a cross-compiler? Are you building your code wit a 32-bit cross-comiler?
Last edited by iansjack on Sat Mar 07, 2015 1:16 pm, edited 1 time in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: Still triple faults

Post by jnc100 »

For one, you allocate your gdt on the stack, which is a seriously bad idea.

Regards,
John.
sham1
Posts: 16
Joined: Wed Nov 30, 2011 12:44 pm
Libera.chat IRC: sham1

Re: Still triple faults

Post by sham1 »

iansjack wrote:The RAX, etc. registers are because you are using 64-bit code. Did you construct your GDT with this in mind?
I do myself know that RAX etc. are 64-bit registers. But I am trying to make 32-bit OS so that maybe is a problem. Think I will look around at this.
jnc100 wrote:For one, you allocate your gdt on the stack, which is a seriously bad idea.

Regards,
John.
Welp, that is pretty much all I could do if I didnt want to get my hands dirty and just start writing assembly to make this happen. I think I will do that anyway to make it easier for myself.
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Still triple faults

Post by iansjack »

I've edited my previous post. You are compiling your code with a 32-bit cross compiler, aren't you?
sham1
Posts: 16
Joined: Wed Nov 30, 2011 12:44 pm
Libera.chat IRC: sham1

Re: Still triple faults

Post by sham1 »

iansjack wrote:I've edited my previous post. You are compiling your code with a 32-bit cross compiler, aren't you?
Yes I am building with 32-bit cross compiler on a 64-bit host because it can take advantage of my real processor being 64-bits.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Still triple faults

Post by neon »

Welp, that is pretty much all I could do if I didnt want to get my hands dirty and just start writing assembly to make this happen. I think I will do that anyway to make it easier for myself.
Alternatively just make it static...the real error RIP > limit is pretty clear that there is something wrong with the GDT in memory. There is absolutely no reason why it cannot be statically allocated. If you still want to allocate it on the stack despite our warning, I'd advise using info gdt command to verify if it has not been corrupted.

Code: Select all

00072305242i[CPU0 ] CPU is in protected mode (active)
00072305242i[CPU0 ] CS.d_b = 32 bit
00072305242i[CPU0 ] SS.d_b = 32 bit
You are in 32 bit protected mode so the fact that you are running on a later version of Bochs that also supports 64 bit registers and long mode is irrelevant. Your software will just use the low 32 bits of the 64 bit registers.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Still triple faults

Post by Roman »

sham1 wrote:
iansjack wrote:The RAX, etc. registers are because you are using 64-bit code. Did you construct your GDT with this in mind?
I do myself know that RAX etc. are 64-bit registers. But I am trying to make 32-bit OS so that maybe is a problem. Think I will look around at this.
jnc100 wrote:For one, you allocate your gdt on the stack, which is a seriously bad idea.

Regards,
John.
Welp, that is pretty much all I could do if I didnt want to get my hands dirty and just start writing assembly to make this happen. I think I will do that anyway to make it easier for myself.
It's absolutely wrong to have the GDT on the stack. Why not just this?

Code: Select all

GDT_Entry_t *gdt = (GDT_Entry_t*) SOME_LOCATION_IN_MEMORY;
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Still triple faults

Post by iansjack »

neon wrote:You are in 32 bit protected mode so the fact that you are running on a later version of Bochs that also supports 64 bit registers and long mode is irrelevant. Your software will just use the low 32 bits of the 64 bit registers.
Fair enough. I'm used to debuggers that adapt their display to the mode in effect.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Still triple faults

Post by Candy »

I'm guessing your stack is misaligned, therefore your gdt is also misaligned, therefore the gdtr loads a wrong address (as it does not store the last few bits!) and uses a wrong address.

Fix your GDT as mentioned above to be sufficiently aligned.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Still triple faults

Post by Octocontrabass »

The GDT doesn't need to be aligned, although it's a good idea to align it anyway.
sham1
Posts: 16
Joined: Wed Nov 30, 2011 12:44 pm
Libera.chat IRC: sham1

Re: Still triple faults

Post by sham1 »

Okay, I have done little bit of progress and by progress I mean that instead of saying RIP > limit it is saying load_seg_reg(SS): loading null selector.

Now this probably is very noobish question but how should I implement this. As I am not the smartest of the people I don't know how I could implement this any other way expect for passing it through stack. Because making it static requires me to use __cxa_guard_aqcuire and I really would not want to do anything like that until I have GDT and interrupts set up.

BTW. how should I align the struct?
User avatar
Combuster
Member
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: Still triple faults

Post by Combuster »

Octocontrabass wrote:The GDT doesn't need to be aligned, although it's a good idea to align it anyway.
Historically, it isn't :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply