Page 1 of 1

loading null selector error while loading GDT

Posted: Thu Jul 21, 2011 10:37 am
by tushs
Hi I am getting following error while init of stack segment,

Code: Select all

<bochs:18> n
00102491411e[CPU0 ] load_seg_reg(SS): loading null selector
00102491411e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00102491411e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00102491411i[CPU0 ] CPU is in protected mode (active)
00102491411i[CPU0 ] CS.d_b = 32 bit
00102491411i[CPU0 ] SS.d_b = 32 bit
00102491411i[CPU0 ] | EAX=00100002  EBX=00031334  ECX=001011d1  EDX=0000005d
00102491411i[CPU0 ] | ESP=0010ef90  EBP=0010efec  ESI=000254d4  EDI=00067fbc
00102491411i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf ZF af PF cf
00102491411i[CPU0 ] | SEG selector     base    limit G D
00102491411i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00102491411i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00102491411i[CPU0 ] |  DS:0002( 0000| 0|  2) 00000000 00000000 0 0
00102491411i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00102491411i[CPU0 ] |  ES:0002( 0000| 0|  2) 00000000 00000000 0 0
00102491411i[CPU0 ] |  FS:0002( 0000| 0|  2) 00000000 00000000 0 0
00102491411i[CPU0 ] |  GS:0002( 0000| 0|  2) 00000000 00000000 0 0
00102491411i[CPU0 ] | EIP=00100f00 (00100f00)
00102491411i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00102491411i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[102491411] [0x0000000000100f00] 0008:00100f00 (unk. ctxt): mov ss, ax                ; 8ed0
00102491411e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00102491411i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00102491411i[CPU0 ] cpu hardware reset
00102491411i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000
00102491411i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00102491411i[CPU0 ] CPUID[0x00000001]: 00000f03 00000800 00000000 07cbfbff
00102491411i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x00000007]: 00000000 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x80000000]: 80000004 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000
00102491411i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00102491411i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00102491411i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00102491411i[     ] reset of 'unmapped' plugin device by virtual method
00102491411i[     ] reset of 'biosdev' plugin device by virtual method
00102491411i[     ] reset of 'speaker' plugin device by virtual method
00102491411i[     ] reset of 'extfpuirq' plugin device by virtual method
00102491411i[     ] reset of 'iodebug' plugin device by virtual method
00102491411i[     ] reset of 'ioapic' plugin device by virtual method
00102491411i[     ] reset of 'keyboard' plugin device by virtual method
00102491411i[     ] reset of 'harddrv' plugin device by virtual method
00102491411i[     ] reset of 'serial' plugin device by virtual method
00102491411i[     ] reset of 'parallel' plugin device by virtual method
Next at t=102491412
(0) [0x00000000fffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
My code is

Code: Select all

# Global Data
.data

.align 16
.global gdt_array
gdt_array:
.quad 0x0000000000000000        # NULL
.quad 0x00CF9A000000FFFF        # Kernel Code
.quad 0x00CF92000000FFFF        # Kernel Data
.quad 0x00CFFA000000FFFF        # user code
.quad 0x00CFF2000000FFFF        # user data
.quad 0x0000000000000000        # reserved
.quad 0x0000000000000000        # reserved
.quad 0x0000000000000000        # reserved

.global gdt_ptr
gdt_ptr:
.word .-gdt_array-1
.long 0

# zero initilized Data
.bss

# code section
.text


.globl asm_install_gdt
asm_install_gdt:
        # stack setup
        # pushl %ebp
        # movl %esp,%ebp
        movl $gdt_ptr,%eax              # $ means base address of variable
        movl $gdt_array,2(%eax)         # skip 2 bytes of length and init base
        movl $gdt_ptr,%eax
        lgdt (%eax)
        mov $2,%ax                      # init special regs
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
        mov %ax,%ds
        mov %ax,%ss   <<<======= Error is at this point
        ljmp here
here:
        mov $0,%eax
        mov %cs,%ax
        ret
It looks like gdt is properly initialized, here is output of debug before execution of Error LINE,

Code: Select all

<bochs:16> n
Next at t=102491411
(0) [0x0000000000100f00] 0008:00100f00 (unk. ctxt): mov ss, ax                ; 8ed0
<bochs:17> info gdt 0 4
Global Descriptor Table (base=0x0010a000, limit=63):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, 32-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write


Please Help me :) ..

Re: loading null selector error while loading GDT

Posted: Thu Jul 21, 2011 10:52 am
by xenos
Instead of 2, you should load 2 * 8 = 16 = 0x10 into the registers DS, ES, FS, GS and SS in order to select the second entry of your GDT (kernel data). Have a look at the Intel manuals and the chapters about segment registers, GDT / LDT and segmentation.

Re: loading null selector error while loading GDT

Posted: Fri Jul 22, 2011 12:45 am
by tushs
Thank u !! Its working now.

Code: Select all

  ljmp here
here:
        mov $0,%eax
        mov %cs,%ax
        ret
Above code was not working as expected, I am not able to understand ljmp and lcall in gnu as.
I used 'retf' instead.
Thanks.

Re: loading null selector error while loading GDT

Posted: Fri Jul 22, 2011 12:55 am
by Velko
tushs wrote:

Code: Select all

  ljmp here
here:
        mov $0,%eax
        mov %cs,%ax
        ret
Above code was not working as expected, I am not able to understand ljmp and lcall in gnu as.
Correct syntax would be:

Code: Select all

        ljmp $0x08, $here 
here: