浏览代码

bugfix: exec执行的文件不存在时,自动退出进程。

fslongjin 2 年之前
父节点
当前提交
2a47569473

+ 1 - 1
kernel/common/glib.h

@@ -224,7 +224,7 @@ void *memset_c(void* dst, uint8_t c, size_t count)
  */
 static void *memcpy(void *dst, void *src, long Num)
 {
-    int d0, d1, d2;
+    int d0=0, d1=0, d2=0;
     __asm__ __volatile__("cld	\n\t"
                          "rep	\n\t"
                          "movsq	\n\t"

+ 0 - 20
kernel/driver/interrupt/apic/apic.c

@@ -178,26 +178,6 @@ void apic_init_ap_core_local_apic()
         : "a"(0x10000), "d"(0x00)
         : "memory");
 
-    /*
-    io_mfence();
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI) = 0x1000000;
-    io_mfence();
-    kdebug("cmci = %#018lx", *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI));
-    */
-    //*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = 0x10000;
-    // io_mfence();
-    /*
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL) = 0x1000000;
-    io_mfence();
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR) = 0x1000000;
-    io_mfence();
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0) = 0x1000000;
-    io_mfence();
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1) = 0x1000000;
-    io_mfence();
-    *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR) = 0x1000000;
-    io_mfence();
-    */
     kdebug("All LVT Masked");
 }
 /**

+ 0 - 1
kernel/driver/keyboard/ps2_keyboard.c

@@ -201,7 +201,6 @@ void ps2_keyboard_init()
     kb_buf_ptr = (struct ps2_keyboard_input_buffer *)kmalloc(sizeof(struct ps2_keyboard_input_buffer), 0);
 
     ps2_keyboard_reset_buffer(kb_buf_ptr);
-    
 
     // ======== 初始化中断RTE entry ==========
 

+ 2 - 1
kernel/driver/timers/HPET/HPET.c

@@ -7,6 +7,7 @@
 #include <process/process.h>
 #include <sched/sched.h>
 #include <smp/ipi.h>
+#include <driver/video/video.h>
 
 static struct acpi_HPET_description_table_t *hpet_table;
 static uint64_t HPET_REG_BASE = 0;
@@ -65,7 +66,7 @@ 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(TIMER_SIRQ);
+            set_softirq_status((1 << TIMER_SIRQ));
 
         sched_update_jiffies();
 

+ 9 - 5
kernel/driver/timers/timer.c

@@ -5,6 +5,8 @@
 #include <driver/timers/HPET/HPET.h>
 #include <process/process.h>
 
+struct timer_func_list_t timer_func_head;
+
 void test_timer()
 {
     printk_color(ORANGE, BLACK, "(test_timer)");
@@ -14,7 +16,7 @@ void timer_init()
 {
     timer_jiffies = 0;
     timer_func_init(&timer_func_head, NULL, NULL, -1UL);
-    register_softirq(0, &do_timer_softirq, NULL);
+    register_softirq(TIMER_SIRQ, &do_timer_softirq, NULL);
 
     struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
     timer_func_init(tmp, &test_timer, NULL, 5);
@@ -28,17 +30,18 @@ void do_timer_softirq(void *data)
     // if(current_pcb->pid==3)
     //     kdebug("pid3 timer irq");
     struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
-    
+
     while ((!list_empty(&timer_func_head.list)) && (tmp->expire_jiffies <= timer_jiffies))
     {
-        if(current_pcb->pid==3)
-        kdebug("pid3 timer do");
+        if (current_pcb->pid == 2)
+            kdebug("pid2 timer do");
         timer_func_del(tmp);
         tmp->func(tmp->data);
         kfree(tmp);
         tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
     }
 
+    softirq_ack(TIMER_SIRQ);
     // printk_color(ORANGE, BLACK, "(HPET%ld)", timer_jiffies);
 }
 
@@ -55,7 +58,8 @@ void timer_func_init(struct timer_func_list_t *timer_func, void (*func)(void *da
     list_init(&timer_func->list);
     timer_func->func = func;
     timer_func->data = data,
-    timer_func->expire_jiffies = timer_jiffies + expire_ms / 5 + expire_ms % HPET0_INTERVAL ? 1 : 0;    // 设置过期的时间片
+    // timer_func->expire_jiffies = timer_jiffies + expire_ms / 5 + expire_ms % HPET0_INTERVAL ? 1 : 0; // 设置过期的时间片
+    timer_func->expire_jiffies = cal_next_n_ms_jiffies(expire_ms); // 设置过期的时间片
 }
 
 /**

+ 17 - 15
kernel/driver/timers/timer.h

@@ -4,46 +4,48 @@
 #include "HPET/HPET.h"
 #include "rtc/rtc.h"
 
-uint64_t volatile timer_jiffies = 0;   // 系统时钟计数
+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)
 
 void timer_init();
 
-void do_timer_softirq(void* data);
+void do_timer_softirq(void *data);
 
 /**
  * @brief 定时功能队列
- * 
+ *
  */
 struct timer_func_list_t
 {
     struct List list;
     uint64_t expire_jiffies;
-    void (*func)(void* data);
-    void* data;
-}timer_func_head;   
+    void (*func)(void *data);
+    void *data;
+};
 
+extern struct timer_func_list_t timer_func_head;
 /**
  * @brief 初始化定时功能
- * 
+ *
  * @param timer_func 队列结构体
  * @param func 定时功能处理函数
  * @param data 传输的数据
  * @param expire_ms 定时时长(单位:ms)
  */
-void timer_func_init(struct timer_func_list_t * timer_func, void (*func)(void*data), void*data,uint64_t expire_ms);
+void timer_func_init(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_ms);
 
 /**
  * @brief 将定时功能添加到列表中
- * 
+ *
  * @param timer_func 待添加的定时功能
  */
-void timer_func_add(struct timer_func_list_t* timer_func);
+void timer_func_add(struct timer_func_list_t *timer_func);
 
 /**
  * @brief 将定时功能从列表中删除
- * 
- * @param timer_func 
+ *
+ * @param timer_func
  */
-void timer_func_del(struct timer_func_list_t* timer_func);
-
-
+void timer_func_del(struct timer_func_list_t *timer_func);

+ 5 - 4
kernel/driver/video/video.c

@@ -70,13 +70,15 @@ void init_frame_buffer(bool level)
  */
 static void video_refresh_framebuffer()
 {
-    if(current_pcb->pid==3)
-        kdebug("pid3 flush fb");
+
+    // kdebug("pid%d flush fb", current_pcb->pid);
+
     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, REFRESH_INTERVAL);
+    timer_func_init(tmp, &video_refresh_framebuffer, NULL, 10 * REFRESH_INTERVAL);
     timer_func_add(tmp);
     spin_unlock(&video_timer_func_add_lock);
 }
@@ -100,6 +102,5 @@ int video_init(bool level)
         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);
-
     }
 }

+ 1 - 0
kernel/driver/video/video.h

@@ -1,6 +1,7 @@
 #pragma once
 #include <common/glib.h>
 #include <stdbool.h>
+
 /**
  * @brief 初始化显示模块,需先低级初始化才能高级初始化
  * @param level 初始化等级

+ 4 - 4
kernel/exception/softirq.c

@@ -1,6 +1,7 @@
 #include "softirq.h"
 #include <common/kprint.h>
-
+#include <process/process.h>
+uint64_t softirq_status = 0;
 void set_softirq_status(uint64_t status)
 {
     softirq_status |= status;
@@ -45,10 +46,9 @@ void do_softirq()
     sti();
     for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_status; ++i)
     {
-        if (softirq_status & (1 << i))
-        {
+        if (softirq_status & (1 << i) && softirq_vector[i].action != NULL)
+        {            
             softirq_vector[i].action(softirq_vector[i].data);
-            softirq_status &= (~(1 << i));
         }
     }
 

+ 32 - 13
kernel/exception/softirq.h

@@ -4,41 +4,61 @@
  * @brief 软中断
  * @version 0.1
  * @date 2022-04-08
- * 
+ *
  * @copyright Copyright (c) 2022
- * 
+ *
  */
 #pragma once
 
-#include<common/glib.h>
+#include <common/glib.h>
 
 #define MAX_SOFTIRQ_NUM 64
 
-#define TIMER_SIRQ (1<<0)   // 时钟软中断号
+#define TIMER_SIRQ 0         // 时钟软中断号
+#define VIDEO_REFRESH_SIRQ 1 // 帧缓冲区刷新软中断
+
+/**
+ * @brief 发起软中断
+ *
+ */
+#define raise_softirq(sirq_num)            \
+    do                                     \
+    {                                      \
+        set_softirq_status(1 << sirq_num); \
+    } while (0);
+
+/**
+ * @brief 清除软中断标志位(需要软中断处理程序手动调用)
+ * 
+ */
+#define softirq_ack(sirq_num)        \
+    do                                 \
+    {                                  \
+        softirq_status &= (~(1 << sirq_num)); \
+    } while (0);
 
-uint64_t softirq_status = 0;
+extern uint64_t softirq_status;
 
 struct softirq_t
 {
-    void (*action)(void* data); // 软中断处理函数
-    void* data;
+    void (*action)(void *data); // 软中断处理函数
+    void *data;
 };
 
 struct softirq_t softirq_vector[MAX_SOFTIRQ_NUM] = {0};
 
-
 /**
  * @brief 软中断注册函数
- * 
+ *
  * @param irq_num 软中断号
  * @param action 响应函数
  * @param data 响应数据结构体
  */
-void register_softirq(uint32_t irq_num, void (*action)(void * data), void* data);
+void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
 
 /**
  * @brief 卸载软中断
- * 
+ *
  * @param irq_num 软中断号
  */
 void unregister_softirq(uint32_t irq_num);
@@ -48,9 +68,8 @@ uint64_t get_softirq_status();
 
 /**
  * @brief 软中断处理程序
- * 
+ *
  */
 void do_softirq();
 
-
 void softirq_init();

+ 3 - 5
kernel/main.c

@@ -87,9 +87,9 @@ void system_initialize()
 
     // 初始化printk
     printk_init(8, 16);
-//#ifdef DEBUG
+    //#ifdef DEBUG
     uart_init(COM1, 115200);
-//#endif
+    //#endif
     kinfo("Kernel Starting...");
     // 重新加载gdt和idt
 
@@ -116,7 +116,6 @@ void system_initialize()
     // 对显示模块进行低级初始化,不启用double buffer
     video_init(false);
 
-
     // =========== 重新设置initial_tss[0]的ist
     uchar *ptr = (uchar *)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
     ((struct process_control_block *)(ptr - STACK_SIZE))->cpu_id = 0;
@@ -158,14 +157,13 @@ void system_initialize()
     // test_mm();
 
     // process_init();
-
+    current_pcb->preempt_count = 0;
     process_init();
     // 对显示模块进行高级初始化,启用double buffer
     video_init(true);
     HPET_init();
     // fat32_init();
     // 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
-
 }
 
 //操作系统内核从这里开始执行

+ 15 - 19
kernel/process/process.c

@@ -11,12 +11,11 @@
 #include <common/stdio.h>
 #include <process/spinlock.h>
 #include <common/libELF/elf.h>
+#include <driver/video/video.h>
 
 spinlock_t process_global_pid_write_lock; // 增加pid的写锁
 long process_global_pid = 1;              // 系统中最大的pid
 
-uint64_t pid_one_map_offset = 0x0000020000000000;
-int pid_one_map_count = 0;
 
 extern void system_call(void);
 extern void kernel_thread_func(void);
@@ -133,8 +132,10 @@ struct vfs_file_t *process_open_exec_file(char *path)
 
     dentry = vfs_path_walk(path, 0);
 
+
     if (dentry == NULL)
         return (void *)-ENOENT;
+
     if (dentry->dir_inode->attribute == VFS_ATTR_DIR)
         return (void *)-ENOTDIR;
 
@@ -162,9 +163,10 @@ 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 ((unsigned long)filp <= 0)
+
+    if ((long)filp <= 0 && (long)filp >=-255)
     {
-        kdebug("(unsigned long)filp=%d", (long)filp);
+        // kdebug("(long)filp=%ld", (long)filp);
         return (unsigned long)filp;
     }
 
@@ -274,21 +276,11 @@ 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);
-    // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, 1 * PAGE_2M_SIZE, PAGE_USER_PAGE, true);
+    
     // 清空栈空间
     memset((void *)(current_pcb->mm->stack_start - PAGE_2M_SIZE), 0, PAGE_2M_SIZE);
 
-    // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE * 2, alloc_pages(ZONE_NORMAL, 2, PAGE_PGT_MAPPED)->addr_phys, 2 * PAGE_2M_SIZE, PAGE_USER_PAGE, true);
-    // // 清空栈空间
-    // memset((void *)(current_pcb->mm->stack_start - 2 * PAGE_2M_SIZE), 0, 2 * PAGE_2M_SIZE);
-
-    // if (current_pcb->pid == 1 && pid_one_map_count < 2)
-    // {
-    //     mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, pid_one_map_offset, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
-    //     memset(pid_one_map_offset, 0, PAGE_2M_SIZE);
-    //     pid_one_map_count++;
-    //     pid_one_map_offset += PAGE_2M_SIZE;
-    // }
+    
 
 load_elf_failed:;
     if (buf != NULL)
@@ -359,7 +351,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
     // 加载elf格式的可执行文件
     int tmp = process_load_elf_file(regs, path);
     if (tmp < 0)
-        return tmp;
+        goto exec_failed;
 
     // 拷贝参数列表
     if (argv != NULL)
@@ -394,7 +386,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
         regs->rdi = argc;
         regs->rsi = (uint64_t)dst_argv;
     }
-    // kdebug("execve ok");
+    kdebug("execve ok");
 
     regs->cs = USER_CS | 3;
     regs->ds = USER_DS | 3;
@@ -404,6 +396,9 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
     regs->es = 0;
 
     return 0;
+
+exec_failed:;
+    process_do_exit(tmp);
 }
 
 /**
@@ -415,6 +410,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
 ul initial_kernel_thread(ul arg)
 {
     // kinfo("initial proc running...\targ:%#018lx", arg);
+
     fat32_init();
 
     struct pt_regs *regs;
@@ -463,7 +459,7 @@ void process_exit_notify()
  */
 ul process_do_exit(ul code)
 {
-    kinfo("process exiting..., code is %#018lx.", code);
+    // kinfo("process exiting..., code is %ld.", (long)code);
     cli();
     struct process_control_block *pcb = current_pcb;
 

+ 2 - 2
kernel/process/spinlock.h

@@ -38,7 +38,6 @@ void spin_init(spinlock_t *lock)
  */
 void spin_lock(spinlock_t *lock)
 {
-    preempt_disable();
     __asm__ __volatile__("1:    \n\t"
                          "lock decq %0   \n\t" // 尝试-1
                          "jns 3f    \n\t"      // 加锁成功,跳转到步骤3
@@ -49,13 +48,14 @@ void spin_lock(spinlock_t *lock)
                          "jmp 1b    \n\t" // 尝试加锁
                          "3:"
                          : "=m"(lock->lock)::"memory");
+    preempt_disable();
 }
 
 void spin_unlock(spinlock_t *lock)
 {
+    preempt_enable();
     __asm__ __volatile__("movq $1, %0   \n\t"
                          : "=m"(lock->lock)::"memory");
-    preempt_enable();
 }
 
 /**

+ 5 - 9
kernel/sched/sched.c

@@ -1,5 +1,7 @@
 #include "sched.h"
 #include <common/kprint.h>
+#include <driver/video/video.h>
+#include <process/spinlock.h>
 
 struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
 
@@ -50,7 +52,9 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
  */
 void sched_cfs()
 {
+
     cli();
+
     current_pcb->flags &= ~PF_NEED_SCHED;
     struct process_control_block *proc = sched_cfs_dequeue();
     // kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
@@ -74,17 +78,9 @@ void sched_cfs()
                 break;
             }
         }
-        // kdebug("before switch, next.rip = %#018lx\tnext->gs=%#018lx", proc->thread->rip, proc->thread->gs);
-        // kdebug("currentpcb=%#018lx", (uint64_t)current_pcb);
         
-        // if(proc->pid == 1 && pid_one_map_count < 2)
-        // {
-        //     mm_map_proc_page_table(proc->mm->pgd, true, pid_one_map_offset, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
-        //     pid_one_map_count++;
-        //     pid_one_map_offset += PAGE_2M_SIZE;
-        // }
         process_switch_mm(proc);
-        
+
         switch_proc(current_pcb, proc);
     }
     else // 不进行切换

+ 2 - 2
user/apps/about/about.c

@@ -1,5 +1,5 @@
 #include <libc/stdio.h>
-
+#include<libc/stdlib.h>
 void print_ascii_logo()
 {
     printf(" ____                                      ___   ____ \n");
@@ -25,7 +25,7 @@ int main()
     // printf("Hello World!\n");
     print_ascii_logo();
     print_copyright();
-    exit(1);
+    exit(0);
     while (1)
         ;
 }

+ 2 - 2
user/apps/shell/cmd.c

@@ -381,7 +381,7 @@ int shell_cmd_exec(int argc, char **argv)
         // 子进程
         int path_len = 0;
         char *file_path = get_target_filepath(argv[1], &path_len);
-        printf("before execv, path=%s, argc=%d\n", file_path, argc);
+        // printf("before execv, path=%s, argc=%d\n", file_path, argc);
         execv(file_path, argv);
         free(argv);
         while (1)
@@ -390,7 +390,7 @@ int shell_cmd_exec(int argc, char **argv)
     }
     else
     {
-        printf("parent process wait for pid:[ %d ]\n", pid);
+        // printf("parent process wait for pid:[ %d ]\n", pid);
 
         waitpid(pid, &retval, 0);
         printf("parent process wait pid [ %d ], exit code=%d\n", pid, retval);