/** * @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); }
void install_gdt() { gp.base=(unsigned int)&gdt; /* set base address to our descriptor table */ gp.limit=(sizeof(struct gdt_entry) * 3)-1; /* (size of our gdt table)-1 */ /* NULL descriptor table - CPU needs it */ set_gdt_entry(0,0,0,0,0); /* Code Segment */ set_gdt_entry(1,0x0,0xFFFFF,0x9A,0xC0); /* cs:0 will be located at 4.MB of memory access; 0x9A (1 - 00 - 1 - 1010b) | | | | P DPL S TYPE P: 1 ( segment present ) DPL: 0 (Ring 0) S: 1 (For CS/DS/SS segments it has to be 1) TYPE: 1010 bit3: (1) if S=1 and bit3=1 then its Code Segment else S=1 and bit3=0 then Data Segment bit2: (0) (TODO: write description) bit1: (1) For Code Segment 0 means you can't read segment, 1 means you can bit0; (0) The segment has been accessed(1) or not(0) granularity: 0xC0 (1 - 1 - 0 - 0 - 0000) | | | | | G D/B 0 AVL Size G:1 segment size specified in bytes(0) or in 4K pages(1) D/B:1 For Code Segment, this field states default address/operand size as 32bit(1) or 16bit(0) 0: Reserved bit always 0 AVL: Avaible bit for programmers own use Size: (TODO: write description) */ /* Data Segment */ set_gdt_entry(2,0x0,0xFFFFF,0x92,0xC0); /* ds:0 will be in 8.MB of memory access: 0x92 (10010010) P: 1 present segment DPL: privilege level ring0 S: 1 for CS/DS/SS Type: bit3 (0): if S=1 bit3=0 then Data Segment bit2 (0): (TODO) bit1 (1): For Data Segment, 0 means read-only, 1 means r/w bit0 (0): Segment has been already accessed? granularity: same as above CS's granularity */ gdt_flush(); }
/* 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); }
void init_desc(void) { // IDT entries ISR_ENTRY(0); ISR_ENTRY(1); ISR_ENTRY(2); ISR_ENTRY(3); ISR_ENTRY(4); ISR_ENTRY(5); ISR_ENTRY(6); ISR_ENTRY(7); ISR_ENTRY(8); ISR_ENTRY(9); ISR_ENTRY(10); ISR_ENTRY(11); ISR_ENTRY(12); ISR_ENTRY(13); ISR_ENTRY(14); ISR_ENTRY(15); ISR_ENTRY(16); ISR_ENTRY(17); ISR_ENTRY(18); ISR_ENTRY(19); ISR_ENTRY(20); ISR_ENTRY(21); ISR_ENTRY(22); ISR_ENTRY(23); ISR_ENTRY(24); ISR_ENTRY(25); ISR_ENTRY(26); ISR_ENTRY(27); ISR_ENTRY(28); ISR_ENTRY(29); ISR_ENTRY(30); ISR_ENTRY(31); SYSG((u32)isr128, this_cpu.idt[0x80]);// SYStem Call goes here ISR_ENTRY(255); IRQ_ENTRY(0); IRQ_ENTRY(1); IRQ_ENTRY(2); IRQ_ENTRY(3); IRQ_ENTRY(4); IRQ_ENTRY(5); IRQ_ENTRY(6); IRQ_ENTRY(7); IRQ_ENTRY(8); IRQ_ENTRY(9); IRQ_ENTRY(10); IRQ_ENTRY(11); IRQ_ENTRY(12); IRQ_ENTRY(13); IRQ_ENTRY(14); IRQ_ENTRY(15); write_tss(&this_cpu.gdt[GDT_TSS_ENTRY], __KERNEL_DS, 0x0); this_cpu.idt_ptr.limit = IDT_ENTRY_NUM * sizeof(struct idt_desc_struct); this_cpu.idt_ptr.base = (u32)&(this_cpu.idt); gdt_flush((u32)&(this_cpu.gdt_ptr)); init_8259A(); irq_enable(2); memset((u8 *)&interrupt_handlers , 0, sizeof(interrupt_handlers)); idt_flush((u32)&(this_cpu.idt_ptr)); tss_flush(); }
/* 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(); }
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; }
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(); }
/* * Initialize The Global Descriptor Table * Should be called by kernel_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(void) { /* Setup the GDT pointer and limit */ gdt_p.limit = (sizeof(struct gdt_entry) * 3) - 1; gdt_p.base = (uint32_t)&gdt; /* Our NULL descriptor */ gdt_set_entry(SEG_NULL, 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_entry(SEG_CODE, 0, 64*1024*1024, 0x9A, 0xCF); /* Kernel Code Segment */ gdt_set_entry(SEG_CODE, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Kernel Code Segment */ /* 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_entry(SEG_DATA, 0, 64*1024*1024, 0x92, 0xCF); /* Kernel Data Segment */ gdt_set_entry(SEG_DATA, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Kernel Data Segment */ //gdt_set_entry(SEG_USR1, 0, 64*1024*1024, 0xFA, 0xCF); /* User-Mode Segment 1 */ //gdt_set_entry(SEG_USR2, 0, 64*1024*1024, 0xF2, 0xCF); /* User-Mode Segment 2 */ //gdt_set_entry(SEG_TSS, 0, 0, 0, 0); /* Flush out the old GDT and install the new changes! */ gdt_flush(); }
void gdt_init() { gdtPointer.limit = (sizeof(gdt_entry_t) * 6) - 1; gdtPointer.base = (unsigned) &gdt; // Null Selector gdt_set_entry(0, 0, 0, 0, 0); // SYSENTER Code Segment gdt_set_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // SYSENTER Data Segment (Stack) gdt_set_entry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // SYSEXIT Code Segment gdt_set_entry(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // SYSEXIT Data Segment (User-mode Stack) gdt_set_entry(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // TSS Segment (Multitasking) gdt_set_entry(5, 0, 0xFFFFFFFF, 0x90, 0xCF); gdt_flush((unsigned) &gdtPointer); }
// Initialize the GDT void gdt_init() { // Tasks setup for (int i = 0; i < tasks_nb; i++) setup_task(i); // Set the address and the size of the GDT in the pointer gdt_ptr.limit = sizeof(gdt); gdt_ptr.base = (uint32_t) &gdt; // Initializing the three segment descriptors in the GDT : NULL, code segment, data segment gdt[0] = null_segment(); gdt[1] = code_segment(0, 1048575, DPL_KERNEL); gdt[2] = data_segment(0, 1048575, DPL_KERNEL); // gdt[3] : entry for initial kernel TSS (CPU state of first task saved there) static uint8_t initial_tss_kernel_stack[65536]; // 64KB of stack static tss_t initial_tss; gdt[3] = gdt_make_tss(&initial_tss, DPL_KERNEL); memset(&initial_tss, 0, sizeof(tss_t)); initial_tss.ss0 = GDT_KERNEL_DATA_SELECTOR; initial_tss.esp0 = ((uint32_t) initial_tss_kernel_stack) + sizeof(initial_tss_kernel_stack); // Load the GDT gdt_flush(&gdt_ptr); // Load the task register to point to the initial TSS selector load_task_register(gdt_entry_to_selector(&gdt[3])); // Confirmation message set_text_color(LIGHT_GREEN); printf("OK\n"); set_text_color(WHITE); }
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(); }
void kmain(multiboot_info_t* mbd, unsigned long magic) { if(magic != MULTIBOOT_BOOTLOADER_MAGIC) { scrn_setmode(GREEN,BLACK); scrn_print("Algo salio muy muy mal. No se que mas decirte."); return; } scrn_cls(); scrn_setmode(GREEN,BLACK); scrn_print("BIENVENIDO A juampiOS\n\t" "Estamos trabajando para ofrecerle " "el OS del futuro.\n"); scrn_print("INICIALIZANDO GDT..."); gdt_init(); gdt_flush(); scrn_print("OK\nINICIALIZANDO IDT PARA LAS EXCEPCIONES..."); initialize_exception_handlers(); idt_init_exceptions(); remap_pic(); scrn_print("OK\nINICIALIZANDO IDT PARA LAS INTERRUPCIONES Y SYSCALLS..."); irq_init_handlers(); syscalls_initialize(); idt_init_interrupts(); idt_init_syscalls(); idt_flush(); irq_sti_force(); scrn_printf("OK\nCHEQUEANDO ESTADO DE LOS MODULOS..."); scrn_printf("%u MODULOS CARGADOS\n",mbd->mods_count); scrn_print("CHECKEANDO ESTADO DE LA MEMORIA\n"); // Chequeamos que la cantidad de memoria RAM presente. if(mbd->flags & 1) { scrn_printf("\tCantidad de RAM en el sistema:\n" "\t\tLower: %u Kb, Upper: %u Kb\n", mbd->mem_lower,mbd->mem_upper); } else { kernel_panic("Mapa de memoria de GRUB invalido"); } scrn_print("INICIALIZANDO LAS ESTRUCTURAS DE MEMORIA DEL KERNEL..."); module_t* grub_modules = (module_t*) mbd->mods_addr; uint kernel_end_addr = grub_modules[mbd->mods_count-1].mod_end; // El mapa de memoria upper es a partir del primer megabyte ergo el primer // lugar donde nos vamos de largo es 1024 kilobytes mas la memoria que dice GRUB paging_init(kernel_end_addr, (1024+mbd->mem_upper)*1024); scrn_printf("OK\n"); scrn_print("INICIALIZANDO DISCO ATA\n"); hdd_init(); scrn_printf("INICIALIZANDO FILESYSTEM MINIX\n"); init_disk_super_block(); keybuffer_init(1024); scheduler_init(); void * buffer = (void *) grub_modules[0].mod_start; jump_to_initial(buffer); while(1) ; }
static void seg_init(){ g_ptr.limit = (sizeof(struct w_gdte) * 5) - 1; g_ptr.base = (w_uint32)&gdt_entries; w_uint32 tmp_access; w_uint32 tmp_gran; /* Segment 0 - Null Segment */ set_gdt(0, 0, 0, 0, 0); /* Segment 1 - Kernel Code Segment */ tmp_access = SEG_P | SEG_W | SEG_SEG | SEG_KERN | SEG_X; tmp_gran = SEG_32 | SEG_GPAGE; set_gdt(1, 0, 0xFFFFFFFF, tmp_access, tmp_gran); /* Segment 2 - Kernel Data Segment */ tmp_access = SEG_P | SEG_W | SEG_SEG | SEG_KERN; tmp_gran = SEG_32 | SEG_GPAGE; set_gdt(2, 0, 0xFFFFFFFF, tmp_access, tmp_gran); /* Segment 3 User Code Segment */ tmp_access = SEG_P | SEG_W | SEG_SEG | SEG_USER | SEG_X; tmp_gran = SEG_32 | SEG_GPAGE | SEG_AVAIL; set_gdt(3, 0, 0xFFFFFFFF, tmp_access, tmp_gran); /* Segment 4 - User Data Segment */ tmp_access = SEG_P | SEG_W | SEG_SEG | SEG_USER; tmp_gran = SEG_32 | SEG_GPAGE | SEG_AVAIL; set_gdt(4, 0, 0xFFFFFFFF, tmp_access, tmp_gran); /* Segment 5 - User TLS Segment */ tmp_access = SEG_P | SEG_W | SEG_SEG | SEG_USER; tmp_gran = SEG_32 | SEG_GPAGE | SEG_AVAIL; set_gdt(5, 0, 0xFFFFFFFF, tmp_access, tmp_gran); /* Segment 6 - TSS Segment */ tmp_access = SEG_P | SEG_KERN | SEG_X | SEG_TSS; tmp_gran = SEG_32 | SEG_GBYTE; w_uint32 addr = (w_uint32)¤t_tss; set_gdt(6, addr, sizeof(struct w_tss), tmp_access, tmp_gran); gdt_flush(&g_ptr); }
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(); }
void gdt_install(void) { //update pointer gp.size = (sizeof(struct gdt_entry) * I86_GDT_ENTRY_COUNT) - 1; gp.offset = (uint32_t)&gdt; //load gdt gdt_flush(); }
// Initialize the GDT void gdt_init() { // TODO: fixer la limite de gdt_ptr, puis la faire pointer sur la GDT // TODO: initialisation des trois descripteurs de segment: NULL, segment code, segment data // Les descripteurs de code et data doivent avoir un DPL de 0. // Load the GDT gdt_flush(&gdt_ptr); }
void gdt_init() { gdt_ptr.limit = sizeof(gdt_entry_t) * 3 - 1; gdt_ptr.base = (uint32_t) &gdt_entries; gdt_setGate(0, 0, 0, 0, 0 ); gdt_setGate(1, 0, 0xFFFFF, 0x9A, 0xCF); gdt_setGate(2, 0, 0xFFFFF, 0x92, 0xCF); gdt_flush(&gdt_ptr); }
void gdt_init() { gdt_pointer.limit = (sizeof(gdt_entry_t) * 5) - 1; gdt_pointer.base = (uint32) &gdt_entries; gdt_set_entry(0, 0, 0, 0, 0); gdt_fill_entry(1, 0, 0xFFFFFFFF, GDT_RING_0, GDT_CODE_SEGMENT); gdt_fill_entry(2, 0, 0xFFFFFFFF, GDT_RING_0, GDT_DATA_SEGMENT); gdt_fill_entry(3, 0, 0xFFFFFFFF, GDT_RING_3, GDT_CODE_SEGMENT); gdt_fill_entry(4, 0, 0xFFFFFFFF, GDT_RING_3, GDT_DATA_SEGMENT); gdt_flush((uint32) &gdt_pointer); }
// 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(); }
void gdtInit() { gdtPointer.limit = (sizeof(gdt_entry_t)*5) - 1; gdtPointer.base = (unsigned int)&gdt; gdtSetGate(0, 0, 0, 0, 0); gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); gdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); gdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); gdt_flush((unsigned int)&gdtPointer); }
/** * initializes the GDT */ void gdt_init() { gp.limit = (sizeof(struct gdt_entry) * 3) - 1; // the size of the GDT gp.base = (uint32) & gdt; // the base address of the GDT gdt_add_entry(0, 0, 0, 0, 0); // first entry: the null descriptor gdt_add_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // second entry: code segment gdt_add_entry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // third entry: data segment gdt_flush((uint32)&gp); // replace the old GDT by the new one }
bool gdt_setup(void) { bool status; gdt_location.limit = (sizeof(struct gdt_entry) * BERMUDOS_GDT_NB_ENTRY) - 1; gdt_location.base = (uint32_t)&kernel_GDT; status = gdt_set_entry(0, (uint32_t)(NULL), 0, 0, 0) /* The GDT MUST start with a NULL entry */ && gdt_set_entry(1, (uint32_t)(NULL), 0xFFFFFFFF, GDT_ENTRY_DATA_SEGMENT, GDT_GRANULARITY_4KiB | GDT_PROTECTED_32_BIT) && gdt_set_entry(2, (uint32_t)(NULL), 0xFFFFFFFF, GDT_ENTRY_CODE_SEGMENT, GDT_GRANULARITY_4KiB | GDT_PROTECTED_32_BIT); gdt_flush(); return status; }
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"); }
void GdtManager::initialize() { gdt_ptr.pointer = (uint32_t)&m_gdt; // pointer to our structure gdt_ptr.entries = 3*sizeof(m_gdt) - 1; // last valid byte is size - 1 setGate(0, 0, 0, 0, 0); // null segment setGate(1, 0, 0xfffff, 0x9a, 0xcf); // code segment (access: segment present: 1, dpl (ring): 00, descriptor type: 1, type: 1010) setGate(2, 0, 0xfffff, 0x92, 0xcf); // data segment (access: segment present: 1, dpl (ring): 00, descriptor type: 1, type: 0010) // push to CPU gdt_flush((uint32_t) &gdt_ptr); }
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 }
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"); }
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); }
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); }
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); }
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); }