test GDT?

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.
MoneyCat

test GDT?

Post by MoneyCat »

I have implemented a GDT in my OS and I was wondering if it possible to somehow test GDT to see if I have defined everything right (ie. run some code to excercise GDT)

thanks
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

well, that'll be pretty hard to do unless you have exception handlers ready, and even more complicated if you're willing to test the basic descriptors for OS code and OS data (prior to the Far Jmp to protected mode).

However, a few things you can do if the above conditions are met is
[*] try to write at offset 0xB8000 on a 0-based segment and see if it something appears on screen.
[*] write a magic word at offset X of the 0-based segment and see if you can read it at offset X-S.base through segment S
[*] try to go beyond the expected limit (just by 1 byte) and see if you get a GPF ...
[*] try to call the code segment (at an address that just has a "RETF" instruction) and see if you get a GPF or not (expected not ;) )
MoneyCat

Re:test GDT?

Post by MoneyCat »

try to write at offset 0xB8000 on a 0-based segment and see if it something appears on screen.
Well I call my loadGDT function which is defined in another file . Then I call prinft which seems to be writing correctly. However I am using Grub. How can I be sure I am not using Grub's temporary GDT??
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

check Grub's GDT location with SGDT (iirc) and then compare yours with its.

For instance, if you add a specific segment (which could be for instance based at 0xB8000 and have a limit of 4000 bytes = 80x25x2), you could be sure you're using your GDT if that selector behaves as *you* stated ...

Code: Select all

ia32Descriptor mygdt[]={
    IA32_INVALID(0),
    IA32_CODE(0,0xFFFFFFFF),
    IA32_DATA(0,0xFFFFFFFF),
    IA32_DATA(0xB8000,80*25*2),
};

void test() {
   printf("GRuB's GDT @%x", sgdt());
   install_gdt(mygdt);
   printf("now GDT is @%x", sgdt());
   far_poke_w(0x18,'H'+256*(WHITE+BACKGROUND*BLUE));
   far_poke_w(0x18,'i'+256*(WHITE+BACKGROUND*BLUE));
}
MoneyCat

Re:test GDT?

Post by MoneyCat »

I did a objdump on my gdt file and this is what I got:

Code: Select all

gdt.o:     file format elf32-i386

Disassembly of section .text:

00000000 <loadGDT>:
   0:   0f 01 15 20 00 00 00    lgdtl  0x20
   7:   66 b8 10 00             mov    $0x10,%ax
   b:   8e d8                   mov    %eax,%ds
   d:   8e c0                   mov    %eax,%es
   f:   8e d0                   mov    %eax,%ss
  11:   8e e0                   mov    %eax,%fs
  13:   8e e8                   mov    %eax,%gs
  15:   c3                      ret
Disassembly of section .data:

00000000 <gdt>:
        ...
  10:   ff                      (bad)
  11:   ff 00                   incl   (%eax)
  13:   00 00                   add    %al,(%eax)
  15:   92                      xchg   %eax,%edx
  16:   cf                      iret
  17:   00 ff                   add    %bh,%bh
  19:   ff 00                   incl   (%eax)
  1b:   00 00                   add    %al,(%eax)
  1d:   9a cf 00 1f 00 00 00    lcall  $0x0,$0x1f00cf

00000020 <gdt_end>:
  20:   1f                      pop    %ds
  21:   00 00                   add    %al,(%eax)
  23:   00 00                   add    %al,(%eax)
        ...
Does this mean I am loading the GDT at 0?? Sorry I am just trying to get a good understanding on this topic..

I got the GDT code from osdever.com:

Code: Select all

[BITS 32]

GLOBAL loadGDT

loadGDT:
  ; stop using bootloader GDT, and load new GDT
  lgdt [gdt_ptr]

  mov ax,LINEAR_DATA_SEL
  mov ds,ax
  mov es,ax
  mov ss,ax
  mov fs,ax
  mov gs,ax

   ret


;--------------------
; GDT loading info
;--------------------
SECTION .data

gdt:
; NULL descriptor
        dw 0            ; limit 15:0
        dw 0            ; base 15:0
        db 0            ; base 23:16
        db 0            ; type
        db 0            ; limit 19:16, flags
        db 0            ; base 31:24

; unused descriptor
        dw 0
        dw 0
        db 0
        db 0
        db 0
        db 0

LINEAR_DATA_SEL equ     $-gdt
        dw 0FFFFh
        dw 0
        db 0
        db 92h          ; present, ring 0, data, expand-up, writable
        db 0CFh         ; page-granular (4 gig limit), 32-bit
        db 0

LINEAR_CODE_SEL equ     $-gdt
        dw 0FFFFh
        dw 0
        db 0
        db 9Ah          ; present,ring 0,code,non-conforming,readable
        db 0CFh         ; page-granular (4 gig limit), 32-bit
        db 0
gdt_end:

gdt_ptr:
        dw gdt_end - gdt - 1
        dd gdt
I do not understand what should go into sgdt() like you mentioned before. Any feedback is appreciated.

thanks
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

for your objdump, make sure you have the -r flag so that it also shows you what addresses are to be relocated, and compared to which symbols. There are chances that the '0x20' value for lgdtl is just 'offset 0x20 relative to .data' :)
MoneyCat

Re:test GDT?

Post by MoneyCat »

Code: Select all


gdt.o:     file format elf32-i386

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
00000003 R_386_32          .data


RELOCATION RECORDS FOR [.data]:
OFFSET   TYPE              VALUE
00000022 R_386_32          .data

So my GDT is being loaded at 0000003 ? Arghhh...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

no. use objdump -drS to get a good idea of what's happening:

at offset 3 in section .text, you have an offset which must be adjusted by adding the base address of section .data ... this is what the relocation line #1 states ...
MoneyCat

Re:test GDT?

Post by MoneyCat »

Code: Select all

gdt.o:     file format elf32-i386

Disassembly of section .text:

00000000 <loadGDT>:
   0:   0f 01 15 20 00 00 00    lgdtl  0x20
   3:   R_386_32     .data
   7:   66 b8 10 00             mov    $0x10,%ax
   b:   8e d8                   mov    %eax,%ds
   d:   8e c0                   mov    %eax,%es
   f:   8e d0                   mov    %eax,%ss
  11:   8e e0                   mov    %eax,%fs
  13:   8e e8                   mov    %eax,%gs
  15:   c3                      ret
with -drS this is what I got. Since I can write to the screen maybe i am using my own gdt...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

adding

Code: Select all

VIDEO_SEL equ    $-gdt
        dw 0FFFFh
        dw 0x8000
        db 0x000b
        db 92h          ; present, ring 0, data, expand-up, writable
        db 0CFh        ; page-granular (4 gig limit), 32-bit
        db 0

past your LINEAR_CODE_SEL and issuing

Code: Select all

       mov ax,VIDEO_SEL
       mov gs,ax
       mov [gs:0],'.i.h'
should convince you definitely :)
(the colors may be funny ... light red on dark cyan or something ;)
MoneyCat

Re:test GDT?

Post by MoneyCat »

Code: Select all

      mov ax,VIDEO_SEL
      mov gs,ax
      mov [gs:0],'.i.h'
Nasm complains that [gs:0] is: "Operation size not specified"


thanks for the help!
Therx

Re:test GDT?

Post by Therx »

I'm a bit rusty but i think it should be:-

Code: Select all

mov dword [gs:0],'.i.h'
Pete
MoneyCat

Re:test GDT?

Post by MoneyCat »

I'm a bit rusty but i think it should be:-
That gave me the same error: "operation size not specified"


thanks for all the help ! :)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:test GDT?

Post by Pype.Clicker »

i'm no longer sure nasm allows that kind of litteral (32-bits long characters)... damn ...

maybe you could try

Code: Select all

mov dword [gs:0], 0x3e693e48
instead. Sorry for submitting non-assemblable code, i just thought you were far enough in assembly to correct it if it were wrong ...
MoneyCat

Re:test GDT?

Post by MoneyCat »

Hello,

I have a strange situation. I am using grub to boot my kernel. I loaded my gdt, idt, isr and remaped the PIC. I enable interrupts and the instant I try to fire an int 0 it triplefaults. However, when I take out my gdt and thus use Grub's temporary gdt the interrupts work fine for some reason. I don't understand.. I didn't even change my IDT's or ISR's selector and yet it works fine. Even my test interrupt function fired correctly.

To make sure my gdt was working right I used Pype.Clicker's method:

Code: Select all

  mov ax,VIDEO_SEL
  mov gs,ax
  mov dword [gs:0], 0x3E693E48   ; 4bytes = 2char + 2attr
This correctly prints 'Hi' on top left corner.

I also tried to use:

Code: Select all

     int gdtdesc[2];
   char* ptr= ((char*)gdtdesc) + 2;
   asm("sgdt (%0)": "=r" (ptr));
This reported that Grub's gdt limit was: 270000 and base: 8F60. I then called my loadGDT function and then checked the sgdt but I got the same base and limit (8F60 and 270000).

Do I even have the right asm instruction to gather sgdt info? I think these interrupts are working becuase grub's gdt has the same data and code selector I had in my gdt..


Can anyone help me please?

Thanks!
Post Reply