Page 1 of 1

my tss just wont load

Posted: Fri Aug 10, 2007 11:14 am
by Gizmo
I am still learning the robes of pmode, I am making 1 tss and trying to load its descriptor from the gdt to the tr using ltr.

Here is what bochs says:

Code: Select all

00052687104e[CPU0 ] LTR: doesn't point to an available TSS descriptor!
00052687104e[CPU0 ] interrupt(): gate not present
00052687104e[CPU0 ] interrupt(): gate not present
00052687104i[CPU0 ] protected mode
00052687104i[CPU0 ] CS.d_b = 32 bit
00052687104i[CPU0 ] SS.d_b = 32 bit
00052687104i[CPU0 ] | EAX=00000018  EBX=00004800  ECX=00000201  EDX=00000000
00052687104i[CPU0 ] | ESP=00007ff0  EBP=00000000  ESI=00007c8d  EDI=0000ffde
00052687104i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00052687104i[CPU0 ] | SEG selector     base    limit G D
00052687104i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00052687104i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00052687104i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00052687104i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00052687104i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00052687104i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00052687104i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00052687104i[CPU0 ] | EIP=00008049 (00008049)
00052687104i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00052687104i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00052687104i[CPU0 ] >> ltr ax : 0F00D8
00052687104e[CPU0 ] exception(): 3rd (11) exception with no resolution, shutdown status is 00h, resetting
Here is my asm code

Code: Select all

org 8000h
use16
jmp BOOT_ENTRY

;--------------------memory diagram----------------------------------------------------
       ;kernel stack  1008 bytes (504 words or 253 dwords)
              ;7c00-7ff0
              KERNEL_STACK       equ 7C00h
              KERNEL_STACK_TOP   equ 7FF0h
       ;kernel program
              ;8000-9400
              KERNEL_START       equ 8000h
              KERNEL_END         equ 9400h
       ;interupt stack  4096 bytes (1021 dwords)
              ;101000-102000
              INT_HANDLER_STACK      equ 101000h
              INT_HANDLER_STACK_TOP  equ 102000h

;---------------------------------16 bit entry ---------------------------------------------------------------------------------
        use16
        BOOT_ENTRY:
        ; initialize the stack:
               mov     ax, 07c0h
               mov     ss, ax
               mov     sp, 03feh ; top of the stack.
        ; set data segment:
               mov     ax, 0h
               mov     ds, ax
        ;disable interupts
               cli
        ;load the GDT (gloabl description table) descriptor
               lgdt    [ds:gdt_32_desc]
       ;load interupt descriptor table
               lidt     [ds:idt_32_desc]
       ;set bit 0 of cr0 to 1  enabling protected mode
               mov     eax,    cr0
               or      eax,    1
               mov     cr0,    eax
        ;jump to 32 bit code segment to clear out instruction cache
               jmp     08h:PMODE_ENTRY

;---------------------------------32 bit entry ---------------------------------------------------------------------------------
       use32
       PMODE_ENTRY:
       ;set ds
               mov     ax,     10h
               mov     ds,     ax
               mov     es,     ax
               mov     fs,     ax
       ;setup kernel stack
               mov     ax,     10h
               mov     ss,     ax
               mov     esp,    7FF0h
       ;load null local desc table
               mov     ax,     0
               lldt    ax
        ;load kernel task register
               mov   ax, 18h
               ltr   ax         ;uncomment here
        ;draw colorful random charactors on line 1
                mov ecx, 0
                hang:
                        mov ebx, 0B8000h
                        add ebx, ecx
                        add ebx, 2
                        mov     ax, word [ds:ebx]
                        sub ebx, 2
                        mov     word [ds:ebx], ax
                        add ecx, 2
                        cmp ecx, 158
                        jl     hang
                        mov ecx, 0
                        inc  byte [ds:0B809Eh]
                        inc  byte [ds:0B809Fh]
                        jmp    hang

;--- 32 bit global segment descriptor table-----------------------------------------------------
        gdt_32:
    ;null segment
        gdt_32_null:
              dd 0
              dd 0
    ; Data segment
        gdt_32_code:
        ;address limit 2 bytes
              dw 0FFFFh
        ;base address lower 3 bytes
              dw 0
              db 0
        ;type(4 bits)=1010(read code nonc),s flag=1,dpl(2 bits)=00,present=1
            ;    pddstttt
              db 10011010b
        ;limit upper nibble=1111,avail=0,long=0,bd size(32)=1,granularity=1(4k units)
              ;  gblallll
              db 11001111b
        ;base address upper byte
              db 0
        gdt_32_code_end:
    ; Data segment
        gdt_32_data:
        ;address limit 2 bytes
              dw 0FFFFh
        ;base address lower 3 bytes
              dw 0
              db 0
        ;type(4 bits)=0010(r/w),s flag=1,dpl(2 bits)=00,present=1
            ;    pddstttt
              db 10010010b
        ;limit upper nibble=1111,avail=0,long=0,bd size(32)=1,granularity=1(4k units)
              ;  gblallll
              db 11001111b
        ;base address upper byte
              db 0
        gdt_32_data_end:
    ; tss segment, read/write, expand down
        gdt_32_tss:
        ;address limit 2 bytes
              dw tss_32-tss_32_end+2
        ;base address lower 3 bytes
              dw tss_32
              db 0
        ;Type(4 bits)=1001(inactive task),0,Dpl(2 bits)=00,Present=1
            ;    PDp0Type
              db 10011001b
        ;limit upper Nibble=0000,Avail=1,0,0,Granularity=0
              ;  G00ANibb
              db 00010000b
        ;base address upper byte
              db 0
        gdt_32_tss_end:
    ;end of gdt
        gdt_32_end:

        times 0x1000-($-$$) db 0

   ;---kernel task descriptor----------------------------------------------
        tss_32:
        ;previous task link and reserved
              tss_32_link:
              dw        0
              dw        0
        ;esp0 offset in stack
              tss_32_esp0:
              dd        KERNEL_STACK_TOP
        ;ss0  stack segment and reserved
              tss_32_ss0:
              dw        10h
              dw        0
        ;esp1 offset in stack
              tss_32_esp1:
              dd        0
        ;ss1  stack segment and reserved
              tss_32_ss1:
              dw        0
              dw        0
        ;esp2 offset in stack
              tss_32_esp2:
              dd        0
        ;ss2  stack segment and reserved
              tss_32_ss2:
              dw        0
              dw        0
        ;cr3 page directory pointer
              tss_32_cr3:
              dd        0
        ;instruction pointer eip
              tss_32_eip:
              dd        0
        ;eflags regs
              tss_32_eflags:
              dd        202h
        ;eax register
              tss_32_eax:
              dd        0
        ;ecx register
              tss_32_ecx:
              dd        0
        ;edx register
              tss_32_edx:
              dd        0
        ;ebx register
              tss_32_ebx:
              dd        0
        ;esp register
              tss_32_esp:
              dd        0
        ;ebp register
              tss_32_ebp:
              dd        0
        ;esi register
              tss_32_esi:
              dd        0
        ;edi register
              tss_32_edi:
              dd        0
        ;es segment register and unused
              tss_32_es:
              dw        10h
              dw        0
        ;cs segment register and unused
              tss_32_cs:
              dw        08h
              dw        0
        ;ss segment register and unused
              tss_32_ss:
              dw        10h
              dw        0
        ;ds segment register and unused
              tss_32_ds:
              dw        10h
              dw        0
        ;fs segment register and unused
              tss_32_fs:
              dw        10h
              dw        0
        ;gs segment register and unused
              tss_32_gs:
              dw        10h
              dw        0
        ;ldt segment register and unused
              tss_32_ldt:
              dw        0
              dw        0
        ;io map bitmap pointer
              dw        0
              dw        tss_32_end-tss_32
        tss_32_end:


;--- 32 bit gdt descriptor --------------------------------------------------------
        gdt_32_desc:
    ;size (limit) of gdt
        dw gdt_32_end - gdt_32 - 1
    ;address of gdt
        dd gdt_32

;--- 32 bit interupt descriptor table --------------------------------------------------------
        idt_32:
       ;first 32 interupts
           repeat 20h
               dw 0x0000
               dw 0x08
               dw 0xE00
               dw 0x00
           end repeat
        idt_32_end:

;--- 32 bit idt descriptor --------------------------------------------------------
        idt_32_desc:
    ;size (limit) of gdt
        dw idt_32_end - idt_32 - 1
    ;address of gdt
        dd idt_32

If you can tell me what I am doing wrong I would appreciate it- I have been trying to fix this for 3 days now.

Posted: Fri Aug 10, 2007 12:02 pm
by jnc100
1) Please don't post your entire kernel, it makes it very difficult to read and unlikely that people will take the time to read it all and find the pertinent bits.

2) Intel 3A:6.2.2. Bit 12 of the 3rd word of the gdt entry for the tss should be 0 to describe a system segment descriptor. Setting it to 1 means you're describing a 'code, execute only, accessed' segment.
Gizmo wrote:

Code: Select all

;Type(4 bits)=1001(inactive task),0,Dpl(2 bits)=00,Present=1
            ;    PDp0Type
              db 10011001b
should be

Code: Select all

db 10001001b
3) Running bochs with the debugger, halting it before the offending instruction (in this case ltr) and running the command 'info gdt' will be of great help in diagnosing gdt problems.

Regards,
John.

Posted: Fri Aug 10, 2007 12:43 pm
by Gizmo
Thanks, that fixed it.
Now I can abort the pull hair routine.
I put in the comment describing that bit 0 meaning set to 0 but obviously I forgot to change it after copying and pasting it from the code descriptor.

Thats actually not the entire kernel, its just enough to run and show the problem. It only looks so long because its asm, if I put that in C it might be 10 lines :).