void cpu_init_idt(void) { struct region_descriptor region; setregion(®ion, idt, NIDT * sizeof(idt[0]) - 1); lidt(®ion); }
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ void idt_init(void) { /* LAB1 YOUR CODE : STEP 2 */ /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)? * All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ? * __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c * (try "make" command in lab1, then you will find vector.S in kern/trap DIR) * You can use "extern uintptr_t __vectors[];" to define this extern variable which will be used later. * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT). * Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction. * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ extern uintptr_t __vectors[]; int i; int k; k=sizeof(idt)/sizeof(struct gatedesc); for (i = 0; i < k; i ++) { SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); } SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); lidt(&idt_pd); }
void InterruptUtils::initialise() { // allocate some memory for our handlers GateDesc *interrupt_gates = new GateDesc[NUM_INTERRUPT_HANDLERS]; for (uint32 i = 0; i < NUM_INTERRUPT_HANDLERS; ++i) { interrupt_gates[i].offset_low = LO_WORD(handlers[i].offset); interrupt_gates[i].offset_high = HI_WORD(handlers[i].offset); interrupt_gates[i].gate_size = GATE_SIZE_32_BIT; interrupt_gates[i].present = 1; interrupt_gates[i].reserved = 0; interrupt_gates[i].segment_selector = KERNEL_CS; interrupt_gates[i].type = TYPE_INTERRUPT_GATE; interrupt_gates[i].unused = 0; interrupt_gates[i].zeros = 0; interrupt_gates[i].dpl = (handlers[i].number == SYSCALL_INTERRUPT ? DPL_USER_SPACE : DPL_KERNEL_SPACE); } IDTR idtr; idtr.base = (uint32)interrupt_gates; idtr.limit = sizeof(GateDesc)*NUM_INTERRUPT_HANDLERS - 1; lidt(&idtr); }
void InterruptUtils::initialise() { uint32 num_handlers = 0; for (uint32 i = 0; handlers[i].offset != 0; ++i) num_handlers = handlers[i].number; ++num_handlers; // allocate some memory for our handlers GateDesc *interrupt_gates = new GateDesc[num_handlers]; uint32 j = 0; for (uint32 i = 0; i < num_handlers; ++i) { while (handlers[j].number < i && handlers[j].offset != 0) ++j; interrupt_gates[i].offset_low = LO_WORD((handlers[j].number == i && handlers[j].offset != 0) ? handlers[j].offset : arch_dummyHandler); interrupt_gates[i].offset_high = HI_WORD((handlers[j].number == i && handlers[j].offset != 0) ? handlers[j].offset : arch_dummyHandler); interrupt_gates[i].gate_size = GATE_SIZE_32_BIT; interrupt_gates[i].present = 1; interrupt_gates[i].reserved = 0; interrupt_gates[i].segment_selector = KERNEL_CS; interrupt_gates[i].type = TYPE_INTERRUPT_GATE; interrupt_gates[i].unused = 0; interrupt_gates[i].zeros = 0; interrupt_gates[i].dpl = ((i == SYSCALL_INTERRUPT && handlers[j].number == i) ? DPL_USER_SPACE : DPL_KERNEL_SPACE); } IDTR idtr; idtr.base = (uint32) interrupt_gates; idtr.limit = sizeof(GateDesc) * num_handlers - 1; lidt(&idtr); }
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ void idt_init(void) { /* LAB1 2011011384 : STEP 2 */ /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)? * All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ? * __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c * (try "make" command in lab1, then you will find vector.S in kern/trap DIR) * You can use "extern uintptr_t __vectors[];" to define this extern variable which will be used later. * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT). * Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction. * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ //the global descriptor table is loaded at bootasm.s //code seg is at 0x08 extern uintptr_t __vectors[]; int i; for(i = 0; i < 256; i++) { SETGATE(idt[i], 0, 0x08, __vectors[i], 0); } SETGATE(idt[T_SWITCH_TOU], 0, 0x08, __vectors[T_SWITCH_TOU], 3); SETGATE(idt[T_SWITCH_TOK], 0, 0x08, __vectors[T_SWITCH_TOK], 3); lidt(&idt_pd); }
/* * AP cpu's call this to sync up protected mode. * * WARNING! We must ensure that the cpu is sufficiently initialized to * be able to use to the FP for our optimized bzero/bcopy code before * we enter more mainstream C code. * * WARNING! %fs is not set up on entry. This routine sets up %fs. */ void init_secondary(void) { int gsel_tss; int x, myid = bootAP; u_int cr0; struct mdglobaldata *md; struct privatespace *ps; ps = &CPU_prvspace[myid]; gdt_segs[GPRIV_SEL].ssd_base = (int)ps; gdt_segs[GPROC0_SEL].ssd_base = (int) &ps->mdglobaldata.gd_common_tss; ps->mdglobaldata.mi.gd_prvspace = ps; for (x = 0; x < NGDT; x++) { ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); } r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; r_gdt.rd_base = (int) &gdt[myid * NGDT]; lgdt(&r_gdt); /* does magic intra-segment return */ lidt(&r_idt); lldt(_default_ldt); mdcpu->gd_currentldt = _default_ldt; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; md = mdcpu; /* loaded through %fs:0 (mdglobaldata.mi.gd_prvspace)*/ md->gd_common_tss.tss_esp0 = 0; /* not used until after switch */ md->gd_common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16; md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd; md->gd_common_tssd = *md->gd_tss_gdt; ltr(gsel_tss); /* * Set to a known state: * Set by mpboot.s: CR0_PG, CR0_PE * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM */ cr0 = rcr0(); cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); load_cr0(cr0); pmap_set_opt(); /* PSE/4MB pages, etc */ /* set up CPU registers and state */ cpu_setregs(); /* set up FPU state on the AP */ npxinit(__INITIAL_NPXCW__); /* set up SSE registers */ enable_sse(); }
void InterruptUtils::initialise() { uint32 num_handlers = 0; for (uint32 i = 0; handlers[i].offset != 0; ++i) num_handlers = handlers[i].number; ++num_handlers; // allocate some memory for our handlers GateDesc *interrupt_gates = new GateDesc[num_handlers]; size_t dummy_handler_sled_size = (((size_t) arch_dummyHandlerMiddle) - (size_t) arch_dummyHandler); assert((dummy_handler_sled_size % 128) == 0 && "cannot handle weird padding in the kernel binary"); dummy_handler_sled_size /= 128; uint32 j = 0; for (uint32 i = 0; i < num_handlers; ++i) { while (handlers[j].number < i && handlers[j].offset != 0) ++j; interrupt_gates[i].offset_low = LO_WORD((handlers[j].number == i && handlers[j].offset != 0) ? (size_t)handlers[j].offset : (((size_t)arch_dummyHandler)+i*dummy_handler_sled_size)); interrupt_gates[i].offset_high = HI_WORD((handlers[j].number == i && handlers[j].offset != 0) ? (size_t)handlers[j].offset : (((size_t)arch_dummyHandler)+i*dummy_handler_sled_size)); interrupt_gates[i].gate_size = GATE_SIZE_32_BIT; interrupt_gates[i].present = 1; interrupt_gates[i].reserved = 0; interrupt_gates[i].segment_selector = KERNEL_CS; interrupt_gates[i].type = TYPE_INTERRUPT_GATE; interrupt_gates[i].unused = 0; interrupt_gates[i].zeros = 0; interrupt_gates[i].dpl = ((i == SYSCALL_INTERRUPT && handlers[j].number == i) ? DPL_USER_SPACE : DPL_KERNEL_SPACE); } IDTR idtr; idtr.base = (uint32) interrupt_gates; idtr.limit = sizeof(GateDesc) * num_handlers - 1; lidt(&idtr); }
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ void idt_init(void) { /* LAB1 2011010312 : STEP 2 */ /* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)? * All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ? * __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c * (try "make" command in lab1, then you will find vector.S in kern/trap DIR) * You can use "extern uintptr_t __vectors[];" to define this extern variable which will be used later. * (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT). * Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT * (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction. * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ /* LAB5 2011010312 */ //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore //so you should setup the syscall interrupt gate in here extern uintptr_t __vectors[]; int i; for(i = 0; i < 256; i++) { SETGATE(idt[i], 0, KERNEL_CS, __vectors[i], DPL_KERNEL); } SETGATE(idt[T_SYSCALL], 1, KERNEL_CS, __vectors[T_SYSCALL], DPL_USER); lidt(&idt_pd); }
initevec() { int i; STATWORD ps; #ifdef __COM32__ puts_com32("initevec() begin"); #endif for (i=0; i<NID; ++i) set_evec(i, (int)defevec[i]); /* * "girmask" masks all (bus) interrupts with the default handler. * initially, all, then cleared as handlers are set via set_evec() */ girmask = 0xfffb; /* leave bit 2 enabled for IC cascade */ #ifdef __COM32__ puts_com32("initevec() set_evec() done\n"); #endif lidt(); #ifdef __COM32__ puts_com32("initevec() lidt() done\n"); #endif init8259(); #ifdef __COM32__ puts_com32("initevec() init8259() done\n"); #endif }
// Initialize and load the per-CPU TSS and IDT void trap_init_percpu(void) { // The example code here sets up the Task State Segment (TSS) and // the TSS descriptor for CPU 0. But it is incorrect if we are // running on other CPUs because each CPU has its own kernel stack. // Fix the code so that it works for all CPUs. // // Hints: // - The macro "thiscpu" always refers to the current CPU's // struct CpuInfo; // - The ID of the current CPU is given by cpunum() or // thiscpu->cpu_id; // - Use "thiscpu->cpu_ts" as the TSS for the current CPU, // rather than the global "ts" variable; // - Use gdt[(GD_TSS0 >> 3) + i] for CPU i's TSS descriptor; // - You mapped the per-CPU kernel stacks in mem_init_mp() // // ltr sets a 'busy' flag in the TSS selector, so if you // accidentally load the same TSS on more than one CPU, you'll // get a triple fault. If you set up an individual CPU's TSS // wrong, you may not get a fault until you try to return from // user space on that CPU. // // LAB 4: Your code here: //------------ Lab4 ---------------------------------------------------------------------------------------- int cpuid = thiscpu->cpu_id; thiscpu->cpu_ts.ts_esp0 = KSTACKTOP - cpuid * (KSTKGAP + KSTKSIZE); thiscpu->cpu_ts.ts_ss0 = GD_KD; gdt[(GD_TSS0 >> 3) + cpuid] = SEG16(STS_T32A, (uint32_t) (&(thiscpu->cpu_ts)), sizeof(struct Taskstate), 0); gdt[(GD_TSS0 >> 3) + cpuid].sd_s = 0; ltr(GD_TSS0 + (cpuid << 3)); lidt(&idt_pd); //------------ Lab4 ---------------------------------------------------------------------------------------- /* // Setup a TSS so that we get the right stack // when we trap to the kernel. ts.ts_esp0 = KSTACKTOP; ts.ts_ss0 = GD_KD; // Initialize the TSS slot of the gdt. gdt[GD_TSS0 >> 3] = SEG16(STS_T32A, (uint32_t) (&ts), sizeof(struct Taskstate), 0); gdt[GD_TSS0 >> 3].sd_s = 0; // Load the TSS selector (like other segment selectors, the // bottom three bits are special; we leave them 0) ltr(GD_TSS0); // Load the IDT lidt(&idt_pd); */ }
static void cpu_reset_real() { struct region_descriptor null_idt; int b; disable_intr(); /* * Attempt to do a CPU reset via the keyboard controller, * do not turn off GateA20, as any machine that fails * to do the reset here would then end up in no man's land. */ outb(IO_KBD + 4, 0xFE); DELAY(500000); /* wait 0.5 sec to see if that did it */ /* * Attempt to force a reset via the Reset Control register at * I/O port 0xcf9. Bit 2 forces a system reset when it * transitions from 0 to 1. Bit 1 selects the type of reset * to attempt: 0 selects a "soft" reset, and 1 selects a * "hard" reset. We try a "hard" reset. The first write sets * bit 1 to select a "hard" reset and clears bit 2. The * second write forces a 0 -> 1 transition in bit 2 to trigger * a reset. */ outb(0xcf9, 0x2); outb(0xcf9, 0x6); DELAY(500000); /* wait 0.5 sec to see if that did it */ /* * Attempt to force a reset via the Fast A20 and Init register * at I/O port 0x92. Bit 1 serves as an alternate A20 gate. * Bit 0 asserts INIT# when set to 1. We are careful to only * preserve bit 1 while setting bit 0. We also must clear bit * 0 before setting it if it isn't already clear. */ b = inb(0x92); if (b != 0xff) { if ((b & 0x1) != 0) outb(0x92, b & 0xfe); outb(0x92, b | 0x1); DELAY(500000); /* wait 0.5 sec to see if that did it */ } printf("No known reset method worked, attempting CPU shutdown\n"); DELAY(1000000); /* wait 1 sec for printf to complete */ /* Wipe the IDT. */ null_idt.rd_limit = 0; null_idt.rd_base = 0; lidt(&null_idt); /* "good night, sweet prince .... <THUNK!>" */ breakpoint(); /* NOTREACHED */ while(1); }
void load_idtr() { idtr.limit = 256*(sizeof(IDT_t)-1); idtr.base = idt; // load IDTR with lidt lidt(&idtr); }
void idt_init(void) { extern uintptr_t __vectors[]; int i; for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { SETGATE(idt[i], 1, GD_KTEXT, __vectors[i], DPL_KERNEL); } SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER); lidt(&idt_pd); }
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ void idt_init(void) { extern uintptr_t __vectors[]; int i; for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); } // load the IDT lidt(&idt_pd); }
/* * 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); }
void initevec(void) { int i; /* bzero( idt, sizeof( struct idt ) * 256 ); */ memset( idt, 0, sizeof( struct idt ) * 256 ); for (i=0; i<NID; ++i) set_evec(i, (long)defevec[i]); lidt(); init8259(); set_exception=&set_evec; }
/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ void idt_init(void) { extern uintptr_t __vectors[]; int i; for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); } // set for switch from user to kernel SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); // load the IDT lidt(&idt_pd); }
void trap_init_percpu() { extern struct seg_descriptor gdt[CPUNUMS + 5]; extern int ncpu; uint32_t cid = get_cpuid(); struct taskstate *pts = &(thiscpu->cpu_ts); //pts->ts_esp0 = KERNEL_STACKTOP - (KERNEL_STKSIZE + KERNEL_STKGAP) * cid; pts->ts_esp0 = KERN_STACKTOP; pts->ts_ss0 = _KERNEL_DS_; gdt[(_TSS0_ >> 3) + cid] = set_seg(STS_T32A, (uint32_t) (pts), sizeof(struct taskstate), 0); gdt[(_TSS0_ >> 3) + cid].s = 0; ltr(_TSS0_ + cid * sizeof(struct seg_descriptor)); lidt(&idt_pd); }
int initevec() { int i; for (i=0; i<NID; ++i) set_evec(i, (long)defevec[i]); /* * "girmask" masks all (bus) interrupts with the default handler. * initially, all, then cleared as handlers are set via set_evec() */ girmask = 0xfffb; /* leave bit 2 enabled for IC cascade */ lidt(); init8259(); return(OK); }
// Initialize and load the per-CPU TSS and IDT void trap_init_percpu(void) { // Setup a TSS so that we get the right stack // when we trap to the kernel. ts.ts_esp0 = KSTACKTOP; // Initialize the TSS slot of the gdt. SETTSS((struct SystemSegdesc64 *)((gdt_pd>>16)+40),STS_T64A, (uint64_t) (&ts),sizeof(struct Taskstate), 0); // Load the TSS selector (like other segment selectors, the // bottom three bits are special; we leave them 0) ltr(GD_TSS0); // Load the IDT lidt(&idt_pd); }
/** Reboot the system. */ void platform_reboot(void) { uint8_t val; /* Try the keyboard controller. */ do { val = in8(0x64); if(val & (1<<0)) { in8(0x60); } } while(val & (1<<1)); out8(0x64, 0xfe); spin(5000); /* Fall back on a triple fault. */ lidt(0, 0); __asm__ volatile("ud2"); }
// Initialize and load the per-CPU TSS and IDT void trap_init_percpu(void) { // The example code here sets up the Task State Segment (TSS) and // the TSS descriptor for CPU 0. But it is incorrect if we are // running on other CPUs because each CPU has its own kernel stack. // Fix the code so that it works for all CPUs. // // Hints: // - The macro "thiscpu" always refers to the current CPU's // struct CpuInfo; // - The ID of the current CPU is given by cpunum() or // thiscpu->cpu_id; // - Use "thiscpu->cpu_ts" as the TSS for the current CPU, // rather than the global "ts" variable; // - Use gdt[(GD_TSS0 >> 3) + 2*i] for CPU i's TSS descriptor; // - You mapped the per-CPU kernel stacks in mem_init_mp() // // ltr sets a 'busy' flag in the TSS selector, so if you // accidentally load the same TSS on more than one CPU, you'll // get a triple fault. If you set up an individual CPU's TSS // wrong, you may not get a fault until you try to return from // user space on that CPU. // // LAB 4: Your code here: // Setup a TSS so that we get the right stack // when we trap to the kernel. int id = thiscpu->cpu_id; size_t kstacktop_ncpus = KSTACKTOP - id*(KSTKSIZE+KSTKGAP); thiscpu->cpu_ts.ts_esp0 = kstacktop_ncpus; SETTSS((struct SystemSegdesc64 *)(&gdt[(GD_TSS0>>3)+2*id]),STS_T64A, (uint64_t) (&thiscpu->cpu_ts),sizeof(struct Taskstate), 0); /* ts.ts_esp0 = KSTACKTOP; // Initialize the TSS slot of the gdt. SETTSS((struct SystemSegdesc64 *)((gdt_pd>>16)+40),STS_T64A, (uint64_t) (&ts),sizeof(struct Taskstate), 0); // Load the TSS selector (like other segment selectors, the // bottom three bits are special; we leave them 0) */ ltr(GD_TSS0 + ((2*id << 3) & (~0x7))); //ltr(GD_TSS0+2*id); // Load the IDT lidt(&idt_pd); }
// Initialize and load the per-CPU TSS and IDT void trap_init_percpu(void) { // Setup a TSS so that we get the right stack // when we trap to the kernel. ts.ts_esp0 = KSTACKTOP; ts.ts_ss0 = GD_KD; // Initialize the TSS slot of the gdt. gdt[GD_TSS0 >> 3] = SEG16(STS_T32A, (uint32_t) (&ts), sizeof(struct Taskstate) - 1, 0); gdt[GD_TSS0 >> 3].sd_s = 0; // Load the TSS selector (like other segment selectors, the // bottom three bits are special; we leave them 0) ltr(GD_TSS0); // Load the IDT lidt(&idt_pd); }
int setup_idt (void) { uint_t i; ulong_t irq_start = (ulong_t)&early_irq_handlers; ulong_t excp_start = (ulong_t)&early_excp_handlers; // clear the IDT out memset(&idt64, 0, sizeof(struct gate_desc64) * NUM_IDT_ENTRIES); for (i = 0; i < NUM_EXCEPTIONS; i++) { set_intr_gate(idt64, i, (void*)(excp_start + i*16)); idt_assign_entry(i, (ulong_t)null_excp_handler); } for (i = 32; i < NUM_IDT_ENTRIES; i++) { set_intr_gate(idt64, i, (void*)(irq_start + (i-32)*16)); idt_assign_entry(i, (ulong_t)null_irq_handler); } if (idt_assign_entry(PF_EXCP, (ulong_t)nk_pf_handler) < 0) { ERROR_PRINT("Couldn't assign page fault handler\n"); return -1; } if (idt_assign_entry(DF_EXCP, (ulong_t)df_handler) < 0) { ERROR_PRINT("Couldn't assign double fault handler\n"); return -1; } if (idt_assign_entry(0xf, (ulong_t)pic_spur_int_handler) < 0) { ERROR_PRINT("Couldn't assign PIC spur int handler\n"); return -1; } lidt(&idt_descriptor); return 0; }
void i86_idt_init(void) { memset(IDT32, 0, IDT32_NB_DESCRIPTORS * sizeof(idt_descriptor_t)); // all interrupts are initialized as interrupt gates and only can be executed // with ring 0's priviledges. idt_descriptor_flags_t flags; memset(&flags, 0, sizeof(idt_descriptor_flags_t)); flags.gate_type = IDT_DESC_TYPE_32BIT_INTERRUPT_GATE; flags.privilege_level = IDT_DESC_PRIVILEGE_RING_0; flags.present = IDT_DESC_PRESENT_IN_MEMORY; for (uint16_t i=0; i<IDT32_NB_DESCRIPTORS; ++i) { if (IDT32_PIC1_INT_VECT_OFFSET <= i && i < IDT32_PIC1_INT_VECT_OFFSET + PIC1INTNBR) { idt_desc_init(ISR32_SEG, _asm_default_pic1_int, flags, &IDT32[i]); } else if (IDT32_PIC1_INT_VECT_OFFSET <= i && i < IDT32_PIC1_INT_VECT_OFFSET + PIC1INTNBR) { idt_desc_init(ISR32_SEG, _asm_default_pic2_int, flags, &IDT32[i]); } else { idt_desc_init(ISR32_SEG, _asm_default_int, flags, &IDT32[i]); } } cntxt_p_mode_32bit.ptr_idt.base = (uint32_t) &IDT32; cntxt_p_mode_32bit.ptr_idt.limit = sizeof(idt_descriptor_t) * IDT32_NB_DESCRIPTORS; // load the 32-bit IDT's pointer lidt(&cntxt_p_mode_32bit.ptr_idt); #ifdef DEBUG_IDT debug_printf("IDT: ridt=%#08x, base=%#08x, limit=%#x\r\n", &cntxt_p_mode_32bit.ptr_idt, cntxt_p_mode_32bit.ptr_idt.base, cntxt_p_mode_32bit.ptr_idt.limit); #endif }
// Initialize and load the per-CPU TSS and IDT void trap_init_percpu(void) { // The example code here sets up the Task State Segment (TSS) and // the TSS descriptor for CPU 0. But it is incorrect if we are // running on other CPUs because each CPU has its own kernel stack. // Fix the code so that it works for all CPUs. // // Hints: // - The macro "thiscpu" always refers to the current CPU's // struct Cpu; // - The ID of the current CPU is given by cpunum() or // thiscpu->cpu_id; // - Use "thiscpu->cpu_ts" as the TSS for the current CPU, // rather than the global "ts" variable; // - Use gdt[(GD_TSS0 >> 3) + 2*i] for CPU i's TSS descriptor; // - You mapped the per-CPU kernel stacks in mem_init_mp() // // ltr sets a 'busy' flag in the TSS selector, so if you // accidentally load the same TSS on more than one CPU, you'll // get a triple fault. If you set up an individual CPU's TSS // wrong, you may not get a fault until you try to return from // user space on that CPU. // // Ashish thiscpu->cpu_ts.ts_esp0 = KSTACKTOP - thiscpu->cpu_id * (KSTKSIZE + KSTKGAP); SETTSS((struct SystemSegdesc64 *)(&(gdt[(GD_TSS0 >> 3)+thiscpu->cpu_id * 2])), // We want the TSS0 at 0x28, TSS1 at 0x38, TSS2 at 0x48, etc // The size of gdt is 2*NCPU+5 because - 2bytes for tss of each cpu // Initialize the TSS slot of the gdt. STS_T64A, (uint64_t) (&(thiscpu->cpu_ts)), sizeof(struct Taskstate), 0); // Load the TSS selector (like other segment selectors, the // bottom three bits are special; we leave them 0) ltr(GD_TSS0+(thiscpu->cpu_id * 8 * 2)); // Byte offset of TSSs // Load the IDT lidt(&idt_pd); }
void idtinit(void) { lidt(idt, sizeof(idt)); }
/* 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) { multiboot_info_t *mbi; /* Clear the screen. */ clear(); uint32_t filestart; /* 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); filestart = 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); } //Initialization of IDE { printf("Initilization of Idt table..."); set_trap_gate(0,divide_error); set_trap_gate(1,debug); set_intr_gate(2,nmi); set_system_intr_gate(3,int3); set_system_gate(4,overflow); set_system_gate(5,bounds); set_trap_gate(6,invalid_op); set_trap_gate(7,device_not_available); set_task_gate(8,31); set_trap_gate(9,coprocessor_segment_overrun); set_trap_gate(10,invalid_TSS); set_trap_gate(11,segment_not_present); set_trap_gate(12,stack_segment); set_trap_gate(13,general_protection); set_trap_gate(14,page_fault);//intr set_trap_gate(16,coprocessor_error); set_trap_gate(17,alignment_check); set_trap_gate(18,machine_check); set_trap_gate(19,simd_coprocessor_error); set_system_gate(128,system_call); set_intr_gate(32,irq0); //intr set_intr_gate(33,irq1); //intr set_intr_gate(34,0); //intr set_intr_gate(40,irq8); //intr //set_intr_gate(44,irq12); //intr lidt(idt_desc_ptr); printf("ok!\n"); } // Init the PIC i8259_init(); //Enable interrupts enable_irq(1); enable_irq(2); open_rtc(); enable_irq(8); enable_irq(12); uint8_t file =0x00; //Enable paging printf("Enabling paging...\n"); paging(); printf("ok!\n"); //Restore interrupts sti(); //Mounting file system printf("Mounting filesystem...\n"); open_terminal(&file); setstart(filestart); printf("ok!\n"); //clear(); //Executing first program shell uint8_t cmd[10]={"shell "}; #if debug_by_showing_dentries test_dentries(); while(1); #endif test_system_call((int32_t)cmd, NULL, 0, 2); 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) { multiboot_info_t *mbi; uint8_t* filesystem_address; /* 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) { filesystem_address = (uint8_t*)mod->mod_start; 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); } int z = 0; reset_scr(); //set the IDT set_idt(); lidt(idt_desc_ptr); /* Init the PIC */ i8259_init(); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ //init paging init_paging(); //init filesystem init_filesys(filesystem_address); //init keyboard init_keyboard(); //init the rtc init_rtc(); //init the mouse init_mouse(); //clear the screen reset_scr(); // boot_screen(); for(z = 0; z < 3; z++) { terminal_init(); } node* buffer = screens[0]; reset_buf(buffer); //display the status bar /* Enable interrupts */ sti(); /* 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 */ boot_screen(); //sample mario sound for(z = 0; z < 500000; z++) play_sound(1000); for(z = 0; z < 500000; z++) play_sound(100); for(z = 0; z < 500000; z++) play_sound(900); for(z = 0; z < 50000; z++) play_sound(200); for(z = 0; z < 500000; z++) play_sound(800); for(z = 0; z < 500000; z++) play_sound(300); for(z = 0; z < 500000; z++) play_sound(700); for(z = 0; z < 500000; z++) play_sound(400); for(z = 0; z < 500000; z++) play_sound(600); for(z = 0; z < 500000; z++) play_sound(500); for(z = 0; z < 500000; z++) play_sound(500); for(z = 0; z < 500000; z++) play_sound(1000); for(z = 0; z < 500000; z++) play_sound(400); for(z = 0; z < 500000; z++) play_sound(300); for(z = 0; z < 500000; z++) play_sound(300); for(z = 0; z < 500000; z++) play_sound(200); //boot_screen(); nosound(); reset_scr(); //init PIT for sound, timer init_pit(0, 100); ///////////////////////////////////////////////////////////// // void imperial(); status_bar(); /* Execute the first program (`shell') ... */ uint8_t fname[33] = "shell"; execute(fname); /* We should never get to this point */ //printf("Initial shell halted."); /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }