Page 1 of 1

trouble with gdt

Posted: Sun Apr 13, 2008 6:14 pm
by elkvis
I have a kernel, written in C and NASM, that boots up and I can print to the screen with a printf-like command, complete with \n support and scrolling, etc.

I am having trouble with it rebooting when I try to jump to the new code segment.

my segment descriptor structure looks like this:

Code: Select all

typedef struct
{
  uint limit_0_15:16 __attribute__((__packed__));
  uint base_0_23:24 __attribute__((__packed__));
  uint accessed:1 __attribute__((__packed__));
  uint read_write:1 __attribute__((__packed__));
  uint expand_conform:1 __attribute__((__packed__));
  uint code:1 __attribute__((__packed__));
  uint system:1 __attribute__((__packed__));
  uint dpl:2 __attribute__((__packed__));
  uint present:1 __attribute__((__packed__));
  uint limit_16_19:4 __attribute__((__packed__));
  uint long_mode:1 __attribute__((__packed__));
  uint default_op:1 __attribute__((__packed__));
  uint granularity:1 __attribute__((__packed__));
  uint base_24_31:8 __attribute__((__packed__));
} segment_descriptor;
I have verified through printf(... sizeof(segment_descriptor)) that this structure is 8 bytes, and after setting the values to what I want, and printing out the contents, it appears correct.

I am able to LGDT with my array of 8192 descriptors, but when I try to jump into my new code segment (selector 0x08), it reboots.

the code for jumping to the new code segment is pretty typical, in NASM:

Code: Select all

jump_to_new_segment:
  jmp 0x08:new_seg
new_seg:
  mov eax, 0x10
  mov ds, eax
  mov ss, eax
  mov es, eax
  mov fs, eax
  mov gs, eax
  ret
I'm sure I'm missing something very simple, but after looking through forums and web pages for hours, I have come up with nothing useful.

any help will be very appreciated.

thanks in advance.

Andy

Posted: Sun Apr 13, 2008 7:25 pm
by neon
Just that I asked as it is very simple to mess:

You have disabled interrupts before jumping to pmode, right? (cli instruction)

Also, new_seg should be inside 32 bit code (use bits 32):

Code: Select all

  cli
  jmp 0x08:new_seg

bits 32

new_seg:
  mov eax, 0x10
  mov ds, eax
  mov ss, eax
  mov es, eax
  mov fs, eax
  mov gs, eax

Posted: Sun Apr 13, 2008 7:33 pm
by Zenith
I think the problem is that

Code: Select all

uint limit_0_15:16 __attribute__((__packed__));
uint base_0_23:24 __attribute__((__packed__));
this part will not produced the desired effect as GCC would just see 16 bits + 24 bits not fitting into uint (assuming it is 32 bits), so that it would do

Code: Select all

uint #1
limit_0_15 [16 bits]
padding [16 bits]
uint #2
base_0_23 [24 bits]
accessed [1 bit]
etc...
throwing off the alignment. Do:

Code: Select all

  uint limit_0_15:16;
  uint base_0_15:16;
  uint base_16_24:8;
Also, for readability's sake, drop the "__attribute__((__packed__));"s - just put one at the end of the struct definition. :wink:

And for <powerful diety>'s sake, people (note that this is not directly at the OP, but to half of the people who post here looking for instant help), where has the art of debugging gone to?
If you're using an emulator like Bochs, what output does it give?
Did you inspect the memory location the GDT is loaded at - are the values right?
Did you put the right values into the entry in the first place?
And if you're not using an emulator, then I strongly advise you to do so immediately.

Peace, and hope this helps,
J.S.

Posted: Mon Apr 14, 2008 5:34 am
by elkvis
neon:
I am already in PMode when I do this. I forgot to mention that I'm using GRUB to load my kernel, and that I'm just trying to reload a new GDT that I can manipulate however I want.

karekare0:
Why would using a 24-bit field throw of alignment? I thought that was the purpose of using __attribute__((__packed__)) - so that it would NOT pad the structure for alignment. I am using an emulator - sort of. I've been using vmware, but as I'm sure you know, it does not provide any kind of debugging output. this bochs debugger you're talking about - is it commercial softwar? because I'm all about open source software, and don't really want to spend any money on this project.

Posted: Mon Apr 14, 2008 7:21 am
by Zenith
Before doubting me, can you at least try my suggestion?

The 4th post at
this topic might be of some help understanding why... :wink:

And Bochs and QEMU are free and open source! I'd say they're vital to OSDev... They'll give you debugging output, register values, disassembly, etc.

Posted: Mon Apr 14, 2008 7:52 am
by elkvis
karekare0 wrote:Before doubting me, can you at least try my suggestion?

The 4th post at
this topic might be of some help understanding why... :wink:

And Bochs and QEMU are free and open source! I'd say they're vital to OSDev... They'll give you debugging output, register values, disassembly, etc.
not doubting you.... if you recall, I said "why would a 24-bit field throw off alignment?" it was a question. an attempt to understand better. I can see how you could misinterpret though, given the large number of less-than-highly-skilled coders that may tend to have questions like these. after reading the post you suggested, I understand better now.

so let me see if I got this right... if I use some sort of 64-bit integer, will it work the way I have it, since the structure is 64 bits (8 bytes) long? or should I switch to using fields that are multiples of whole bytes?

Posted: Mon Apr 14, 2008 4:50 pm
by iammisc
Your structure definition is really shaky. You never know exactly how gcc is going to align anything like that. Personally, I would either break the structure up into integer fields and do any bitwise operations manually so you can be absolutely sure that gcc is not doing anything wrong.

Also, if you don't want to do this, then just look at the assembler gcc is producing there has to be something wrong. In addition, could you please post the code that creates your segments? How do you know that your code segment is even valid?

Posted: Mon Apr 14, 2008 4:53 pm
by 01000101
I believe there was an earlier thread about the inefficiency and inconsistency of gcc bitfield declarations

Posted: Mon Apr 14, 2008 5:50 pm
by elkvis
perhaps I'll just redo my structures with no bitfields and do the bit by bit manipulation manually... it seems the lesser of the two evils.