diff --git a/kernel/driver/interrupt/8259A/8259A.c b/kernel/driver/interrupt/8259A/8259A.c index 690838cd..0d3b85fd 100644 --- a/kernel/driver/interrupt/8259A/8259A.c +++ b/kernel/driver/interrupt/8259A/8259A.c @@ -8,9 +8,9 @@ extern void (*interrupt_table[24])(void); void init_8259A() { - // 初始化中断门, 中断使用第二个ist + // 初始化中断门, 中断使用第0个ist for(int i=32;i<=55;++i) - set_intr_gate(i, 2, interrupt_table[i-32]); + set_intr_gate(i, 0, interrupt_table[i-32]); kinfo("Initializing 8259A..."); // 初始化主芯片 diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index fe9ff55d..60923c04 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -68,6 +68,18 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies) set_softirq_status((1 << TIMER_SIRQ)); + // if (current_pcb->pid == 2) + // kwarn("timer_jiffies = %ld video_refresh_expire_jiffies=%ld", timer_jiffies, video_refresh_expire_jiffies); + if (timer_jiffies >= video_refresh_expire_jiffies) + { + raise_softirq(VIDEO_REFRESH_SIRQ); + } + else + { + if (video_last_refresh_pid != current_pcb->pid) + raise_softirq(VIDEO_REFRESH_SIRQ); + } + sched_update_jiffies(); break; @@ -142,6 +154,8 @@ int HPET_init() HPET_NUM_TIM_CAP = (tmp >> 8) & 0x1f; // 读取计时器数量 // kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq); + kdebug("HPET_freq=%ld", (long)HPET_freq); + // kdebug("HPET_freq=%lf", HPET_freq); struct apic_IO_APIC_RTE_entry entry; // 使用I/O APIC 的IRQ2接收hpet定时器0的中断 @@ -149,6 +163,7 @@ int HPET_init() // 计算HPET0间隔多少个时钟周期触发一次中断 uint64_t clks_to_intr = 0.001 * HPET0_INTERVAL * HPET_freq; + // kdebug("clks_to_intr=%#ld", clks_to_intr); if (clks_to_intr <= 0 || clks_to_intr > (HPET_freq * 8)) { kBUG("HPET0: Numof clocks to generate interrupt is INVALID! value=%lld", clks_to_intr); diff --git a/kernel/driver/timers/timer.h b/kernel/driver/timers/timer.h index 4e4fa3f9..a13d47b2 100644 --- a/kernel/driver/timers/timer.h +++ b/kernel/driver/timers/timer.h @@ -7,7 +7,7 @@ uint64_t volatile timer_jiffies = 0; // 系统时钟计数 // 计算接下来n毫秒对应的系统时间片 -#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + expire_ms / 5 + expire_ms % HPET0_INTERVAL ? 1 : 0) +#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + expire_ms / 5 + (expire_ms % HPET0_INTERVAL ? 1 : 0)) void timer_init(); diff --git a/kernel/driver/video/video.c b/kernel/driver/video/video.c index 22417e02..13720a01 100644 --- a/kernel/driver/video/video.c +++ b/kernel/driver/video/video.c @@ -7,10 +7,15 @@ #include #include #include +#include + // 每个时刻只能有1个进程新增定时任务 spinlock_t video_timer_func_add_lock; -#define REFRESH_INTERVAL 15 // 启动刷新帧缓冲区任务的时间间隔 +uint64_t video_refresh_expire_jiffies = 0; +uint64_t video_last_refresh_pid = -1; + +#define REFRESH_INTERVAL 15UL // 启动刷新帧缓冲区任务的时间间隔 ul VBE_FB_phys_addr; // 由bootloader传来的帧缓存区的物理地址 struct screen_info_t @@ -68,19 +73,15 @@ void init_frame_buffer(bool level) * @brief 刷新帧缓冲区 * */ -static void video_refresh_framebuffer() +void video_refresh_framebuffer(void *data) { - - // kdebug("pid%d flush fb", current_pcb->pid); + // 暂时设置一个很大的值作为屏障,防止二次进入该区域(造成#GP) + video_refresh_expire_jiffies = timer_jiffies + 100000; + video_last_refresh_pid = current_pcb->pid; + softirq_ack(VIDEO_REFRESH_SIRQ); memcpy((void *)sc_info.fb_vaddr, (void *)sc_info.double_fb_vaddr, (sc_info.length << 2)); - - // 新增下一个刷新定时任务 - struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0); - spin_lock(&video_timer_func_add_lock); - timer_func_init(tmp, &video_refresh_framebuffer, NULL, 10 * REFRESH_INTERVAL); - timer_func_add(tmp); - spin_unlock(&video_timer_func_add_lock); + video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL); } /** @@ -99,8 +100,15 @@ int video_init(bool level) // 启用双缓冲后,使能printk滚动动画 // printk_enable_animation(); // 初始化第一个屏幕刷新任务 - struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0); - timer_func_init(tmp, &video_refresh_framebuffer, NULL, REFRESH_INTERVAL); - timer_func_add(tmp); + // struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0); + // timer_func_init(tmp, &video_refresh_framebuffer, NULL, 10*REFRESH_INTERVAL); + // timer_func_add(tmp); + register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL); + kdebug("15/5=%#ld", 15 / 5); + kdebug("1212121=%#ld", REFRESH_INTERVAL / 5); + kdebug("sdds21=%#ld", REFRESH_INTERVAL / 5 + (REFRESH_INTERVAL % HPET0_INTERVAL ? 1 : 0)); + video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL); + kdebug("video_refresh_expire_jiffies=%ld", video_refresh_expire_jiffies); + raise_softirq(VIDEO_REFRESH_SIRQ); } } \ No newline at end of file diff --git a/kernel/driver/video/video.h b/kernel/driver/video/video.h index 7e10fcd2..aa1b05d0 100644 --- a/kernel/driver/video/video.h +++ b/kernel/driver/video/video.h @@ -9,4 +9,9 @@ * true ->高级初始化:增加double buffer的支持 * @return int */ -int video_init(bool level); \ No newline at end of file +int video_init(bool level); + +extern uint64_t video_refresh_expire_jiffies; +extern uint64_t video_last_refresh_pid; + +extern void video_refresh_framebuffer(); \ No newline at end of file diff --git a/kernel/exception/softirq.c b/kernel/exception/softirq.c index c97a1010..14c8cfdc 100644 --- a/kernel/exception/softirq.c +++ b/kernel/exception/softirq.c @@ -1,6 +1,7 @@ #include "softirq.h" #include #include +#include uint64_t softirq_status = 0; void set_softirq_status(uint64_t status) { @@ -42,17 +43,18 @@ void unregister_softirq(uint32_t irq_num) */ void do_softirq() { - sti(); + // video_refresh_framebuffer(); for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_status; ++i) { if (softirq_status & (1 << i) && softirq_vector[i].action != NULL) - { + { softirq_vector[i].action(softirq_vector[i].data); } } cli(); + } void softirq_init() diff --git a/kernel/process/process.c b/kernel/process/process.c index f3e075af..1a98e1df 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -16,7 +16,6 @@ spinlock_t process_global_pid_write_lock; // 增加pid的写锁 long process_global_pid = 1; // 系统中最大的pid - extern void system_call(void); extern void kernel_thread_func(void); @@ -132,7 +131,6 @@ struct vfs_file_t *process_open_exec_file(char *path) dentry = vfs_path_walk(path, 0); - if (dentry == NULL) return (void *)-ENOENT; @@ -164,7 +162,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path) int retval = 0; struct vfs_file_t *filp = process_open_exec_file(path); - if ((long)filp <= 0 && (long)filp >=-255) + if ((long)filp <= 0 && (long)filp >= -255) { // kdebug("(long)filp=%ld", (long)filp); return (unsigned long)filp; @@ -276,12 +274,10 @@ static int process_load_elf_file(struct pt_regs *regs, char *path) uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true); - + // 清空栈空间 memset((void *)(current_pcb->mm->stack_start - PAGE_2M_SIZE), 0, PAGE_2M_SIZE); - - load_elf_failed:; if (buf != NULL) kfree(buf); @@ -565,13 +561,14 @@ void process_init() */ // 初始化pid的写锁 spin_init(&process_global_pid_write_lock); - // 初始化进程的循环链表 list_init(&initial_proc_union.pcb.list); kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核进程 initial_proc_union.pcb.state = PROC_RUNNING; initial_proc_union.pcb.preempt_count = 0; initial_proc_union.pcb.cpu_id = 0; + initial_proc_union.pcb.virtual_runtime = (1UL << 60); + current_pcb->virtual_runtime = (1UL << 60); } /** @@ -625,7 +622,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned spin_unlock(&process_global_pid_write_lock); tsk->cpu_id = proc_current_cpu_id; - tsk->state = PROC_UNINTERRUPTIBLE; + tsk->state = PROC_RUNNING; tsk->parent_pcb = current_pcb; wait_queue_init(&tsk->wait_child_proc_exit, NULL); diff --git a/kernel/process/process.h b/kernel/process/process.h index 8b09ba21..c55a0f73 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -125,7 +125,7 @@ struct process_control_block long pid; long priority; // 优先级 - long virtual_runtime; // 虚拟运行时间 + int64_t virtual_runtime; // 虚拟运行时间 // 进程拥有的文件描述符的指针数组 // todo: 改用动态指针数组 diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index 5cccd8ab..8ca1ce80 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -78,6 +78,13 @@ void sched_cfs() break; } } + + // if (proc->pid == 0) + // { + // kdebug("switch to pid0, current pid%ld, vrt=%ld pid0 vrt=%ld", current_pcb->pid, current_pcb->virtual_runtime, proc->virtual_runtime); + // if(current_pcb->state != PROC_RUNNING) + // kdebug("current_pcb->state!=PROC_RUNNING"); + // } process_switch_mm(proc);