setting up TSS restarts

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.
Post Reply
prasikumbhare

setting up TSS restarts

Post by prasikumbhare »

Hello to all,

my bootloader enters PM & jumps to image load address 0x600. GDT includes null,linear code(0x08) & linear data (0x10) descriptors.
C kernel  entry function (kmain()) adds to this GDT a TSS descriptor . Then it loads this TSS into task register using LTR. But now it restarts :

what goes wrong here ? is there anything  that needs to be done before setting up TSS.
I will be very greatful & thankful if anybody gives me the solution.


Thanks in advance........

Prasad.

I use gcc(i mean djgpp) , nasm & ld.

// ___________________global.h______________________
// some stuff is copied from alexfru os .

#define GDT_entries     4
#define ACS_PRESENT     0x80
#define ACS_CODE        0x18
#define ACS_DATA        0x10
#define ACS_EXP_DOWN    0x04
#define ACS_CONFORM     0x04
#define ACS_READABLE    0x02
#define ACS_WRITEABLE   0x02

#define ACS_CODE_SEG    (ACS_CODE | ACS_PRESENT)
#define ACS_DATA_SEG    (ACS_DATA | ACS_PRESENT | ACS_WRITEABLE)
#define ACS_STACK_SEG   ACS_DATA_SEG

#define ACS_IDT         ACS_DATA_SEG
#define ACS_INT         0x0E
#define ACS_TRAP        0x0F
#define ACS_TASK 0x05
#define ACS_INT_GATE    (ACS_INT | ACS_PRESENT)
#define ACS_TRAP_GATE   (ACS_TRAP | ACS_PRESENT)
#define ACS_TSS         (0x09 | ACS_PRESENT)
#define ACS_TASK_GATE   (ACS_TASK | ACS_PRESENT)


#define ACS_DPL_0       0x00
#define ACS_DPL_1       0x20
#define ACS_DPL_2       0x40
#define ACS_DPL_3       0x60

#define ATTR_32BIT      0x40
#define ATTR_BIG        0x40
#define ATTR_GRANUL     0x80

#define RPL_0           0x00
#define RPL_1           0x01
#define RPL_2           0x02
#define RPL_3           0x03

typedef struct SEG_DESCRIPTOR
{
  word limit;
  word base0_15;
  byte base16_23;
  byte attrs0_7;
  byte attrs8_15;
  byte base24_31;
} SEG_DESCRIPTOR;

typedef struct GDT_REG
{
word limit;
dword base;
}GDT_REG;

        typedef struct TSS
{
  dword link,
        esp0,
        ss0,
        esp1,
        ss1,
        esp2,
        ss2,
        cr3,
        eip,
        eflags,
        eax,
        ecx,
        edx,
        ebx,
        esp,
        ebp,
        esi,
        edi,
        es,
        cs,
        ss,
        ds,
        fs,
        gs,
        ldtr;
  word  trace,
        io_map_addr;
} TSS;

void kmain();
void setup_GDT();
void setup_IDT();
void setup_TSS();
.........  // other function declaration...
// asm routines are extern..

extern void LGDT  (GDT_REG *gdtr);
extern void SGDT (GDT_REG *gdtr);
extern void LIDT (IDT_REG *idtr);
extern void SIDT  (IDT_REG *idtr);
extern void LTR (dword sel);
extern dword STR();

// _________________ kernel.c __________________________

#include "global.h"

static SEG_DESCRIPTOR  gdt[4];
static INT_DESCRIPTOR  idt[0x31];
static GDT_REG         gdtr;
static IDT_REG         idtr;

TSS    tss;

void kmain()
{
      setup_GDT();
      setup_TSS();
      asm("hlt");      // it does not halt here.
//      setup_IDT();
//      remap_PIC(0x20,0x28);
//      enable_IRQ(1);
//      asm("hlt");          
}

void setup_TSS()
{
  memset (&tss, 0, sizeof(TSS));            // tested works correctly...
  tss.ss0 = 0x10;                     // linear data segment descriptor    

  LTR (0x18);                        // asm routine.  
// restarts now..... If asm("hlt");    is placed before LTR() , it
// hangs .            
// esp is set to oxffff & ss = 0x10 (i.e.linear data seg.desc) by bootloader.
// here is asm part :

}


static void setup_GDT() {
  SEG_DESCRIPTOR *old_gdt;
  GDT_REG old_gdtr;
  int i;

  /* let's copy contents of the old GDT to new GDT and set up the new one */

  SGDT (&old_gdtr);        // asm routine. works correctly.
  old_gdt = (SEG_DESCRIPTOR *) old_gdtr.base;

  for (i=0;i<3;i++)
    gdt[i] = old_gdt[i];

// TSS (18h)

  gdt[3].limit = sizeof(TSS)-1;
  gdt[3].base0_15 = ((dword)(&tss)) & 0xFFFF;
  gdt[3].base16_23 = (((dword)(&tss)) >> 16) & 0xFF;
  gdt[3].base24_31 = (((dword)(&tss)) >> 24) & 0xFF;
  gdt[3].attrs0_7 = ACS_TSS;
  gdt[3].attrs8_15 = 0;

  gdtr.base = (dword) &gdt;
  gdtr.limit = GDT_entries * sizeof(SEG_DESCRIPTOR) - 1;
  LGDT (&gdtr);                       // asm routine works correctly...
}

// here is  asm part

GLOBAL          _LGDT, _SGDT, _LTR, _STR

%define PARAM_1 ebp+8+4*0

[SECTION .text]
[BITS 32]

_LGDT:
        push    ebp
        mov     ebp, esp
        mov     eax, [PARAM_1]
        lgdt    [eax]
        pop     ebp
        ret

_SGDT:
        push    ebp
        mov     ebp, esp
        mov     eax, [PARAM_1]
        sgdt    [eax]
        pop     ebp
        ret

_LTR:
        push    ebp
        mov     ebp, esp
        ltr     [PARAM_1]
        pop     ebp
        ret
Post Reply