PRIVATE void estimate_cpu_freq(void) { u64_t tsc_delta; u64_t cpu_freq; irq_hook_t calib_cpu; /* set the probe, we use the legacy timer, IRQ 0 */ put_irq_handler(&calib_cpu, CLOCK_IRQ, calib_cpu_handler); /* just in case we are in an SMP single cpu fallback mode */ BKL_UNLOCK(); /* set the PIC timer to get some time */ intr_enable(); /* loop for some time to get a sample */ while(probe_ticks < PROBE_TICKS) { intr_enable(); } intr_disable(); /* just in case we are in an SMP single cpu fallback mode */ BKL_LOCK(); /* remove the probe */ rm_irq_handler(&calib_cpu); tsc_delta = sub64(tsc1, tsc0); cpu_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0)); cpu_set_freq(cpuid, cpu_freq); cpu_info[cpuid].freq = div64u(cpu_freq, 1000000); BOOT_VERBOSE(cpu_print_freq(cpuid)); }
/*======================================================================* init_keyboard *======================================================================*/ PUBLIC void init_keyboard() { kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; put_irq_handler(KEYBOARD_IRQ, keyboard_handler); /* 设定键盘中断处理程序 */ enable_irq(KEYBOARD_IRQ); /* 开键盘中断 */ }
PUBLIC void init_clock() { out_byte(TIMER_MODE, RATE_GENERATOR); out_byte(TIMER0, (TIMER_FREQ / HZ)); out_byte(TIMER0, ((TIMER_FREQ / HZ) >> 8)); put_irq_handler(CLOCK_IRQ, clock_handler); enable_irq(CLOCK_IRQ); }
int omap3_register_timer_handler(const irq_handler_t handler) { /* Initialize the CLOCK's interrupt hook. */ omap3_timer_hook.proc_nr_e = NONE; omap3_timer_hook.irq = OMAP3_GPT1_IRQ; put_irq_handler(&omap3_timer_hook, OMAP3_GPT1_IRQ, handler); return 0; }
/*======================================================================* kernel_main *======================================================================*/ PUBLIC int kernel_main() { disp_str("-----\"kernel_main\" begins-----\n"); TASK* p_task = task_table; PROCESS* p_proc = proc_table; char* p_task_stack = task_stack + STACK_SIZE_TOTAL; u16 selector_ldt = SELECTOR_LDT_FIRST; int i; for (i = 0; i < NR_TASKS; i++) { strcpy(p_proc->p_name, p_task->name); // name of the process p_proc->pid = i; // pid p_proc->ldt_sel = selector_ldt; memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR)); p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR)); p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; p_proc->regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK; p_proc->regs.eip = (u32)p_task->initial_eip; p_proc->regs.esp = (u32)p_task_stack; p_proc->regs.eflags = 0x1202; /* IF=1, IOPL=1 */ p_task_stack -= p_task->stacksize; p_proc++; p_task++; selector_ldt += 1 << 3; } k_reenter = 0; p_proc_ready = proc_table; put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */ enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */ restart(); while(1){} }
/*===========================================================================* * init_profile_clock * *===========================================================================*/ void init_profile_clock(u32_t freq) { int irq; if((irq = arch_init_profile_clock(freq)) >= 0) { /* Register interrupt handler for statistical system profiling. */ profile_clock_hook.proc_nr_e = CLOCK; put_irq_handler(&profile_clock_hook, irq, profile_clock_handler); enable_irq(&profile_clock_hook); } }
void main(void) { intr_init(); init_pit(); outb(0x21, 0xf8); outb(0xa1, 0xff); put_irq_handler(0, keyborad_handler); put_irq_handler(12, mouse_handler); put_irq_handler(0, timer_handler); kprintf("\n%s %s.%s. Copyright (c) 2013 loulanguju\n", KERNEL_NAME, KERNEL_RELEASE, KERNEL_VERSION); kprintf("Executing in %s mode.\n\n", "32-bit protected"); while (1) {// do while } return ; }
PUBLIC void init_keyboard() { kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; vk.count = 0; vk.p_head = vk.p_tail = vk.buf; put_irq_handler(KEYBOARD_IRQ, keyboard_handler); //设定键盘的中断处理程序 enable_irq(KEYBOARD_IRQ); //打开键盘中断 //清屏 clearScreen(); }
/*======================================================================* init_keyboard *======================================================================*/ PUBLIC void init_keyboard() { kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; caps_lock = 0; num_lock = 1; scroll_lock = 0; set_leds(); put_irq_handler(KEYBOARD_IRQ, keyboard_handler);/*设定键盘中断处理程序*/ enable_irq(KEYBOARD_IRQ); /*开键盘中断*/ }
/** * <Ring 1> Check hard drive, set IRQ handler, enable IRQ and initialize data * structures. *****************************************************************************/ PRIVATE void init_hd() { int i; /* Get the number of drives from the BIOS data area */ u8 * pNrDrives = (u8*)(0x475); printl("NrDrives:%d.\n", *pNrDrives); assert(*pNrDrives); put_irq_handler(AT_WINI_IRQ, hd_handler); enable_irq(CASCADE_IRQ); enable_irq(AT_WINI_IRQ); for (i = 0; i < (sizeof(hd_info) / sizeof(hd_info[0])); i++) memset(&hd_info[i], 0, sizeof(hd_info[0])); hd_info[0].open_cnt = 0; }
PRIVATE void init_hd() { int i; u8_t *pNrDrives = (u8_t*)(0x475); kprintf("NrDrives:%d.\n", *pNrDrives); put_irq_handler(AT_WINI_IRQ, hd_handler); enable_irq(CASCADE_IRQ); enable_irq(AT_WINI_IRQ); for (i = 0; i < (sizeof (hd_info) / sizeof (hd_info[0])); ++i) memset(&hd_info[i], 0, sizeof (hd_info[0])); hd_info[0].open_cnt = 0; }
PUBLIC void init_clock() { /* init 8253 8254 TIMER */ out_byte(TIMER_MODE,RATE_GENERATOR); out_byte(TIMER0,(u8)(TIMER_FREQ/HZ)); out_byte(TIMER0,(u8)((TIMER_FREQ/HZ)>>8)); put_irq_handler(CLOCK_IRQ,clock_handler); enable_irq(CLOCK_IRQ); MESSAGE m; m.EXPIRETIME=2000000000; m.source=TASK_SYS; set_timer(&m); nextexpiretime=-1; }
//初始化键盘中断 PUBLIC void init_keyboard() { kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; shift_l = shift_r = 0; alt_l = alt_r = 0; ctrl_l = ctrl_r = 0; caps_lock = 0; num_lock = 1; scroll_lock = 0; put_irq_handler(KEYBOARD_IRQ, keyboard_handler); enable_irq(KEYBOARD_IRQ); }
PUBLIC void init_hd() { /* Get the number of drives from the BIOS data area */ u8* pNrDrives = (u8*)(0x475); disp_str("NrDrives:"); disp_int(*pNrDrives); disp_str("\n"); put_irq_handler(AT_WINI_IRQ, hd_handler); enable_irq(CASCADE_IRQ); //打开级联中断线 enable_irq(AT_WINI_IRQ); //打开硬盘中断线 int i = 0; for(i = 0; i < (sizeof(hd_info) / sizeof(hd_info[0])); i++) memset(&hd_info[i], 0, sizeof(hd_info[0])); hd_info[0].open_cnt = 0; }
PUBLIC void init_keyboard(TTY *p_tty) { kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; code_with_E0 = 0; shift_l = shift_r = 0; ctrl_l = ctrl_r = 0; alt_l = alt_r = 0; num_lock = 1; caps_lock = 0; scroll_lock = 0; set_leds(); put_irq_handler(KEYBOARD_IRQ, keyboard_handler); enable_irq(KEYBOARD_IRQ); }
PRIVATE void init_hd() { /* 初始化硬盘 */ u8* pNrDrives = (u8*)(0x475); /* 从0x475处取得系统硬盘数,地址由BIOS指定 */ printl("NR Drives: %d\n", *pNrDrives); assert(*pNrDrives); put_irq_handler(AT_WINI_IRQ, hd_handler); /* 开启级联的中断口 */ enable_irq(CASCADE_IRQ); enable_irq(AT_WINI_IRQ); for (int i=0; i< (sizeof(hd_info) / sizeof(hd_info[0])); i++) { memset(&hd_info[i], 0, sizeof(hd_info[0])); } hd_info[0].open_cnt = 0; }
/*======================================================================* init_keyboard *----------------------------------------------------------------------* * 作用:初始化键盘中断处理函数,开启键盘中断 *======================================================================*/ PUBLIC void init_keyboard() { code_with_E0 = FALSE; shift_l = FALSE; shift_r = FALSE; ctrl_l = FALSE; ctrl_r = FALSE; alt_l = FALSE; alt_l = FALSE; // 初始化键盘缓冲区结构体 kb_in.count = 0; kb_in.p_head = kb_in.p_tail = kb_in.buf; // **************************** 设置 键盘中断 处理函数 **************************** put_irq_handler(KEYBOARD_IRQ, keyboard_handler); enable_irq(KEYBOARD_IRQ); }
void kernel_main(void) { clear(); clear_line(13); s32_print("memory size", (u8*)(0xb8000+160*13)); //int memsize = memtest(0x00400000, 0xbfffffff) / (1024 * 1024); // 0x2000000 = 32MB // because of bochs will alert memory access more than the memory size, // so limit address to 0x2000000, if use qemu, it works fine. memsize = memtest(0x00400000, 0x2000000); int memsize_mb = memsize / (1024 * 1024); u8 stack_str[10]="y"; u8 *sp = stack_str; sp = s32_itoa(memsize_mb, stack_str, 10); clear(); #if 1 clear_line(24); s32_print("memory size", (u8*)(0xb8000+160*24)); s32_print(sp, (u8*)(0xb8000+160*24 + 12*2)); s32_print("MB", (u8*)(0xb8000+160*24 + 12*2 + 4*2)); #endif void setup_paging(void); //setup_paging(); put_irq_handler(CLOCK_IRQ, clock_handler); enable_irq(CLOCK_IRQ); ready_process = proc_table; init_proc(); cur_vb = (u8*)0xb8000+160; void restart(void); restart(); s32_print("xxxxxxxxxxx", (u8*)(0xb8000+160*15)); while(1); }
/*<ring 1> 功能: 初始化硬盘,其中包括显示主机硬盘数、启动硬盘驱动程序及初始化hd_info 参数: (无) 返回值: (无) */ static void init_hd(){ int i; u8 *p_drivers_count=(u8*)(0x475); #ifdef DEBUG_HD printl("Drivers_count:%d.\n",*p_drivers_count); #endif assert(*p_drivers_count,""); /*启动硬盘中断,由于硬盘中断接在级联从片上,所以需要同时启动主片上的对应驱动*/ put_irq_handler(AT_WINI_IRQ,hd_handler); enable_irq(CASCADE_IRQ); enable_irq(AT_WINI_IRQ); /*hd_info初始化*/ for(i=0;i<ARRAY_LENGTH(hd_info);i++){ memset(&hd_info[i],0,sizeof(hd_info[0])); } hd_info[0].open_count=0; }
// ---------------------------------------------------------------------------- // kernel_main 由内核跳入 PUBLIC int kernel_main() { disp_str("-----\"kernel_main\" begins-----\n"); TASK *p_task = task_table; PROCESS *p_proc = proc_table; char *p_task_stack = task_stack + STACK_SIZE_TOTAL; u16 selector_ldt = SELECTOR_LDT_FIRST; int i; for (i = 0; i < NR_TASKS; ++i) { // name of the process strcpy(p_proc->p_name, p_task->name); // pid p_proc->pid = i; p_proc->ldt_sel = selector_ldt; // 由 8 的倍数的偏移变成数组的下标 // 进程的两个 ldt 为了简化起见, 分别被初始化位内核代码段和内核数据段 // 只是改变了以下 DPL 以让其运行在低特权级下 memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR)); // chage the DPL p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR)); p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; p_proc->regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK; p_proc->regs.eip = (u32)p_task->initial_eip; p_proc->regs.esp = (u32)p_task_stack; p_proc->regs.eflags = 0x1202; // IF = 1, IOPL = 1, bit 2 is always 1 p_task_stack -= p_task->stacksize; ++p_proc; ++p_task; selector_ldt += 1 << 3; } proc_table[0].ticks = proc_table[0].priority = 15; // 0x96 proc_table[1].ticks = proc_table[1].priority = 5; // 0x32 proc_table[2].ticks = proc_table[2].priority = 3; // 0x1E k_reenter = 0; ticks = 0; p_proc_ready = proc_table; // 初始化 8253 PIT out_byte(TIMER_MODE, RATE_GENERATOR); out_byte(TIMER0, (u8)(TIMER_FREQ / HZ)); out_byte(TIMER0, (u8)((TIMER_FREQ / HZ) >> 8)); put_irq_handler(CLOCK_IRQ, clock_handler); // 设定时钟中断处理程序 enable_irq(CLOCK_IRQ); // 让8259A可以接收时钟中断 restart(); while (1) {} }
PUBLIC int kernel_main(void) { TASK *p_task = task_table; PROCESS *p_proc = proc_table; char *p_task_stack = task_stack + STACK_SIZE_TOTAL; u16 selector_ldt = SELECTOR_LDT_FIRST; int i; for(i = 0; i < NR_TASKS; i++) { //strcpy(p_proc->p_name, p_task->name); //p_proc->pid = i; /* initialize the ldt selector for process A*/ p_proc->ldt_sel = selector_ldt; /*initialize two ldt desciptors for process A * the code desciptor equals to kernel code desciptor * the data desciptor equals to the kernel data desciptor*/ memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR)); p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR)); p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; /*initialize the segment registers for process A*/ p_proc->regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK ) | SA_TIL | RPL_TASK; p_proc->regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK ) | SA_TIL | RPL_TASK; p_proc->regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK ) | SA_TIL | RPL_TASK; p_proc->regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK ) | SA_TIL | RPL_TASK; p_proc->regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK ) | SA_TIL | RPL_TASK; p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK ) | RPL_TASK; /* initialize eip address for process A * eip will point to function testA*/ p_proc->regs.eip = (u32) p_task->initial_eip; /* process A will use a new stack */ p_proc->regs.esp = (u32) p_task_stack; /*IF =1, IOFL =1 => unblock interrupt and process can use io ports*/ p_proc->regs.eflags = 0x1202; p_task_stack -= p_task->stack_size; p_proc++; p_task++; selector_ldt += 0x08; } k_reenter = 0; /*jump to new process*/ p_proc_ready = proc_table; /*register clock_handler, enable clock_irq*/ put_irq_handler(CLOCK_IRQ, clock_handler); enable_irq(CLOCK_IRQ); restart(); while(TRUE) {} return 0; }
PUBLIC int init_local_timer(unsigned freq) { #ifdef USE_APIC /* if we know the address, lapic is enabled and we should use it */ if (lapic_addr) { unsigned cpu = cpuid; tsc_per_ms[cpu] = div64u(cpu_get_freq(cpu), 1000); lapic_set_timer_one_shot(1000000/system_hz); } else { BOOT_VERBOSE(printf("Initiating legacy i8253 timer\n")); #else { #endif init_8253A_timer(freq); estimate_cpu_freq(); /* always only 1 cpu in the system */ tsc_per_ms[0] = div64u(cpu_get_freq(0), 1000); } return 0; } PUBLIC void stop_local_timer(void) { #ifdef USE_APIC if (lapic_addr) { lapic_stop_timer(); apic_eoi(); } else #endif { stop_8253A_timer(); } } PUBLIC void restart_local_timer(void) { #ifdef USE_APIC if (lapic_addr) { lapic_restart_timer(); } #endif } PUBLIC int register_local_timer_handler(const irq_handler_t handler) { #ifdef USE_APIC if (lapic_addr) { /* Using APIC, it is configured in apic_idt_init() */ BOOT_VERBOSE(printf("Using LAPIC timer as tick source\n")); } else #endif { /* Using PIC, Initialize the CLOCK's interrupt hook. */ pic_timer_hook.proc_nr_e = NONE; pic_timer_hook.irq = CLOCK_IRQ; put_irq_handler(&pic_timer_hook, CLOCK_IRQ, handler); } return 0; } PUBLIC void cycles_accounting_init(void) { #ifdef CONFIG_SMP unsigned cpu = cpuid; #endif read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch)); make_zero64(get_cpu_var(cpu, cpu_last_tsc)); make_zero64(get_cpu_var(cpu, cpu_last_idle)); }
/*===========================================================================* * do_irqctl * *===========================================================================*/ int do_irqctl(struct proc * caller, message * m_ptr) { /* Dismember the request message. */ int irq_vec; int irq_hook_id; int notify_id; int r = OK; int i; irq_hook_t *hook_ptr; struct priv *privp; /* Hook identifiers start at 1 and end at NR_IRQ_HOOKS. */ irq_hook_id = m_ptr->m_lsys_krn_sys_irqctl.hook_id - 1; irq_vec = m_ptr->m_lsys_krn_sys_irqctl.vector; /* See what is requested and take needed actions. */ switch(m_ptr->m_lsys_krn_sys_irqctl.request) { /* Enable or disable IRQs. This is straightforward. */ case IRQ_ENABLE: case IRQ_DISABLE: if (irq_hook_id >= NR_IRQ_HOOKS || irq_hook_id < 0 || irq_hooks[irq_hook_id].proc_nr_e == NONE) return(EINVAL); if (irq_hooks[irq_hook_id].proc_nr_e != caller->p_endpoint) return(EPERM); if (m_ptr->m_lsys_krn_sys_irqctl.request == IRQ_ENABLE) { enable_irq(&irq_hooks[irq_hook_id]); } else disable_irq(&irq_hooks[irq_hook_id]); break; /* Control IRQ policies. Set a policy and needed details in the IRQ table. * This policy is used by a generic function to handle hardware interrupts. */ case IRQ_SETPOLICY: /* Check if IRQ line is acceptable. */ if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) return(EINVAL); privp= priv(caller); if (!privp) { printf("do_irqctl: no priv structure!\n"); return EPERM; } if (privp->s_flags & CHECK_IRQ) { for (i= 0; i<privp->s_nr_irq; i++) { if (irq_vec == privp->s_irq_tab[i]) break; } if (i >= privp->s_nr_irq) { printf( "do_irqctl: IRQ check failed for proc %d, IRQ %d\n", caller->p_endpoint, irq_vec); return EPERM; } } /* When setting a policy, the caller must provide an identifier that * is returned on the notification message if a interrupt occurs. */ notify_id = m_ptr->m_lsys_krn_sys_irqctl.hook_id; if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL); /* Try to find an existing mapping to override. */ hook_ptr = NULL; for (i=0; !hook_ptr && i<NR_IRQ_HOOKS; i++) { if (irq_hooks[i].proc_nr_e == caller->p_endpoint && irq_hooks[i].notify_id == notify_id) { irq_hook_id = i; hook_ptr = &irq_hooks[irq_hook_id]; /* existing hook */ rm_irq_handler(&irq_hooks[irq_hook_id]); } } /* If there is nothing to override, find a free hook for this mapping. */ for (i=0; !hook_ptr && i<NR_IRQ_HOOKS; i++) { if (irq_hooks[i].proc_nr_e == NONE) { irq_hook_id = i; hook_ptr = &irq_hooks[irq_hook_id]; /* free hook */ } } if (hook_ptr == NULL) return(ENOSPC); /* Install the handler. */ hook_ptr->proc_nr_e = caller->p_endpoint; /* process to notify */ hook_ptr->notify_id = notify_id; /* identifier to pass */ hook_ptr->policy = m_ptr->m_lsys_krn_sys_irqctl.policy; /* policy for interrupts */ put_irq_handler(hook_ptr, irq_vec, generic_handler); DEBUGBASIC(("IRQ %d handler registered by %s / %d\n", irq_vec, caller->p_name, caller->p_endpoint)); /* Return index of the IRQ hook in use. */ m_ptr->m_krn_lsys_sys_irqctl.hook_id = irq_hook_id + 1; break; case IRQ_RMPOLICY: if (irq_hook_id < 0 || irq_hook_id >= NR_IRQ_HOOKS || irq_hooks[irq_hook_id].proc_nr_e == NONE) { return(EINVAL); } else if (caller->p_endpoint != irq_hooks[irq_hook_id].proc_nr_e) { return(EPERM); } /* Remove the handler and return. */ rm_irq_handler(&irq_hooks[irq_hook_id]); irq_hooks[irq_hook_id].proc_nr_e = NONE; break; default: r = EINVAL; /* invalid IRQ REQUEST */ } return(r); }