GDT issues

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.
FusT
Member
Member
Posts: 91
Joined: Wed Sep 19, 2012 3:43 am
Location: The Netherlands

Re: GDT issues

Post by FusT »

Here it is:

Code: Select all

gdt.o:     file format elf32-i386
 
 
Disassembly of section .text:
 
00000000 <init_gdt>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 28                sub    $0x28,%esp
   6:   c7 05 00 00 00 00 3b    movl   $0x3b,0x0
   d:   00 00 00
                        8: R_386_32     gdt
  10:   b8 00 00 00 00          mov    $0x0,%eax
                        11: R_386_32    gdt_entries
  15:   a3 04 00 00 00          mov    %eax,0x4
                        16: R_386_32    gdt
  1a:   c7 44 24 10 00 00 00    movl   $0x0,0x10(%esp)
  21:   00
  22:   c7 44 24 0c 00 00 00    movl   $0x0,0xc(%esp)
  29:   00
  2a:   c7 44 24 08 00 00 00    movl   $0x0,0x8(%esp)
  31:   00
  32:   c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
  39:   00
  3a:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  41:   e8 bf 00 00 00          call   105 <gdt_set_gate>
  46:   c7 44 24 10 cf 00 00    movl   $0xcf,0x10(%esp)
  4d:   00
  4e:   c7 44 24 0c 9a 00 00    movl   $0x9a,0xc(%esp)
  55:   00
  56:   c7 44 24 08 ff ff ff    movl   $0xffffffff,0x8(%esp)
  5d:   ff
  5e:   c7 44 24 04 00 00 00    movl   $0x40000000,0x4(%esp)
  65:   40
  66:   c7 04 24 01 00 00 00    movl   $0x1,(%esp)
  6d:   e8 93 00 00 00          call   105 <gdt_set_gate>
  72:   c7 44 24 10 cf 00 00    movl   $0xcf,0x10(%esp)
  79:   00
  7a:   c7 44 24 0c 92 00 00    movl   $0x92,0xc(%esp)
  81:   00
  82:   c7 44 24 08 ff ff ff    movl   $0xffffffff,0x8(%esp)
  89:   ff
  8a:   c7 44 24 04 00 00 00    movl   $0x40000000,0x4(%esp)
  91:   40
  92:   c7 04 24 02 00 00 00    movl   $0x2,(%esp)
  99:   e8 67 00 00 00          call   105 <gdt_set_gate>
  9e:   c7 44 24 10 cf 00 00    movl   $0xcf,0x10(%esp)
  a5:   00
  a6:   c7 44 24 0c fa 00 00    movl   $0xfa,0xc(%esp)
  ad:   00
  ae:   c7 44 24 08 ff ff ff    movl   $0xffffffff,0x8(%esp)
  b5:   ff
  b6:   c7 44 24 04 00 00 00    movl   $0x40000000,0x4(%esp)
  bd:   40
  be:   c7 04 24 03 00 00 00    movl   $0x3,(%esp)
  c5:   e8 3b 00 00 00          call   105 <gdt_set_gate>
  ca:   c7 44 24 10 cf 00 00    movl   $0xcf,0x10(%esp)
  d1:   00
  d2:   c7 44 24 0c f2 00 00    movl   $0xf2,0xc(%esp)
  d9:   00
  da:   c7 44 24 08 ff ff ff    movl   $0xffffffff,0x8(%esp)
  e1:   ff
  e2:   c7 44 24 04 00 00 00    movl   $0x40000000,0x4(%esp)
  e9:   40
  ea:   c7 04 24 04 00 00 00    movl   $0x4,(%esp)
  f1:   e8 0f 00 00 00          call   105 <gdt_set_gate>
  f6:   b8 00 00 00 00          mov    $0x0,%eax
                        f7: R_386_32    gdt
  fb:   89 04 24                mov    %eax,(%esp)
  fe:   e8 fc ff ff ff          call   ff <init_gdt+0xff>
                        ff: R_386_PC32  gdt_flush
 103:   c9                      leave  
 104:   c3                      ret 
I've put the entire dump on pastebin: http://pastebin.com/muJSqQVv. just in case more is needed.
Thanks for the help so far!
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: GDT issues

Post by jnc100 »

When I compile the same code, I get (debugging symbols added):

Code: Select all

void init_gdt()
{
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 28                sub    $0x28,%esp
        gdt.limit = (sizeof(gdt_entry_t) * 5) - 1;
   6:   66 c7 05 00 00 00 00    movw   $0x27,0x0
   d:   27 00
                        9: R_386_32     gdt
        gdt.base = (uint32_t)&gdt_entries;
   f:   b8 00 00 00 00          mov    $0x0,%eax
                        10: R_386_32    gdt_entries
  14:   a3 02 00 00 00          mov    %eax,0x2
                        15: R_386_32    gdt
note how they differ with respect to line 6 (calculation of sizeof(gdt_entry_t) * 5) - 1) and line 14 (15 in yours) - offset of gdt.base.

I suppose you are using your compilers stdint.h header rather than writing one yourself?
edit: because line 6 should be a 2 byte move rather than a 4 byte one suggesting your compiler thinks your uint16_t type is actually 4 bytes long.

Your CFLAGS should also be something like -ffreestanding -Wall -Wextra -Werror (you do not need -nostdlib when compiling, only linking).

Regards,
John.
FusT
Member
Member
Posts: 91
Joined: Wed Sep 19, 2012 3:43 am
Location: The Netherlands

Re: GDT issues

Post by FusT »

Aha! got it. that actually makes complete sense.
No, I don't use my compiler's stdint.h, I did write my own.
However, I didn't use the correct integer types.
My (old) stdint.h definitions looked like this:

Code: Select all

typedef signed char     int8_t;
typedef unsigned char   uint8_t;
typedef signed int      int16_t;
typedef unsigned int    uint16_t;
typedef signed long int         int32_t;
typedef unsigned long int       uint32_t;
typedef signed long long int    int64_t;
typedef unsigned long long int  uint64_t;
while it _should_ be like this:

Code: Select all

typedef signed char     int8_t;
typedef unsigned char   uint8_t;
typedef signed short    int16_t;
typedef unsigned short  uint16_t;
typedef signed int      int32_t;
typedef unsigned int    uint32_t;
typedef signed long int         int64_t;
typedef unsigned long int       uint64_t;
Changed the base address for the GDT entries back to 0x00000000 (the 0x40000000) was just to see if it got loaded O.K.) and.....
TADAAA! it works. Can't believe how stupid this bug actually was, feel kind of dumb now #-o

Anyhow, thanks for the help everyone! I'm on the the next part of my OS: interrupts and the PIT. Wish me luck :D
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: GDT issues

Post by jnc100 »

I'd advise using the compiler-provided stdint.h. It is fully available to use in a freestanding environment. The reason for this is that short int is defined to be 'at least 16 bits' i.e. it may be more. It isn't for i386 on the current version of gcc, but on other compilers it may well be, but the length of uint16_t defined in stdint.h for any particular compiler version is guaranteed to be 16 bits.

Regards,
John.
FusT
Member
Member
Posts: 91
Joined: Wed Sep 19, 2012 3:43 am
Location: The Netherlands

Re: GDT issues

Post by FusT »

I get where you're going, solid arguments (especially after reading part of the C library specs). However, this somewhat confuses me:
I suppose you are using your compilers stdint.h header rather than writing one yourself?
and
I'd advise using the compiler-provided stdint.h.
You're kind of contradicting youself (unless i'm reading it wrong, in which case please correct me).

Anyhow, thanks for the help. It explains a lot for me (including reading/understanding objdump, nm and ndisadm output).
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: GDT issues

Post by jnc100 »

jnc100 wrote:I suppose you are using your compilers stdint.h header rather than writing one yourself?
Apologies for the confusion. I'd strongly recommend the use of the built-in stdint.h. Originally I did not presume to think you were doing otherwise, it was only when I noted the incorrect sizes of data types I began to suspect it, but I was still trying to give you the benefit of the doubt in that particular phraseology.

Anyway, not using stdint.h is one of James Molloy's Tutorial Known Bugs. You may want to check for the others.

Regards,
John.
Post Reply