void idt_init(void) { extern struct Segdesc gdt[]; // 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; // Love to put this code in the initialization of gdt, // but the compiler generates an error incorrectly. gdt[GD_TSS >> 3] = SEG16(STS_T32A, (u_long) (&ts), sizeof(struct Taskstate), 0); gdt[GD_TSS >> 3].sd_s = 0; printf("????????????????????????\n"); // Load the TSS ltr(GD_TSS); idt[0x0] = GATE(STS_IG32, GD_KT, (int)&myint0, 3); idt[0xE] = GATE(STS_IG32, GD_KT, (int)&myint14, 3); idt[0x30] = GATE(STS_IG32, GD_KT, (int)&myint30, 3); printf("????????????????????????%x\n", idt[0x30]); // Load the IDT asm volatile("lidt idt_pd+2"); }
/* * 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 idt_init(void) { extern struct Segdesc gdt[]; // LAB 3: Your code here. assert(sizeof(struct Gatedesc) == SZ_GATEDESC); assert(sizeof(struct Pseudodesc) == SZ_PSEUDODESC); assert(sizeof(struct Trapframe) == SIZEOF_STRUCT_TRAPFRAME); clog("idt_pd = %u, %p", idt_pd.pd_lim, idt_pd.pd_base); //print_idt(idt); setup_idt(); //print_idt(idt); // 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 field of the gdt. gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (&ts), sizeof(struct Taskstate), 0); gdt[GD_TSS >> 3].sd_s = 0; // Load the TSS ltr(GD_TSS); // Load the IDT asm volatile("lidt idt_pd"); }
void idt_init(void) { extern struct Segdesc gdt[]; // LAB 2: Your code here. //extern char* t_brkpt_lbl; extern char t_brkpt_lbl[]; SETGATE(idt[3], 0, GD_KT, t_brkpt_lbl, 3); // Hint: Must this gate be accessible from userlevel? // LAB 3: Your code here. // 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 field of the gdt. gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (&ts), sizeof(struct Taskstate), 0); gdt[GD_TSS >> 3].sd_s = 0; // Load the TSS ltr(GD_TSS); // Load the IDT asm volatile("lidt idt_pd"); }
// Set up CPU's segment descriptors and task state for a given process. // If p==0, set up for "idle" state for when scheduler() is running. void setupsegs(struct proc *p) { struct cpu *c; pushcli(); c = &cpus[cpu()]; c->ts.ss0 = SEG_KDATA << 3; if(p) c->ts.esp0 = (uint)(p->kstack + KSTACKSIZE); else c->ts.esp0 = 0xffffffff; c->gdt[0] = SEG_NULL; c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); c->gdt[SEG_TSS].s = 0; if(p){ c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)p->mem, p->sz-1, DPL_USER); c->gdt[SEG_UDATA] = SEG(STA_W, (uint)p->mem, p->sz-1, DPL_USER); } else { c->gdt[SEG_UCODE] = SEG_NULL; c->gdt[SEG_UDATA] = SEG_NULL; } lgdt(c->gdt, sizeof(c->gdt)); ltr(SEG_TSS << 3); popcli(); }
/* * Set up proc0's TSS and LDT. */ void x86_64_proc0_tss_ldt_init(void) { struct pcb *pcb; int x; gdt_init(); cpu_info_primary.ci_curpcb = pcb = &proc0.p_addr->u_pcb; pcb->pcb_flags = 0; pcb->pcb_tss.tss_iobase = (u_int16_t)((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss); for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++) pcb->pcb_iomap[x] = 0xffffffff; pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSYSSEL(GLDT_SEL, SEL_KPL); pcb->pcb_cr0 = rcr0(); pcb->pcb_tss.tss_rsp0 = (u_int64_t)proc0.p_addr + USPACE - 16; pcb->pcb_tss.tss_ist[0] = (u_int64_t)proc0.p_addr + PAGE_SIZE; proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_rsp0 - 1; proc0.p_md.md_tss_sel = tss_alloc(pcb); ltr(proc0.p_md.md_tss_sel); lldt(pcb->pcb_ldt_sel); }
// 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); */ }
/* * Load appropriate gdt descriptor; we better be running on *ci * (for the most part, this is how a cpu knows who it is). */ void gdt_init_cpu(struct cpu_info *ci) { struct region_descriptor region; set_sys_segment(GDT_ADDR_SYS(ci->ci_gdt, GPROC0_SEL), ci->ci_tss, sizeof (struct x86_64_tss)-1, SDT_SYS386TSS, SEL_KPL, 0); setregion(®ion, ci->ci_gdt, GDT_SIZE - 1); lgdt(®ion); ltr(GSYSSEL(GPROC0_SEL, SEL_KPL)); }
// Switch TSS and h/w page table to correspond to process p. void switchuvm(struct proc *p) { pushcli(); cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0); cpu->gdt[SEG_TSS].s = 0; cpu->ts.ss0 = SEG_KDATA << 3; cpu->ts.esp0 = (uint) proc->kstack + KSTACKSIZE; ltr(SEG_TSS << 3); if (p->pgdir == 0) panic("switchuvm: no pgdir"); lcr3(v2p(p->pgdir)); // switch to new address space popcli(); }
// Set up CPU's segment descriptors and current process task state. void usegment(void) { pushcli(); cpu->gdt[SEG_UCODE] = SEG(STA_X|STA_R, proc->mem, proc->sz-1, DPL_USER); cpu->gdt[SEG_UDATA] = SEG(STA_W, proc->mem, proc->sz-1, DPL_USER); cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0); cpu->gdt[SEG_TSS].s = 0; cpu->ts.ss0 = SEG_KDATA << 3; cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE; ltr(SEG_TSS << 3); popcli(); }
static void createAndAppendTextDirectionSubMenu(const HitTestResult& result, ContextMenuItem& textDirectionMenuItem) { ContextMenu textDirectionMenu(result); ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection()); ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight()); ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft()); textDirectionMenu.appendItem(defaultItem); textDirectionMenu.appendItem(ltr); textDirectionMenu.appendItem(rtl); textDirectionMenuItem.setSubMenu(&textDirectionMenu); }
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); }
/* gdt_init - initialize the default GDT and TSS */ static void gdt_init(void) { // set boot kernel stack and default SS0 load_rsp0((uintptr_t) bootstacktop); ts.ts_ss0 = KERNEL_DS; // initialize the TSS filed of the gdt gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t) & ts, sizeof(ts), DPL_KERNEL); // reload all segment registers lgdt(&gdt_pd); // load the TSS ltr(GD_TSS); }
// 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); }
void idt_init(void) { extern struct Segdesc gdt[]; // LAB 3: Your code here. SETGATE(idt[T_DIVIDE], 0, GD_KT, divide_error, 0); SETGATE(idt[T_DEBUG], 0, GD_KT, debug, 0); SETGATE(idt[T_NMI], 0, GD_KT, nmi, 0); SETGATE(idt[T_BRKPT], 0, GD_KT, break_point, 3); SETGATE(idt[T_OFLOW], 0, GD_KT, overflow, 0); SETGATE(idt[T_BOUND], 0, GD_KT, bounds, 0); SETGATE(idt[T_ILLOP], 0, GD_KT, invalid_op, 0); SETGATE(idt[T_DEVICE], 0, GD_KT, device_not_available, 0); SETGATE(idt[T_DBLFLT], 0, GD_KT, double_fault, 0); SETGATE(idt[T_TSS], 0, GD_KT, invalid_TSS, 0); SETGATE(idt[T_SEGNP], 0, GD_KT, segment_not_present, 0); SETGATE(idt[T_STACK], 0, GD_KT, stack_segment, 0); SETGATE(idt[T_GPFLT], 0, GD_KT, general_protection, 0); SETGATE(idt[T_PGFLT], 0, GD_KT, page_fault, 0); SETGATE(idt[T_FPERR], 0, GD_KT, float_point_error, 0); SETGATE(idt[T_ALIGN], 0, GD_KT, alignment_check, 0); SETGATE(idt[T_MCHK], 0, GD_KT, machine_check, 0); SETGATE(idt[T_SIMDERR], 0, GD_KT, SIMD_float_point_error, 0); SETGATE(idt[IRQ_OFFSET + IRQ_TIMER], 0, GD_KT, timer, 0); SETGATE(idt[T_SYSCALL], 0, GD_KT, system_call, 3); // 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 field of the gdt. gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (&ts), sizeof(struct Taskstate), 0); gdt[GD_TSS >> 3].sd_s = 0; // Load the TSS ltr(GD_TSS); // Load the IDT asm volatile("lidt idt_pd"); }
inline int fast_send_m (task_id dst_id, u32 arg1, u32 arg2) { quest_tss *src = lookup_TSS (str ()); quest_tss *dst = lookup_TSS (dst_id); semaphore_wait (&dst->Msem, 1, -1); wakeup (str ()); dst->M[0] = arg1; dst->M[1] = arg2; ltr (dst_id); asm volatile ("call _sw_ipc" : :"S" (src), "D" (dst) :"eax", "ebx", "ecx", "edx"); return 0; }
// 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); }
// Sets up virtual memory for process p void switchuvm(Proc *p) { TaskStateDescriptor *d; pushcli(); d = (TaskStateDescriptor *)&cpu->gdt[SEG_TSS]; tsdesc(d, &cpu->ts, sizeof(cpu->ts)); cpu->ts.rsp0 = (ulong)p->kstack + KSTACKSIZE; cpu->ts.iomapbase = 0xFFFF; // disable in/out in user space ltr(SEG_TSS << 3); if (p->pgmap == nil) panic("switchuvm - no pgmap"); lcr3(v2p(p->pgmap)); popcli(); }
inline int fast_sendrecv_m (task_id dst_id, u32 arg1, u32 arg2, u32 *r_arg1, u32 *r_arg2) { quest_tss *src = lookup_TSS (str ()); quest_tss *dst = lookup_TSS (dst_id); semaphore_wait (&dst->Msem, 1, -1); dst->M[0] = arg1; dst->M[1] = arg2; semaphore_signal (&src->Msem, 1); ltr (dst_id); asm volatile ("call _sw_ipc" :"+S" (src), "+D" (dst) : :"eax", "ebx", "ecx", "edx", "cc", "memory"); /* after _sw_ipc dst and src are swapped */ *r_arg1 = dst->M[0]; *r_arg2 = dst->M[1]; return 0; }
// 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); }
// 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); }
/* Si no existe la TSS, crea una y la configura con los valores para el * segmento y offset del stack de nivel 0, carga un descriptor para ella en la * GDT y carga el Task Register con un selector que la referencia. * * Si ya existe, simplemente actualiza el valor del offset del stack de nivel * 0. * * - ``kernel_stack`` es la direccion del stack pointer para el stack de nivel * 0 de la tarea en su espacio de direcciones */ void setup_tss(uint32_t kernel_stack) { if (tss) { tss->esp0 = kernel_stack; return; } tss = (tss_t *)kmalloc(sizeof(tss_t)); memset(tss, 0, sizeof(tss_t)); // Solo nos interesa el segmento de stack para el kernel tss->ss0 = GDT_SEGSEL(0x0, GDT_INDEX_KERNEL_DS); tss->esp0 = kernel_stack; // Escribimos el descriptor de la TSS en la GDT gdt[GDT_INDEX_TSS] = GDT_DESC_BASE((uint32_t)tss) | GDT_DESC_LIMIT(sizeof(tss_t)) | GDT_DESC_DPL(0x0) | GDT_DESC_TYPE(GDT_F_32BTA) | GDT_DESC_G | GDT_DESC_P; // Cargamos el Task Register con un selector para la TSS uint16_t segsel = GDT_SEGSEL(0x0, GDT_INDEX_TSS); ltr(segsel); }
virtual void setup_analog_in() { CloseADC10(); // ERROR: Only open 2 channels? SetChanADC10(ADC_CH0_NEG_SAMPLEA_NVREF|ADC_CH0_POS_SAMPLEA_AN0); PORTSetPinsAnalogIn(ltr(), num()); enabled_ADCs |= (typeof(enabled_ADCs)) (1 << bit); // PIC32 SPECIFIC uint32_t count_enabled = __builtin_popcount(enabled_ADCs); // 32bit cuz we bitshift below /* 1: Turn module on | ouput in integer | trigger mode auto | enable autosample * 2: ADC ref external | disable offset test | disable scan mode | perform 2 samples | use dual buffers | use alternate mode * 3: use ADC internal clock | set sample time * 4: enable all ANX not in use * 5: do not assign other channels to scan */ #define PARAM1 ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON #define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | (count_enabled << _AD1CON2_SMPI_POSITION) | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF // use Channel A only #define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15 #define PARAM4 ENABLE_AN0_ANA | ENABLE_AN1_ANA #define PARAM5 SKIP_SCAN_ALL OpenADC10( PARAM1, PARAM2, PARAM3, enabled_ADCs, ~enabled_ADCs ); // setup ADC EnableADC10(); }
} void sched_init(void) { /* 初始化进程控制块指针数组 */ /* nothing.在bss段,已被清零 */ proc[0] = &init_proc.proc; current = proc[0]; ticks = 0; /* 设置进程0的ldt和tss描述符 */ set_ldt_desc(0, V_KERNEL_ZONE_START+(unsigned long)&(proc[0]->ldt)); set_tss_desc(0, V_KERNEL_ZONE_START+(unsigned long)&(proc[0]->tss)); /* 装载进程0的ldt和tss选择符,第一次需我们来加载 */ lldt(_LDT(0)); ltr(_TSS(0)); /* 挂载时钟中断处理程序 */ set_idt(INT_R0, timer_int, NR_TIMER_INT); /* 设置8253定时器芯片 */ out_b(0x43, 0x36); out_b(0x40, (LATCH & 0xff)); out_b(0x40, ((LATCH>>8) & 0xff)); /* 挂载系统调用处理程序 */
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); void * zbigfs_location = NULL; 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++; } if (mod_count){ module_t* zbigfsmod = (module_t*)mbi->mods_addr; zbigfs_location = (void *) zbigfsmod->mod_start; } else { printf("No module 0, zbigfs will FAIL!"); } } /* 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; //8MB ltr(KERNEL_TSS); } //printf("Enabling Interrupts\n"); /* Init the PIC */ populate_idt(); i8259_init(); rtc_init(); outb(PIT_MODIFY_LOW | PIT_MODIFY_HIGH | PIT_MODE_2 ,PIT_CTRL_ADDR); outb(PIT_DEFAULT_RATE_LOW,PIT_PORT0_CTRL_ADDR); //set low byte outb(PIT_DEFAULT_RATE_HIGH,PIT_PORT0_CTRL_ADDR); //set high byte /* * pc speaker code from osdev * uint32_t Div; uint8_t tmp; //Set the PIT to the desired frequency Div = 1193180 / 1000; outb(0x43, 0xb6); outb(0x42, (uint8_t) (Div) ); outb(0x42, (uint8_t) (Div >> 8)); //And play the sound using the PC speaker tmp = inb(0x61); if (tmp != (tmp | 3)) { outb(0x61, tmp | 3); } */ disable_irq(0); /* 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 */ //Enable interrupts for the first time printf("Enabling Interrupts\n"); sti(); //Initialize paging and mount the filesysem init_paging(); printf("Mounting module 0 as read-only zbigfs filesystem\n"); zbigfs_mount(zbigfs_location); //Initialize PCBs and then clear the terminal so it looks nice init_pcbs(); term_clear(); /* 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(); 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; /* 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"); BOOT_BLOCK_PTR = (uint32_t *)mod->mod_start; 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); } /* disable all interrupts on PIC */ /* Init the PIC */ i8259_init(); init_idt(); int i; for(i = 0; i < 16; i++) { disable_irq(i); } /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */\ paging_init(); rtc_init(); init_fs(); enable_irq(PIC_1); terminal_open(0); clear(); /* 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(); //write(1, "abcdefghijklmnopqrstuvwxyz", 26); /* printf("testing terminal \n");*/ /* unsigned char buf[4000] = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n"; write(1, buf, 4000); */ /*unsigned char buf2[4000] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\n"; terminal_write(1, buf2, 4000); terminal_read(0, buf, 4000); terminal_write(1, buf, 4000); printf("done testing terminal \n"); //clear(); // Clears the screen before test_interrupts //int x = 1/0; */ // Tests for RTC /* for(i = 0; i < 1000000000; i++); rtc_read(); int j = 1024; rtc_write(&j,4); for(i = 0; i < 1000000000; i++); rtc_read(); */ /*testing open and read file*/ /*uint8_t filename[] = "verylargetxtwithverylongname.tx"; uint8_t buffer[3000]; int res; res = filesystem_open(filename); if(res == -1) terminal_write((const uint8_t *)"not able to open the file", 200); else { filesystem_read(0, buffer, 3000); terminal_write(buffer, 3000); }*/ /*testing read directory*/ //dirread(); /* Execute the first program (`shell') ... */ uint8_t filename[] = "shell"; execute(filename); /*execute(filename); execute(filename); execute(filename); execute(filename);*/ /* 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; 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;"); }
X86Kernel::X86Kernel() : Kernel(), ticks(0) { /* ICW1: Initialize PIC's (Edge triggered, Cascade) */ outb(PIC1_CMD, 0x11); outb(PIC2_CMD, 0x11); /* ICW2: Remap IRQ's to interrupts 32-47. */ outb(PIC1_DATA, PIC_IRQ_BASE); outb(PIC2_DATA, PIC_IRQ_BASE + 8); /* ICW3: PIC2 is connected to PIC1 via IRQ2. */ outb(PIC1_DATA, 0x04); outb(PIC2_DATA, 0x02); /* ICW4: 8086 mode, fully nested, not buffered, no implicit EOI. */ outb(PIC1_DATA, 0x01); outb(PIC2_DATA, 0x01); /* OCW1: Disable all IRQ's for now. */ outb(PIC1_DATA, 0xff); outb(PIC2_DATA, 0xff); /* Let the i8253 timer run continuously (square wave). */ outb(PIT_CMD, 0x36); outb(PIT_CHAN0, PIT_DIVISOR & 0xff); outb(PIT_CHAN0, PIT_DIVISOR >> 8); /* Make sure to enable PIC2 and the i8253. */ enableIRQ(2, true); enableIRQ(0, true); /* Setup exception handlers. */ for (int i = 0; i < 17; i++) { hookInterrupt(i, exception, 0); } /* Setup IRQ handlers. */ for (int i = 17; i < 256; i++) { /* Trap gate. */ if (i == 0x90) hookInterrupt(0x90, trap, 0); /* Hardware Interrupt. */ else hookInterrupt(i, interrupt, 0); } /* Install PIT (i8253) IRQ handler. */ hookInterrupt(IRQ(0), clocktick, 0); /* Initialize TSS Segment. */ gdt[USER_TSS].limitLow = sizeof(TSS) + (0xfff / 8); gdt[USER_TSS].baseLow = ((Address) &kernelTss) & 0xffff; gdt[USER_TSS].baseMid = (((Address) &kernelTss) >> 16) & 0xff; gdt[USER_TSS].type = 9; gdt[USER_TSS].privilege = 0; gdt[USER_TSS].present = 1; gdt[USER_TSS].limitHigh = 0; gdt[USER_TSS].granularity = 8; gdt[USER_TSS].baseHigh = (((Address) &kernelTss) >> 24) & 0xff; /* Let TSS point to I/O bitmap page. */ kernelTss.bitmap = PAGESIZE << 16; /* Load Task State Register. */ ltr(USER_TSS_SEL); }