Exemple #1
0
int init_gdt()
{
/* initialize the pointer */
gdt_ptr.limit = (sizeof(gdt_entry_t) * NUM_GDT) -1; /* the size of our gdt entry is 5 gdt entries */
// gdt_ptr.base = (u32int)&gdt_entries; /* store the gdt register from where ever gdt_entries begins */
gdt_ptr.base = (unsigned int)&gdt_entries; /* store the gdt register from where ever gdt_entries begins */

/* set the gates */
/* from intel manuals :
"The architecture also defines a set of special descriptors called gates (call gates, interrupt gates, trap gates, and
task gates). These provide protected gateways to system procedures and handlers that may operate at a different
privilege level than application programs and most procedures. For example, a CALL to a call gate can provide
access to a procedure in a code segment that is at the same or a numerically lower privilege level (more privileged)
than the current code segment. To access a procedure through a call gate, the calling procedure
supplies the selector for the call gate. The processor then performs an access rights check on thecall gate, comparing the CPL
with the privilege level of the call gate and the destination code segment pointed to by the call gate"
*/


/* TODO: understand
why the segment bases and limits are allowed to overlap - is it physical or virtual memory?
how binary and hexadecimal conversions, CF, 9A and so on work
*/

/* set the gates. Only the access byte changes. */
gdt_set_gate(NULL, NULL, NULL, NULL, NULL);                // NULL segment, required for some reason
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Ring 0 Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Ring 0 Data segment
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // Ring 3 (User mode) code segment
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // Ring 3 (User mode) data segment


gdt_flush(); /* an asm routine to lgdt gdt_ptr and set up the segment registers */
return 1;
}
Exemple #2
0
/* Should be called by main. This will setup the special GDT
*  pointer, set up the first 3 entries in our GDT, and then
*  finally call gdt_flush() in our assembler file in order
*  to tell the processor where the new GDT is and update the
*  new segment registers */
void gdt_install()
{
    /* Setup the GDT pointer and limit */
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
    gp.base = (unsigned int) &gdt;

    /* Our NULL descriptor */
    gdt_set_gate(0, 0, 0, 0, 0);

    /* The second entry is our Code Segment. The base address
    *  is 0, the limit is 4GBytes, it uses 4KByte granularity,
    *  uses 32-bit opcodes, and is a Code Segment descriptor.
    *  Please check the table above in the tutorial in order
    *  to see exactly what each value means */
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);

    /* The third entry is our Data Segment. It's EXACTLY the
    *  same as our code segment, but the descriptor type in
    *  this entry's access byte says it's a Data Segment */
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

    //sys_tss.ss0 = 0x10;
    //sys_tss.iomap = (unsigned short) sizeof(struct tss_entry_struct);

    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);

    //unsigned long addr = &sys_tss;
    //int size = sizeof(struct tss_entry_struct)+1;
    //gdt_set_gate(5, addr, addr+size, 0x86, 0xCF);

    gdt_flush((uint32_t)&gp);
}
Exemple #3
0
Fichier : gdt.c Projet : mcaos/sOS
void init_gdt()
{
    //Sets up the gdt pointer
    gdtp.limit = (sizeof(struct gdt_entry)*GDT_LEN)-1;
    gdtp.base = (unsigned int)&gdt_table;

    /*the first NULL entry*/
    gdt_set_gate(0, 0,0,0,0);
    
    // 0x9A, 0x92, 0xFA, 0xF2
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
    
    // Ok, add the tss
   
    set_tss(5, 0x10, 0x0);

    /*actually flushes gdt with lgdt code*/
    gdt_flush((unsigned int)&gdtp);
    
    // now flush the TSS
    tss_flush();
}
Exemple #4
0
/* Should be called by main. This will setup the special GDT
*  pointer, set up the first 3 entries in our GDT, and then
*  finally call gdt_flush() in our assembler file in order
*  to tell the processor where the new GDT is and update the
*  new segment registers */
void gdt_install()
{
    kprintc(":: Installing ", BLACK, LIGHT_RED);
    kprintc("GDT\n", BLACK, LIGHT_CYAN);
    /* Setup the GDT pointer and limit */
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
    gp.base = (int)&gdt;

    /* Our NULL descriptor */
    gdt_set_gate(0, 0, 0, 0, 0);

    /* The second entry is our Code Segment. The base address
    *  is 0, the limit is 4GBytes, it uses 4KByte granularity,
    *  uses 32-bit opcodes, and is a Code Segment descriptor.
    *  Please check the table above in the tutorial in order
    *  to see exactly what each value means */
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);

    /* The third entry is our Data Segment. It's EXACTLY the
    *  same as our code segment, but the descriptor type in
    *  this entry's access byte says it's a Data Segment */
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

    /* Flush out the old GDT and install the new changes! */
    gdt_flush();
}
Exemple #5
0
/**
 * @brief setup GDT
 *
 * Should be called by main. This will setup the special GDT
 * pointer, set up the first 3 entries in our GDT, and then
 * finally call gdt_flush() in our assembler file in order
 * to tell the processor where the new GDT is and update the
 * new segment registers
 */
void gdt_install()
{
	/* Setup the GDT pointer and limit */
	struct gdt_ptr gp;
	gp.limit = (sizeof(struct gdt_entry) * 10) - 1;
	gp.base = (unsigned int)&gdt;

	/* Our NULL descriptor */
	gdt_set_gate(0, 0, 0, 0, 0);

	/* The second entry is our Code Segment. The base address
	*  is 0, the limit is 4GBytes, it uses 4KByte granularity,
	*  uses 32-bit opcodes, and is a Code Segment descriptor.
	*  Please check the table above in the tutorial in order
	*  to see exactly what each value means */
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);

	/* The third entry is our Data Segment. It's EXACTLY the
	*  same as our code segment, but the descriptor type in
	*  this entry's access byte says it's a Data Segment */
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

	/* The 4th entry is
	gdt_video:	Descriptor 0B8000h, 0ffffh, DA_DRW | 0xcf00	; VGA address */
	gdt_set_gate(3, 0xB8000, 0xFFFFFFFF, 0x92, 0xCF);

	/* Flush out the old GDT and install the new changes! */
	gdt_flush(gp);
}
Exemple #6
0
void	gdt_flush(void)
{
   asm("lgdtl (gdtptr)");

   asm("movw $0x10, %ax\n \
        movw %ax, %ds\n \
        movw %ax, %es\n \
	movw %ax, %fs\n \
        movw %ax, %gs\n \
        movw %ax, %ss\n \
	ljmp $0x08, $next\n \
	next:		\n");
}

void	init_gdt(void)
{

    gdtptr.limit = (sizeof(t_gdt_entry) * 5) - 1;
    gdtptr.base  = (uint)&gdt_entries;

    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

    gdt_flush();
}
Exemple #7
0
void gdt_install() {
    gp.limit = (sizeof(gdt_entry) * 3) - 1;
    gp.base = (int)&gdt;
    gdt_set_gate(0, 0, 0, 0, 0);
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_flush();
}
Exemple #8
0
// Setup the GDT pointer and create the three entries (gates) we
// want to use:
// 1: Null descriptor (See Tutorial)
// 2: Describes the code segment (Base address is 0, limit is 4GBytes,
// use 4 KBytes granularity, 32bit coding and a Code Segment descriptor.
// 3: Data segment which is the same as the data segment except the access
// flag which tells it is a data segment.
void gdt_install() {
  /* Setup the GDT pointer and limit */
  gdt_p.limit = (sizeof(gdt_entry_t) * 3) - 1;
  gdt_p.base = (unsigned int)&gdt; // convert pointer to unsigned int
  gdt_set_gate(0, 0, 0, 0, 0);
  gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
  gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
  // Flush the old GDT and install the new one. This code
  // can be found in start.asm.
  gdt_flush();
}
Exemple #9
0
void gdt_init()
{
	gdtp.limit = (sizeof(struct gdt_entry) * 3) - 1;
	gdtp.base = (uint32_t)&gdt;
	// 0x2000000
	gdt_set_gate(0, 0, 0, 0, 0);
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
	
	__gdt_flush();
}
Exemple #10
0
void gdt_install()
    /// Initiates our GDT with flat 32-bit addresses.
{
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1;  // Set up the Pointer
    gp.base = (unsigned int)&gdt;                   // To the Table

    gdt_set_gate(0, 0, 0, 0, 0);                // 1st Descriptor is null
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code Segment, Kernel Mode
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data Segment, Kernel Mode

    gdt_flush();                                // Tell CPU we have a new GDT
}
Exemple #11
0
static void init_gdt(void){
    _gdt_ptr.limit = sizeof(gdt_entry_t)*5 - 1;
    _gdt_ptr.base  = (uint32_t)&_gdt;

    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

    __flush_gdt((uint32_t)&_gdt_ptr);
}
Exemple #12
0
void gdt_install ( void )
{
    gp.limit = ( sizeof ( struct gdt_entry ) * 3 ) - 1;
    gp.base = (unsigned int) &gdt;

    gdt_set_gate ( 0, 0, 0, 0, 0 ); //NULL descriptor
    gdt_set_gate ( 1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //Code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //Data segment

    gdt_flush();
    printline ("Installed GDT");
}
Exemple #13
0
void init_gdt()
{
    terminal_writestring("Initiating GDT...          ");
    gdt_ptr.limit = (sizeof(gdt_entry_t) * 3) - 1;
    gdt_ptr.base  = (uint32_t)&gdt_entries;
    
    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Kernel data segment
    
    gdt_flush((uint32_t)&gdt_ptr);
    terminal_writestring("DONE\n");
}
Exemple #14
0
void gdt_init(void) {
	gdt_set_gdtr(&gdt_ptr, gdt);

	gdt_set_gate(0, 0, 0, 0, 0); /* NULL Descriptor */
	gdt_set_gate(GDT_ENTRY_KERNEL_CS, 0, 0xFFFFFFFF, 0x9A, 0xCF);
	gdt_set_gate(GDT_ENTRY_KERNEL_DS, 0, 0xFFFFFFFF, 0x92, 0xCF);
	gdt_set_gate(GDT_ENTRY_USER_CS, 0, 0xFFFFFFFF, 0xFA, 0xCF);
	gdt_set_gate(GDT_ENTRY_USER_DS, 0, 0xFFFFFFFF, 0xF2, 0xCF);
	/* TSS is filled in usermode (if we have) */
	gdt[GDT_ENTRY_TSS].access &= ~GDT_BUSY_FLAG;

	gdt_flush(&gdt_ptr);
}
Exemple #15
0
static void init_gdt()
{
	gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
	gdt_ptr.base = (u32int) &gdt_entries;

	gdt_set_gate(0, 0, 0, 0, 0);
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);	// code seg
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);	// data seg
	gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);	// user code seg
	gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);	// user data seg

	gdt_flush((u32int) &gdt_ptr);
}
// Init the GDT by setting its values
static void init_gdt()
{
    gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
    gdt_ptr.base = (u32int)&gdt_entries;

    gdt_set_gate(0,  0,  0,  0,  0);
    gdt_set_gate(1,  0,  0xFFFFFFFF,    0X9A,   0XCF);
    gdt_set_gate(2,  0,  0xFFFFFFFF,    0X92,   0XCF);
    gdt_set_gate(3,  0,  0xFFFFFFFF,    0XFA,   0XCF);
    gdt_set_gate(4,  0,  0xFFFFFFFF,    0XF2,   0XCF);

    gdt_flush((u32int)&gdt_ptr);
}
static void init_gdt()
{
  gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
  gdt_ptr.base  = (u32int)&gdt_entries;

  gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
  gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // CS
  gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // DS
  gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User CS
  gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User DS

  gdt_flush((u32int)&gdt_ptr);
}
Exemple #18
0
static void init_gdt()
{
    gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
    gdt_ptr.base  = (uint32)&gdt_entries;

    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

    gdt_flush((uint32)&gdt_ptr);
}
Exemple #19
0
static void init_gdt()
{
    gdt_ptr.limit   = (sizeof(gdt_entry_t) * GDT_ENTRIES) - 1;
    gdt_ptr.base    = (uint32_t)&gdt_entries;

    gdt_set_gate(0, 0, 0, 0, 0);                              // Null segment
    gdt_set_gate(1, SEGMENT_BASE, SEGMENT_LIMIT, 0x9A, 0xCF); // Kernel Code segment
    gdt_set_gate(2, SEGMENT_BASE, SEGMENT_LIMIT, 0x92, 0xCF); // Kernel Data segment
    gdt_set_gate(3, SEGMENT_BASE, SEGMENT_LIMIT, 0xFA, 0xCF); // User mode code segment
    gdt_set_gate(4, SEGMENT_BASE, SEGMENT_LIMIT, 0xF2, 0xCF); // User mode data segment

    gdt_flush((uint32_t)&gdt_ptr);
}
Exemple #20
0
static void init_gdt()
{
    gdt_ptr.limit = (sizeof(gdt_entry) * 5) - 1;
    gdt_ptr.base  = (unsigned int)&gdt_entries;

    gdt_set_gate(0, 0, 0, 0, 0);              
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); 
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); 
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); 
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); 

    gdt_flush((unsigned int)&gdt_ptr);
}
Exemple #21
0
/*
 * static function implementation
 */
static void gdt_init() {
	log(LOG_TAG_INFO, "Init global descriptor tables");
	gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
	gdt_ptr.base = (u32int)&gdt_entries;
	
	gdt_set_gate(0, 0, 0, 0, 0);					//Null segment
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);		//Code segemnt
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);		//Data segment
	gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);		//User mode code segment
	gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);		//User mode data segment
	
	gdt_flush((u32int)& gdt_ptr);
	
}
Exemple #22
0
static void init_gdt()
{
    gdt_ptr.limit = (sizeof(gdt_entry_t)*5)-1;
    // forgive me
    gdt_ptr.base = (u32int)&gdt_entries;

    gdt_set_gate(0,0,0,0,0); //null segment
    gdt_set_gate(1,0,LIMIT,0x9A,0xCF); // kernel code segment
    gdt_set_gate(2,0,LIMIT,0x92,0xCF); // kernel data segment
    gdt_set_gate(3,0,LIMIT,0xFA,0xCF); // user code segment
    gdt_set_gate(4,0,LIMIT,0xF2,0xCF); // user data segment

    gdt_flush((u32int)&gdt_ptr);
}
Exemple #23
0
static void init_gdt()
{
	gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
	gdt_ptr.base  = (uint32_t)&gdt_entries;	
	
	gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

    gdt_flush((uint32_t)&gdt_ptr);
    kprintf("GDT:: Finished init of GDT AND it's in memory! :D\n");
}
Exemple #24
0
void gdt_install()
{
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1; // Limit of GDT
    gp.base = (int)&gdt; // Base address of GDT

    gdt_set_gate(0, 0, 0, 0, 0); // GDT must start with a NULL descriptor

    /* Base Address = 0, limit = 4GB, Granularity = 4KB, 32 bit opcodes, type = Code Segment */
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // 0x9A = 10011010, 0xCF = 11001111 
    /* Base Address = 0, limit = 4GB, Granularity = 4KB, 32 bit opcodes, type = Data Segment */
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // 0x92 = 10010010, 0xCF = 11001111

    gdt_flush(); // Gets rid of the old GDT and installs the changes
}
Exemple #25
0
void gdt_init()
{
//Setup GDT pointer
    gdtp.limit=(sizeof(struct gdt_entry)*GDT_COUNT)-1;
    gdtp.base=(unsigned int)&gdt;

//NULL Descriptor
    gdt_set_gate(0,0,0,0,0);

//Code segment
    gdt_set_gate(1,0,0xFFFFFFFF,0x9A,0xCF);

//Data segment
    gdt_set_gate(2,0,0xFFFFFFFF,0x92,0xCF);

//Code segment
    gdt_set_gate(3,0,0xFFFFFFFF,0xFA,0xCF);

//Data segment
    gdt_set_gate(4,0,0xFFFFFFFF,0xF2,0xCF);

//Task state segment
    gdt_set_gate(5,(unsigned int)&mt_task_state_segment,(unsigned int)&mt_task_state_segment + sizeof(mt_task_state_segment) + 1,0x89,0x40);

//16-bit Code segment
    gdt_set_gate(6,0,0xFFFF,0x9A,0x00);

//16-bit Data segment
    gdt_set_gate(7,0,0xFFFF,0x92,0x00);

//Setup GDT
    gdt_setup();
}
Exemple #26
0
/*
 * 初始化GDT
 */
void init_gdt()
{
	// 设置GDT指针
	gdt_ptr.limit = (sizeof(struct gdt_entry_struct) * 5) - 1;
	gdt_ptr.base = (u_int32)&gdt_entries;

	// 设置全局描述符
	gdt_set_gate(0, 0, 0, 0, 0); 			// 第一个为全0
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); 	// 代码段
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); 	// 数据段
	gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); 	// 用户模式代码段
	gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); 	// 用户模式数据段

	// 将GDT写到GDTR
	gdt_flush((u_int32)&gdt_ptr);
}
Exemple #27
0
/* gdt_install
 *
 * Set up our GDT.
 */
void gdt_install()
{
	gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
	gp.base = (unsigned int)&gdt;

	/* Set up the null descriptor. */
	gdt_set_gate(0, 0, 0, 0, 0);

	/* Set up the text segment descriptor. */
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);

	/* Set up the data segment descriptor. */
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

	gdt_flush();
}
Exemple #28
0
static void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
	// Firstly, let's compute the base and limit of our entry into the GDT.
	uint32_t base = (uint32_t) &tss_entry;
	uint32_t limit = base + sizeof(tss_entry);

	// Now, add our TSS descriptor's address to the GDT.
	gdt_set_gate(num, base, limit, 0xE9, 0x00);

	// Ensure the descriptor is initially zero.
	memset(&tss_entry, 0, sizeof(tss_entry));

	tss_entry.ss0 = ss0; // set the kernel stack segment
	tss_entry.esp0 = esp0; // set the kernel stack pointer

	// Here we set the cs, ss, ds, es, fs and gs entries in the TSS.
	// These specify what segments should be loaded when the processor
	// switches to kernel mode. Therefore they are just our normal
	// kernel code/data segments - 0x08 and 0x10 respectively,
	// but with the last two bits set, making 0x0b and 0x13.
	// The setting of these bits sets the RPL (requested privilege level)
	// to 3, meaning that this TSS can be used to switch to
	// kernel mode from ring 3.
	tss_entry.cs = 0x0b;
	tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs =
			0x13;
}
Exemple #29
0
/**
 * Write a TSS (we only do this once)
 */
static void
write_tss(
		int32_t num,
		uint16_t ss0,
		uint32_t esp0
		) {
	uintptr_t base  = (uintptr_t)&tss_entry;
	uintptr_t limit = base + sizeof(tss_entry);

	/* Add the TSS descriptor to the GDT */
	gdt_set_gate(num, base, limit, 0xE9, 0x00);

	memset(&tss_entry, 0x0, sizeof(tss_entry));

	tss_entry.ss0    = ss0;
	tss_entry.esp0   = esp0;
	/* Zero out the descriptors */
	tss_entry.cs     = 0x0b;
	tss_entry.ss     =
		tss_entry.ds =
		tss_entry.es =
		tss_entry.fs =
		tss_entry.gs = 0x13;
	tss_entry.iomap_base = sizeof(tss_entry);
}
/* Init the task state segment structure */
static void tss_write(int32_t num, uint16_t ss0, uint32_t esp0)
{
    uint32_t base, limit;
    /* Firstly, let's compute the base and limit of our entry into the GDT */
    base = (uint32_t) &tss_entry;
    limit = base + sizeof(tss_entry);

    /* Now add the TSS descriptor's address to the GDT */
    gdt_set_gate(num, base, limit, 0xE9, 0x00);

    /* Ensure the descriptor is initially zero */
    memset(&tss_entry, 0, sizeof(tss_entry));

    tss_entry.ss0 = ss0;    /* Set the kernel stack segment */
    tss_entry.esp0 = esp0;  /* Set the kernel stack pointer */

    /* Here we set the cs, ss, ds, es, fs and gs entries in the TSS. The specify
    *  what segments should be loaded when the processor switches to kernel mode.
    *  Therefore they are just the normal kernel code/data segments - 0x08 and
    *  0x10 respectively, but with the last two bits set, making 0x0b and 0x13.
    *  The setting of these bits sets the RP (Requested Privilege Level) to 3,
    *  meaning that this TSS can be used to switch to kernel mode from ring 3 */
    tss_entry.cs = 0x0b;
    tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
}