/* * _fill_idt_interrupts_sys * DESCRIPTION: Fill in the interrupt entries in the IDT. * INPUTS: none * OUTPUTS: none * RETURN VALUE: none * SIDE EFFECTS: Change contents in the IDT table. */ void _fill_idt_interrupts_sys(){ idt_desc_t idt_temp; // Exception and interrupts use interrupt gate idt_temp.seg_selector = KERNEL_CS; idt_temp.size = 1; // Indicates 32 Bits idt_temp.dpl = 0x0; // Kernel level privilege. idt_temp.present = 1; // Mark as present idt_temp.reserved4 = 0; // Reserved. idt_temp.reserved3 = 0; idt_temp.reserved2 = 1; idt_temp.reserved1 = 1; idt_temp.reserved0 = 0; SET_IDT_ENTRY(idt_temp, &PIT_handler); idt[PIT_IDT_ENTRY] = idt_temp; SET_IDT_ENTRY(idt_temp, &KB_handler); idt[KB_IDT_ENTRY] = idt_temp; SET_IDT_ENTRY(idt_temp, &RTC_handler); idt[RTC_IDT_ENTRY] = idt_temp; // Using TRAP Gates idt_temp.dpl = 3; idt_temp.reserved3 = 1; SET_IDT_ENTRY(idt_temp, &syscall_handler); idt[0x80] = idt_temp; }
/* * void populate_idt(); * Inputs: none * Return Value: void * Function: Fills the idt with the correct functions */ void populate_idt() { int i; /*initializing the specific interrupts 0 - 20*/ void (* arr[NUM_VEC]) = { ÷_by_zero, &reserved_1, &non_maskable_interrupt, &breakpoint, &overflow, &BOUND_range_exceeded, &invalid_opcode, &device_not_available, &double_fault, &coprocessor_segment_overrun, &invalid_TSS, &segment_not_present, &stack_segment_fault, &general_protection, &page_fault, &common_interrupt, &floating_point_error, &alignment_check, &machine_check, &SIMD_floating_point_exception }; /*iterating through idt, populating with correct interrupts*/ for(i = 0; i< NUM_VEC; i++) { idt[i].present = 1; idt[i].dpl = 0; idt[i].reserved0 = 0; idt[i].size = 1; idt[i].reserved1 = 1; idt[i].reserved2 = 1; idt[i].reserved3 = 0; idt[i].reserved4 = 0; idt[i].seg_selector = KERNEL_CS; /*Do not set IDT_ENTRY for 20 - 32 (Intel Reserved) */ if(i >= EXCEPTION_INDEX) { /*Set common interrupt for user defined*/ SET_IDT_ENTRY(idt[i],&common_interrupt); } else if(i < 20) { if( i == 15 ) { /*DO NOTHING, Intel Reserved*/ }else{ SET_IDT_ENTRY(idt[i], arr[i]); } } } /*setting more specific interrupts*/ SET_IDT_ENTRY(idt[RTC_INDEX],&asm_rtc); SET_IDT_ENTRY(idt[KEYBOARD_INDEX],&asm_keyboard); SET_IDT_ENTRY(idt[SYS_CALLS_INDEX],&syscall); idt[SYS_CALLS_INDEX].dpl = 3; idt[SYS_CALLS_INDEX].reserved3 = 1; SET_IDT_ENTRY(idt[PIT_INDEX],&next_task); /*loading IDTR*/ lidt(idt_desc_ptr); }
/* Set IDT value helper function * @param table_idx: entry index in the IDT table to be set * @param type: the type of the IDT entry * @param handler: function pointer to the exception or interrupt handler * @param dpl: descriptor priviledge level of the interrupt * @param segment: segment pointer * @return NONE */ void set_gate(unsigned int table_idx, int type, void* handler, unsigned dpl, unsigned segment) { // Declare a interrupt descriptor struct idt_desc_t desc = idt[table_idx]; // First set the offset (pointer to the handler function) SET_IDT_ENTRY(desc, handler); desc.seg_selector = (uint16_t)segment; // seg_selector is KERNEL_CS desc.dpl = (uint32_t)dpl; // set dpl desc.reserved4 = 0; // set reserved bit 4, this is always 0 desc.present = 1; // Make this entry visible // Set the value of the reserved bits based on the type of the gate switch(type) { // Reserved bits for EXCEPTIONS case TRAP_GATE: desc.reserved0 = 0; desc.size = 1; // This is always 1 desc.reserved1 = 1; desc.reserved2 = 1; desc.reserved3 = 1; break; // Reserved bits for HARDWARE and SOFTWARE INTERRUPTS case SYS_GATE: case INTR_GATE: desc.reserved0 = 0; desc.size = 1; // This is always 1 desc.reserved1 = 1; desc.reserved2 = 1; desc.reserved3 = 0; break; } // Insert the new entry into the IDT table idt[table_idx] = desc; }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry (unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; /* Clear the screen. */ clear(); paging_init(); /* Am I booted by a Multiboot-compliant boot loader? */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf ("Invalid magic number: 0x%#x\n", (unsigned) magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *) addr; /* Print out the flags. */ printf ("flags = 0x%#x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if (CHECK_FLAG (mbi->flags, 0)) printf ("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); /* Is boot_device valid? */ if (CHECK_FLAG (mbi->flags, 1)) printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device); /* Is the command line passed? */ if (CHECK_FLAG (mbi->flags, 2)) printf ("cmdline = %s\n", (char *) mbi->cmdline); if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i<16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; } } /* Bits 4 and 5 are mutually exclusive! */ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) { printf ("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if (CHECK_FLAG (mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf ("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned) elf_sec->num, (unsigned) elf_sec->size, (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); } /* Are mmap_* valid? */ if (CHECK_FLAG (mbi->flags, 6)) { memory_map_t *mmap; printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); for (mmap = (memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size))) printf (" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned) mmap->size, (unsigned) mmap->base_addr_high, (unsigned) mmap->base_addr_low, (unsigned) mmap->type, (unsigned) mmap->length_high, (unsigned) mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000; ltr(KERNEL_TSS); } idt_desc_t interrupt; interrupt.seg_selector = KERNEL_CS; interrupt.dpl = 0; interrupt.size = 1; interrupt.reserved0 = 0; interrupt.reserved1 = 1; interrupt.reserved2 = 1; interrupt.reserved3 = 0; interrupt.reserved4 = 0; interrupt.present = 1; idt_desc_t divide_error_desc = interrupt; SET_IDT_ENTRY(divide_error_desc, divide_error); idt[0] = divide_error_desc; idt_desc_t reserved_desc = interrupt; SET_IDT_ENTRY(reserved_desc, reserved); idt[1] = reserved_desc; idt_desc_t nmi_interrupt_desc = interrupt; SET_IDT_ENTRY(nmi_interrupt_desc, nmi_interrupt); idt[2] = nmi_interrupt_desc; idt_desc_t breakpoint_desc = interrupt; SET_IDT_ENTRY(breakpoint_desc, breakpoint); idt[3] = breakpoint_desc; idt_desc_t overflow_desc = interrupt; SET_IDT_ENTRY(overflow_desc, overflow); idt[4] = overflow_desc; idt_desc_t bound_range_exceeded_desc = interrupt; SET_IDT_ENTRY(bound_range_exceeded_desc, bound_range_exceeded); idt[5] = bound_range_exceeded_desc; idt_desc_t invalid_opcode_desc = interrupt; SET_IDT_ENTRY(invalid_opcode_desc, invalid_opcode); idt[6] = invalid_opcode_desc; idt_desc_t device_not_available_desc = interrupt; SET_IDT_ENTRY(device_not_available_desc, device_not_available); idt[7] = device_not_available_desc; idt_desc_t double_fault_desc = interrupt; SET_IDT_ENTRY(double_fault_desc, double_fault); idt[8] = double_fault_desc; idt_desc_t coprocessor_segment_overrun_desc = interrupt; SET_IDT_ENTRY(coprocessor_segment_overrun_desc, coprocessor_segment_overrun); idt[9] = divide_error_desc; idt_desc_t invalid_tss_desc = interrupt; SET_IDT_ENTRY(invalid_tss_desc, invalid_tss); idt[10] = invalid_tss_desc; idt_desc_t segment_not_present_desc = interrupt; segment_not_present_desc.present = 0; SET_IDT_ENTRY(segment_not_present_desc, segment_not_present); idt[11] = segment_not_present_desc; idt_desc_t stack_segment_fault_desc = interrupt; SET_IDT_ENTRY(stack_segment_fault_desc, stack_segment_fault); idt[12] = stack_segment_fault_desc; idt_desc_t general_protection_desc = interrupt; SET_IDT_ENTRY(general_protection_desc, general_protection); idt[13] = general_protection_desc; idt_desc_t page_fault_desc = interrupt; SET_IDT_ENTRY(page_fault_desc, page_fault); idt[14] = page_fault_desc; idt_desc_t math_fault_desc = interrupt; SET_IDT_ENTRY(math_fault_desc, math_fault); idt[16] = math_fault_desc; idt_desc_t alignment_check_desc = interrupt; SET_IDT_ENTRY(alignment_check_desc, alignment_check); idt[17] = alignment_check_desc; idt_desc_t machine_check_desc = interrupt; SET_IDT_ENTRY(machine_check_desc, machine_check); idt[18] = machine_check_desc; idt_desc_t simd_desc = interrupt; SET_IDT_ENTRY(simd_desc, simd_floating_exception); idt[19] = simd_desc; idt_desc_t keyboard_desc = interrupt; SET_IDT_ENTRY(keyboard_desc, &keyboard_wrapper); idt[0x21] = keyboard_desc; idt_desc_t rtc_desc = interrupt; SET_IDT_ENTRY(rtc_desc, &rtc_wrapper); idt[0x28] = rtc_desc; // load idt lidt(idt_desc_ptr); /* Init the PIC */ i8259_init(); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ // initialize rtc rtc_init(); // enable irq1 for keyboard enable_irq(1); /* Enable interrupts */ /* Do not enable the following until after you have set up your * IDT correctly otherwise QEMU will triple fault and simple close * without showing you any output */ printf("Enabling Interrupts\n"); sti(); int freq = 0x0010; write_rtc((char *) (&freq)); // while(1) { // printf("h"); // read_rtc(); // } // int x = 3 / 0; // int * x = 0x12345000; // int y; // y = *x; /* Execute the first program (`shell') ... */ /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry (unsigned long magic, unsigned long addr) { uint32_t fileptr;// start of file system multiboot_info_t *mbi; /* Initialize the screen. */ terminal_open(); /* Am I booted by a Multiboot-compliant boot loader? */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf ("Invalid magic number: 0x%#x\n", (unsigned) magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *) addr; /* Print out the flags. */ printf ("flags = 0x%#x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if (CHECK_FLAG (mbi->flags, 0)) printf ("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); /* Is boot_device valid? */ if (CHECK_FLAG (mbi->flags, 1)) printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device); /* Is the command line passed? */ if (CHECK_FLAG (mbi->flags, 2)) printf ("cmdline = %s\n", (char *) mbi->cmdline); if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; fileptr = mod->mod_start; while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i<16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; } } /* Bits 4 and 5 are mutually exclusive! */ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) { printf ("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if (CHECK_FLAG (mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf ("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned) elf_sec->num, (unsigned) elf_sec->size, (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); } /* Are mmap_* valid? */ if (CHECK_FLAG (mbi->flags, 6)) { memory_map_t *mmap; printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); for (mmap = (memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size))) printf (" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned) mmap->size, (unsigned) mmap->base_addr_high, (unsigned) mmap->base_addr_low, (unsigned) mmap->type, (unsigned) mmap->length_high, (unsigned) mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000; ltr(KERNEL_TSS); } /* Mask all IRQs again*/ int j; for(j=0;j<16;j++) { disable_irq(j); } /* Init the PIC */ i8259_init(); /* Init IDT vector 0-20*/ { int i; for(i=0;i<20;i++) { if(i!=15) { //Define an idt_desc_t structure idt_desc_t idt_desc; //populate w/ correct values idt_desc.seg_selector=0x0010; idt_desc.present=1; idt_desc.size=1; idt_desc.dpl=0x0; idt_desc.reserved1=1; idt_desc.reserved2=1; idt_desc.reserved3=1; SET_IDT_ENTRY(idt_desc, ehandlers[i]); //Set new entry in table idt[i]=idt_desc; } } } /* Init IRQ Interrupts*/ //Timer Chip { //Define an idt_desc_t structure idt_desc_t idt_desc; //populate w/ correct values idt_desc.seg_selector=0x0010; idt_desc.present=1; idt_desc.size=1; idt_desc.dpl=0x0; idt_desc.reserved1=1; idt_desc.reserved2=1; SET_IDT_ENTRY(idt_desc, irqhandlers[0]); //Set new entry in table idt[32]=idt_desc; //Disable IRQ masking //enable_irq(0); } //Keyboard { //Define an idt_desc_t structure idt_desc_t idt_desc; //populate w/ correct values idt_desc.seg_selector=0x0010; idt_desc.present=1; idt_desc.size=1; idt_desc.dpl=0x0; idt_desc.reserved1=1; idt_desc.reserved2=1; SET_IDT_ENTRY(idt_desc, irqhandlers[1]); //Set new entry in table idt[33]=idt_desc; //Disable IRQ masking //enable_irq(1); } //Real Time Clock { //Define an idt_desc_t structure idt_desc_t idt_desc; //populate w/ correct values idt_desc.seg_selector=0x0010; idt_desc.present=1; idt_desc.size=1; idt_desc.dpl=0x0; idt_desc.reserved1=1; idt_desc.reserved2=1; SET_IDT_ENTRY(idt_desc, irqhandlers[2]); //Set new entry in table idt[40]=idt_desc; //Disable IRQ masking //enable_irq(8); } /* Init System Call 0x80 */ //Define an idt_desc_t structure idt_desc_t idt_desc; //populate w/ correct values idt_desc.seg_selector=0x0010; idt_desc.present=1; idt_desc.size=1; idt_desc.dpl=0x0; idt_desc.reserved1=1; idt_desc.reserved2=1; SET_IDT_ENTRY(idt_desc, systemcall); //Set new entry in table idt[128]=idt_desc; //Load new IDT lidt(idt_desc_ptr); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ paging_init(); //Enable IRQ interrupts. enable_irq(8); enable_irq(2); enable_irq(1); /* Enable interrupts */ /* Do not enable the following until after you have set up your * IDT correctly otherwise QEMU will triple fault and simple close * without showing you any output */ printf("Enabling Interrupts\n"); sti(); /* This will be replaced by a system call after CP3 */ rtc_open(); filesys_init(fileptr); // start of filesystem while(1) { printf("Reading-> "); uint8_t buf[1024]; int cnt = terminal_read(buf, 1024); buf[cnt] = '\0'; puts ((int8_t*)"Typed: "); puts ((int8_t*)buf); putc('\n'); } /* Execute the first program (`shell') ... */ /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }
/* * idt_initialize * DESCRIPTION: The function to initilize the idt table * INPUTS: none * OUTPUTS: none * RETURN VALUE: none * SIDE EFFECTS: Call SET_IDT_ENTRY to set all the idt */ void idt_initialize() { /*Loop variables*/ int i = 0; for (i = 0; i < EXCEPTION_COUNT; ++i) { idt[i].seg_selector = KERNEL_CS; idt[i].reserved4 = 0; idt[i].reserved3 = 0; idt[i].reserved2 = 1; idt[i].reserved1 = 1; idt[i].size = 1; idt[i].reserved0 = 0; idt[i].dpl = 0; idt[i].present = 1; } SET_IDT_ENTRY(idt[0], division_by_zero); SET_IDT_ENTRY(idt[1], debug_exception); SET_IDT_ENTRY(idt[2], non_maskable_int); SET_IDT_ENTRY(idt[3], break_point); SET_IDT_ENTRY(idt[4], into_overflow); SET_IDT_ENTRY(idt[5], out_of_bounds); SET_IDT_ENTRY(idt[6], invalid_opcode); SET_IDT_ENTRY(idt[7], device_not_available); SET_IDT_ENTRY(idt[8], double_fault); SET_IDT_ENTRY(idt[9], co_segment_overrun); SET_IDT_ENTRY(idt[10], invalid_tss); SET_IDT_ENTRY(idt[11], segment_not_present); SET_IDT_ENTRY(idt[12], stack_fault); SET_IDT_ENTRY(idt[13], general_protection); SET_IDT_ENTRY(idt[14], page_fault); SET_IDT_ENTRY(idt[16], x87_floating_point); SET_IDT_ENTRY(idt[17], alignment_check); SET_IDT_ENTRY(idt[18], machine_check); SET_IDT_ENTRY(idt[19], SIMD_floating_point); //SET_IDT_ENTRY(idt[0x20],pit_interrput); /*Scheduler part*/ idt[PIT_IDX].seg_selector = KERNEL_CS; idt[PIT_IDX].reserved4 = 0; idt[PIT_IDX].reserved3 = 0; idt[PIT_IDX].reserved2 = 1; idt[PIT_IDX].reserved1 = 1; idt[PIT_IDX].size = 1; idt[PIT_IDX].reserved0 = 0; idt[PIT_IDX].dpl = 0; idt[PIT_IDX].present = 1; SET_IDT_ENTRY(idt[PIT_IDX],sched_link); /*Keyboard part*/ idt[KEYBOARD_IDX].seg_selector = KERNEL_CS; idt[KEYBOARD_IDX].reserved4 = 0; idt[KEYBOARD_IDX].reserved3 = 0; idt[KEYBOARD_IDX].reserved2 = 1; idt[KEYBOARD_IDX].reserved1 = 1; idt[KEYBOARD_IDX].size = 1; idt[KEYBOARD_IDX].reserved0 = 0; idt[KEYBOARD_IDX].dpl = 0; idt[KEYBOARD_IDX].present = 1; SET_IDT_ENTRY(idt[KEYBOARD_IDX],keyboard_link); /*RTC part*/ idt[RTC_IDX].seg_selector=KERNEL_CS; idt[RTC_IDX].reserved4 = 0; idt[RTC_IDX].reserved3 = 0; idt[RTC_IDX].reserved2 = 1; idt[RTC_IDX].reserved1 = 1; idt[RTC_IDX].size = 1; idt[RTC_IDX].reserved0 = 0; idt[RTC_IDX].dpl = 0; idt[RTC_IDX].present= 1 ; SET_IDT_ENTRY(idt[RTC_IDX],rtc_link); /*Mouse part*/ idt[MOUSE_IDX].seg_selector=KERNEL_CS; idt[MOUSE_IDX].reserved4 = 0; idt[MOUSE_IDX].reserved3 = 0; idt[MOUSE_IDX].reserved2 = 1; idt[MOUSE_IDX].reserved1 = 1; idt[MOUSE_IDX].size = 1; idt[MOUSE_IDX].reserved0 = 0; idt[MOUSE_IDX].dpl = 0; idt[MOUSE_IDX].present= 1 ; SET_IDT_ENTRY(idt[MOUSE_IDX],mouse_link); /*System call part*/ idt[SYSCALL_IDX].seg_selector=KERNEL_CS; idt[SYSCALL_IDX].reserved4 = 0; idt[SYSCALL_IDX].reserved3 = 0; idt[SYSCALL_IDX].reserved2 = 1; idt[SYSCALL_IDX].reserved1 = 1; idt[SYSCALL_IDX].size = 1; idt[SYSCALL_IDX].reserved0 = 0; idt[SYSCALL_IDX].dpl = 3; /*Specially for sys call*/ idt[SYSCALL_IDX].present= 1 ; SET_IDT_ENTRY(idt[SYSCALL_IDX],syscall_wrapper); }
/* * idt_init * DESCRIPTION: set IDT entries for interrupts * INPUTS: none * OUTPUTS: none * RETURN VALUE: none * SIDE EFFECTS: interrupts are assigned to proper INTs */ void idt_init() { idt_desc_t idt_interrupt; idt_interrupt.seg_selector = KERNEL_CS; idt_interrupt.reserved4 = 0x0; idt_interrupt.reserved3 = 0x0; idt_interrupt.reserved2 = 0x1; idt_interrupt.reserved1 = 0x1; idt_interrupt.reserved0 = 0x0; idt_interrupt.size = 0x1; idt_interrupt.dpl = 0x0; idt_interrupt.present = 0x1; idt_desc_t idt_exception = idt_interrupt; idt_exception.reserved3 = 1; idt_desc_t idt_syscall = idt_interrupt; idt_syscall.dpl = 3; idt_syscall.reserved3 = 1; int i; for (i = 0; i < 32; i++) { idt[i]= idt_exception; } for (i = 32; i < 256; i++) { idt[i] = idt_interrupt; } idt[0x80] = idt_syscall; SET_IDT_ENTRY(idt[0], ÷_error); SET_IDT_ENTRY(idt[1], &debug_exception); SET_IDT_ENTRY(idt[2], &nmi_interrupt); SET_IDT_ENTRY(idt[3], &breakpoint); SET_IDT_ENTRY(idt[4], &overflow); SET_IDT_ENTRY(idt[5], &bound_range_exceeded); SET_IDT_ENTRY(idt[6], &invalid_opcode); SET_IDT_ENTRY(idt[7], &device_not_available); SET_IDT_ENTRY(idt[8], &double_fault); SET_IDT_ENTRY(idt[9], &coprocessor_segment_overrun); SET_IDT_ENTRY(idt[10], &invalid_tss); SET_IDT_ENTRY(idt[11], &segment_not_present); SET_IDT_ENTRY(idt[12], &stack_fault); SET_IDT_ENTRY(idt[13], &general_protection); SET_IDT_ENTRY(idt[14], &page_fault); SET_IDT_ENTRY(idt[15], &common_exception); SET_IDT_ENTRY(idt[16], &floating_point_error); SET_IDT_ENTRY(idt[17], &alignment_check); SET_IDT_ENTRY(idt[18], &machine_check); SET_IDT_ENTRY(idt[19], &simd_floating_point_exception); SET_IDT_ENTRY(idt[0x20], irq_pit); SET_IDT_ENTRY(idt[0x21], irq_keyboard); SET_IDT_ENTRY(idt[0x28], irq_rtc); SET_IDT_ENTRY(idt[0x80], START_SYS_CALLS); //call sys calls }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry (unsigned long magic, unsigned long addr) { uint32_t file_system_start; multiboot_info_t *mbi; /* Clear the screen. */ clear(); /* Am I booted by a Multiboot-compliant boot loader? */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf ("Invalid magic number: 0x%#x\n", (unsigned) magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *) addr; /* Print out the flags. */ printf ("flags = 0x%#x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if (CHECK_FLAG (mbi->flags, 0)) printf ("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); /* Is boot_device valid? */ if (CHECK_FLAG (mbi->flags, 1)) printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device); /* Is the command line passed? */ if (CHECK_FLAG (mbi->flags, 2)) printf ("cmdline = %s\n", (char *) mbi->cmdline); if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; file_system_start = mod->mod_start; // store mod_start as start address of file system while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i<16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; mod++; } } /* Bits 4 and 5 are mutually exclusive! */ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) { printf ("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if (CHECK_FLAG (mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf ("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned) elf_sec->num, (unsigned) elf_sec->size, (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); } /* Are mmap_* valid? */ if (CHECK_FLAG (mbi->flags, 6)) { memory_map_t *mmap; printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); for (mmap = (memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size))) printf (" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned) mmap->size, (unsigned) mmap->base_addr_high, (unsigned) mmap->base_addr_low, (unsigned) mmap->type, (unsigned) mmap->length_high, (unsigned) mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000 - 4; ltr(KERNEL_TSS); } /////////////////////////////// /* Initialize first 20 IDT entries for exceptions */ /* Initialize interrupt descriptor entries defined in x86_desc.h*/ int i; for (i=0; i<EXCEPTION_NUM; i++) { idt[i].seg_selector = KERNEL_CS; // set up elements in the exception entry idt[i].reserved4 = 0; idt[i].reserved3 = 0; idt[i].reserved2 = 1; idt[i].reserved1 = 1; idt[i].size = 1; idt[i].reserved0 = 0; idt[i].dpl = 0; idt[i].present = 1; SET_IDT_ENTRY(idt[i], reserved); } // /* set 20 idt entries for exceptions */ init_exception(); // set idt entry for RTC { idt[RTC_ENTRY].seg_selector = KERNEL_CS; // set up elements in the RTC entry idt[RTC_ENTRY].reserved4 = 0; idt[RTC_ENTRY].reserved3 = 0; idt[RTC_ENTRY].reserved2 = 1; idt[RTC_ENTRY].reserved1 = 1; idt[RTC_ENTRY].size = 1; idt[RTC_ENTRY].reserved0 = 0; idt[RTC_ENTRY].dpl = 0; idt[RTC_ENTRY].present = 1; SET_IDT_ENTRY(idt[RTC_ENTRY], rtc_wrapper); // set idt entry for RTC } // set idt entry for keyboard { idt[KEYBRD_ENTRY].seg_selector = KERNEL_CS; // set up elements in the keyboard entry idt[KEYBRD_ENTRY].reserved4 = 0; idt[KEYBRD_ENTRY].reserved3 = 0; idt[KEYBRD_ENTRY].reserved2 = 1; idt[KEYBRD_ENTRY].reserved1 = 1; idt[KEYBRD_ENTRY].size = 1; idt[KEYBRD_ENTRY].reserved0 = 0; idt[KEYBRD_ENTRY].dpl = 0; idt[KEYBRD_ENTRY].present = 1; SET_IDT_ENTRY(idt[KEYBRD_ENTRY], keybrd_wrapper); // set idt entry for keyboard } //set idt entry for system call { idt[SYSCALL_ENTRY].seg_selector = KERNEL_CS; idt[SYSCALL_ENTRY].reserved4 = 0; idt[SYSCALL_ENTRY].reserved3 = 0; idt[SYSCALL_ENTRY].reserved2 = 1; idt[SYSCALL_ENTRY].reserved1 = 1; idt[SYSCALL_ENTRY].size = 1; idt[SYSCALL_ENTRY].reserved0 = 0; idt[SYSCALL_ENTRY].dpl = 3; idt[SYSCALL_ENTRY].present = 1; SET_IDT_ENTRY(idt[SYSCALL_ENTRY], syscall_wrapper); } { idt[MOUSE_VECTOR].seg_selector = KERNEL_CS; idt[MOUSE_VECTOR].reserved4 = 0; idt[MOUSE_VECTOR].reserved3 = 0; idt[MOUSE_VECTOR].reserved2 = 1; idt[MOUSE_VECTOR].reserved1 = 1; idt[MOUSE_VECTOR].size = 1; idt[MOUSE_VECTOR].reserved0 = 0; idt[MOUSE_VECTOR].dpl = 0; idt[MOUSE_VECTOR].present = 1; SET_IDT_ENTRY(idt[MOUSE_VECTOR], mouse_linkage); } // set idt entry for pit { idt[PIT_ENTRY].seg_selector = KERNEL_CS; idt[PIT_ENTRY].reserved4 = 0; idt[PIT_ENTRY].reserved3 = 0; idt[PIT_ENTRY].reserved2 = 1; idt[PIT_ENTRY].reserved1 = 1; idt[PIT_ENTRY].size = 1; idt[PIT_ENTRY].reserved0 = 0; idt[PIT_ENTRY].dpl = 3; idt[PIT_ENTRY].present = 1; SET_IDT_ENTRY(idt[PIT_ENTRY], pit_wrapper); } ///////////////////////////////// // keyboard_handler(); // test divide_error // i=1/0; // initialize devices // enable associated interrupts on PIC /* devices initialization ends*/ /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ /* Enable interrupts */ /* Do not enable the following until after you have set up your * IDT correctly otherwise QEMU will triple fault and simple close * without showing you any output */ i8259_init(); /* Init the PIC */ // printf("Enabling Interrupts\n"); paging_init(); // set up paging //testing purpose of paging // uint8_t * test_ptr = 0x000B8000; // * test_ptr = 1; // // uint8_t * test_ptr = 0xB6000; // *test_ptr = 1; // printf("paging works!!\n"); // clear(); sche_init(); pit_init(); rtc_init(); // init rtc keybrd_init(); init_mouse(); fs_init(file_system_start); // init file system, test case: test_fs_init() is commented in the fs_init function //sche_init(); for(i = 0; i < 30; i++){ pid_status[i] = 0; } pid = -1; // enable interrupts on processor /*****test cases*****/ // uint8_t* filename; /*test rtc open*/ // rtc_open(filename); /*test rtc write*/ // int32_t fd; // uint8_t* buf; // rtc_write(fd, buf, 2); // // /*test rtc read*/ // while(1){ // rtc_read(fd, buf, 16); // printf("rtc_read\n"); // } //test_dir_read(); // read_test_text(); // read file depends on the READ_TEXT and READ_TXT flag on the top of file_system_driver.c //read_test_exe(); /*****test cases*****/ //puts("here",1); enable_irq(8); //enable rtc interrupt enable_irq(1); //enable keyboard interrupt enable_irq(0); sti(); //while(1){ /* printf("here\n"); dentry_t tmp_dentry; uint32_t tmp_eip, user_esp; uint8_t buf[4]; read_dentry_by_name((uint8_t*)"testprint", &tmp_dentry); read_data(tmp_dentry.inode_num, 0, (uint8_t*)(0x08048000), 0x400000); read_data(tmp_dentry.inode_num, 24, buf, 4); printf("here2\n"); tmp_eip = 0x080481a4; user_esp = 0x8000000 + 0x400000 - 4; //user space stack = 132MB - 4B tss.esp0 =0x800000-4; //kernel stack = 128MB - 4B tss.ss0 = KERNEL_DS; asm volatile (" \n\ cli \n\ movw %0, %%ax \n\ movw %%ax, %%ds \n\ pushl %0 \n\ pushl %1 \n\ pushfl \n\ popl %%eax \n\ orl %2, %%eax \n\ pushl %%eax \n\ pushl %3 \n\ pushl %4 \n\ iret \n\ " : :"i"(USER_DS), "r"(user_esp), "r"(0x200), "i"(USER_CS), "r"(tmp_eip) :"eax", "memory" ); */ //} execute((uint8_t *) "shell"); while(1){ } /* Spin (nicely, so we don't chew up cycles) */ // uint8_t test_read_buffer[TEST_READ_BUFFER_SIZE]; //initialize buffer for testing terminal_read // uint8_t test_write_buffer[TEST_WRITE_BUFFER_SIZE] = "teststringforwritefunction\n"; //initialize buffer for testing terminal_write // while(1){ // memset(test_read_buffer, 0, TEST_READ_BUFFER_SIZE); // printf("Number of bytes read: %d\n", terminal_read(0, test_read_buffer, TEST_READ_BUFFER_SIZE-1)); //testing terminal_read // terminal_write(1, test_read_buffer, TEST_READ_BUFFER_SIZE); //testing terminal _write // terminal_write(1, test_write_buffer, TEST_WRITE_BUFFER_SIZE); // } asm volatile(".1: hlt; jmp .1;"); }
/* * _fill_idt_exceptions * DESCRIPTION: Fill in all the exception entries in the IDT. * INPUTS: none * OUTPUTS: none * RETURN VALUE: none * SIDE EFFECTS: Change contents in the IDT table. */ void _fill_idt_exceptions(){ idt_desc_t idt_temp; // uint32_t i; // Exception and interrupts use interrupt gate idt_temp.seg_selector = KERNEL_CS; idt_temp.size = 1; // Indicates 32 Bits idt_temp.dpl = 0x0; // Kernel level privilege. idt_temp.present = 1; // Mark as present idt_temp.reserved4 = 0; // Reserved. idt_temp.reserved3 = 0; idt_temp.reserved2 = 1; idt_temp.reserved1 = 1; idt_temp.reserved0 = 0; SET_IDT_ENTRY(idt_temp, &exception_0); idt[0] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_1); idt[1] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_2); idt[2] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_3); idt[3] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_4); idt[4] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_5); idt[5] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_6); idt[6] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_7); idt[7] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_8); idt[8] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_9); idt[9] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_10); idt[10] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_11); idt[11] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_12); idt[12] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_13); idt[13] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_14); idt[14] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_15); idt[15] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_16); idt[16] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_17); idt[17] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_18); idt[18] = idt_temp; SET_IDT_ENTRY(idt_temp, &exception_19); idt[19] = idt_temp; }
/* * create_exceptions * DESCRIPTION: Calls respective exception in handler.c. Loads exceptions in IDT by iterating through k values, where k is the interrupt vector number * INPUTS: none * OUTPUTS: Calls respective exception in handler.c * RETURN VALUE: none * SIDE EFFECTS: none */ void create_exceptions() { int k=0; //Divide By Zero { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_divide_by_zero); } k = 1; //Debugger { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_debugger); } k = 2; //NMI { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_nmi); } k = 3; //Breakpoint { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_breakpoint); } k = 4; //Overflow { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_overflow); } k = 5; //Bounds { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_bounds); } k = 6; //Invalid Opcode { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_invalid_opcode); } k = 7; //Coprocessor Not Available { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_coprocessor_not_available); } k = 8; //Double Fault { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_double_fault); } k = 9; //Coprocessor Segment Overrun { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_coprocessor_segment_overrun); } k = 10; //Invalid Task State Segment { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_invalid_task_state_segment); } k = 11; //Segment Not Present { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_segment_not_present); } k = 12; //Stack Fault { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_stack_fault); } k = 13; //General Protection Fault { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_general_protection_fault); } k = 14; //Page Fault { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_page_fault); } k = 15; //Reserved { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_reserved); } k = 16; //Math Fault { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_math_fault); } k = 17; //Alignment Check { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_alignment_check); } k = 18; //Machine Check { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_machine_check); } k = 19; //SIMD Floating Point { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_simd_floating_point); } k = 0x20; //PIT { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_pit_handler); } k =0x21 ; //Keyboard Vector { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_key_init); } k =0x28 ; //RTC { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_rtc_handler); } k =0x80 ; //Generic System Call { idt[k].present = 1; idt[k].dpl = 3; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_sys_call); } k =0x20+12 ; // mouse { idt[k].present = 1; idt[k].dpl = 0; idt[k].reserved0 = 0; idt[k].size = 1; idt[k].reserved1 = 1; idt[k].reserved2 = 1; idt[k].reserved3 = 1; idt[k].reserved4 = 0; idt[k].seg_selector = KERNEL_CS; SET_IDT_ENTRY(idt[k],a_mouse_handler); } }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry (unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; /* Clear the screen. */ clear(); /* Am I booted by a Multiboot-compliant boot loader? */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf ("Invalid magic number: 0x%#x\n", (unsigned) magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *) addr; /* Print out the flags. */ printf ("flags = 0x%#x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if (CHECK_FLAG (mbi->flags, 0)) printf ("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); /* Is boot_device valid? */ if (CHECK_FLAG (mbi->flags, 1)) printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device); /* Is the command line passed? */ if (CHECK_FLAG (mbi->flags, 2)) printf ("cmdline = %s\n", (char *) mbi->cmdline); if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i<16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; //mod++; } } /* Bits 4 and 5 are mutually exclusive! */ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) { printf ("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if (CHECK_FLAG (mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf ("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned) elf_sec->num, (unsigned) elf_sec->size, (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); } /* Are mmap_* valid? */ if (CHECK_FLAG (mbi->flags, 6)) { memory_map_t *mmap; printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); for (mmap = (memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size))) printf (" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned) mmap->size, (unsigned) mmap->base_addr_high, (unsigned) mmap->base_addr_low, (unsigned) mmap->type, (unsigned) mmap->length_high, (unsigned) mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000; ltr(KERNEL_TSS); } /* Setup Trap Entries */ idt_desc_t idt_entry; // setup idt_entry idt_entry.dpl = 0; idt_entry.present = 1; idt_entry.seg_selector =KERNEL_CS; idt_entry.reserved3 =1; //40 idt_entry.reserved2 =1; //41 idt_entry.reserved1 =1; //42 idt_entry.size =1; //43 idt_entry.reserved0 =0; //44 //0x00 SET_IDT_ENTRY(idt_entry, divide_by_zero); idt[0x00] = idt_entry; /* Setup System Call Entry */ /* idt_entry.dpl = 3; idt_entry.present = 1; idt_entry.seg_selector =KERNEL_CS; idt_entry.reserved3 =1; //40 idt_entry.reserved2 =1; //41 idt_entry.reserved1 =1; //42 idt_entry.size =1; //43 idt_entry.reserved0 =0; //44 */ /* Setup Interrupt Entries */ idt_entry.dpl = 0; idt_entry.present = 1; idt_entry.seg_selector =KERNEL_CS; idt_entry.reserved3 =0; //40 idt_entry.reserved2 =1; //41 idt_entry.reserved1 =1; //42 idt_entry.size =1; //43 idt_entry.reserved0 =0; //44 SET_IDT_ENTRY(idt_entry, divide_by_zero); idt[0x00] = idt_entry; SET_IDT_ENTRY(idt_entry, debugger_interrupt); idt[0x01] = idt_entry; SET_IDT_ENTRY(idt_entry, non_maskable_interrupt); idt[0x02] = idt_entry; SET_IDT_ENTRY(idt_entry, breakpoint_interrupt); idt[0x03] = idt_entry; SET_IDT_ENTRY(idt_entry, overflow_error); idt[0x04] = idt_entry; SET_IDT_ENTRY(idt_entry, out_of_bounds_error); idt[0x05] = idt_entry; SET_IDT_ENTRY(idt_entry, invalid_opcode_interrupt); idt[0x06] = idt_entry; SET_IDT_ENTRY(idt_entry, coprocessor_not_avaliable); idt[0x07] = idt_entry; SET_IDT_ENTRY(idt_entry, coprocessor_not_avaliable); idt[0x08] = idt_entry; SET_IDT_ENTRY(idt_entry, coprocessor_segment_overrun); idt[0x09] = idt_entry; SET_IDT_ENTRY(idt_entry, invalid_task_state_segment); idt[0x0A] = idt_entry; SET_IDT_ENTRY(idt_entry, segment_not_present); idt[0x0B] = idt_entry; SET_IDT_ENTRY(idt_entry, page_fault); idt[0x0C] = idt_entry; SET_IDT_ENTRY(idt_entry, general_protection_fault); idt[0x0D] = idt_entry; SET_IDT_ENTRY(idt_entry, page_fault); idt[0x0E] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x0F] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x10] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x11] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x12] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x13] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x14] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x15] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x16] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x17] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x18] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x19] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1A] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1B] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1C] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1D] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1E] = idt_entry; SET_IDT_ENTRY(idt_entry, reserved_error); idt[0x1F] = idt_entry; /*Interrupt Entries setup*/ clear(); printf("Testing if its even coming here"); SET_IDT_ENTRY(idt_entry, &_kb_wrapper); idt[0x21] = idt_entry; //clear(); /* Init the PIC */ cli(); i8259_init(); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ /* Enable interrupts */ /* Do not enable the following until after you have set up your * IDT correctly otherwise QEMU will triple fault and simple close * without showing you any output */ sti(); printf("Enabling Interrupts"); /* Execute the first program (`shell') ... */ while(1); /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }
void idt_initialize() { int i; idt_desc_t exception; exception.seg_selector = KERNEL_CS; exception.reserved4 = set_0; exception.reserved3 = set_0; exception.reserved2 = set_1; exception.reserved1 = set_1; exception.size = set_1; exception.reserved0 = set_0; exception.dpl = set_0; exception.present = set_1; idt_desc_t interrupt; interrupt = exception; //interrupt.reserved3 = set_1; idt_desc_t syscall; syscall = interrupt; syscall.dpl = set_3; syscall.reserved3 = set_1; for(i = 0; i < 32; i++) idt[i] = exception; for(i = 32; i < 41; i++) idt[i] = interrupt; idt[0x80] = syscall; SET_IDT_ENTRY(idt[0], ÷_by_zero_linkage); SET_IDT_ENTRY(idt[1], &debug_linkage); SET_IDT_ENTRY(idt[2], &nmi_linkage); SET_IDT_ENTRY(idt[3], &breakpoint_linkage); SET_IDT_ENTRY(idt[4], &overflow_linkage); SET_IDT_ENTRY(idt[5], &bound_range_linkage); SET_IDT_ENTRY(idt[6], &invalid_op_linkage); SET_IDT_ENTRY(idt[7], &device_na_linkage); SET_IDT_ENTRY(idt[8], &double_fault_linkage); SET_IDT_ENTRY(idt[9], &coprocessor_seg_overrun_linkage); SET_IDT_ENTRY(idt[10], &invalid_tss_linkage); SET_IDT_ENTRY(idt[11], &seg_not_present_linkage); SET_IDT_ENTRY(idt[12], &stack_seg_fault_linkage); SET_IDT_ENTRY(idt[13], &general_protection_linkage); SET_IDT_ENTRY(idt[14], &page_fault_linkage); SET_IDT_ENTRY(idt[15], &reserved_linkage); SET_IDT_ENTRY(idt[16], &math_fault_linkage); SET_IDT_ENTRY(idt[17], &alignment_check_linkage); SET_IDT_ENTRY(idt[18], &machine_check_linkage); SET_IDT_ENTRY(idt[19], &floating_point_linkage); // we add 32 to the IRQ number because of the offset SET_IDT_ENTRY(idt[32], &irq0_wrapper); // add PIT irq (IRQ0+32 = 32) SET_IDT_ENTRY(idt[33], &irq1_wrapper); // add keyboard irq (IRQ1+32 = 33) SET_IDT_ENTRY(idt[40], &irq8_wrapper); // add rtc irq (IRQ8+32 = 40) // add system call handler SET_IDT_ENTRY(idt[0x80], &syscall_wrapper); lidt(idt_desc_ptr); }