소스 검색

:bug: 页表拷贝的bug

fslongjin 2 년 전
부모
커밋
b7437b24d7
7개의 변경된 파일37개의 추가작업 그리고 37개의 파일을 삭제
  1. 1 1
      kernel/Makefile
  2. 2 5
      kernel/mm/mm.c
  3. 24 26
      kernel/process/process.c
  4. 4 4
      kernel/sched/sched.c
  5. 1 1
      user/Makefile
  6. 5 0
      user/init.c
  7. BIN
      user/sys_api_lib

+ 1 - 1
kernel/Makefile

@@ -1,6 +1,6 @@
 SUBDIR_ROOTS := . common
 DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
-GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel 
+GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel
 GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
 
 DIR_LIB=lib

+ 2 - 5
kernel/mm/mm.c

@@ -20,7 +20,7 @@ void mm_init()
     int count;
 
     multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count);
-    
+
     for (int i = 0; i < count; ++i)
     {
         //可用的内存
@@ -33,8 +33,6 @@ void mm_init()
         memory_management_struct.e820[i].type = mb2_mem_info[i].type;
         memory_management_struct.len_e820 = i;
 
-        
-
         // 脏数据
         if (mb2_mem_info[i].type > 4 || mb2_mem_info[i].len == 0 || mb2_mem_info[i].type < 1)
             break;
@@ -201,7 +199,6 @@ void mm_init()
 
     kinfo("Memory management unit initialize complete!");
 
-    
     flush_tlb();
     // 初始化slab内存池
     slab_init();
@@ -624,7 +621,7 @@ void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul
  */
 void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user)
 {
-    kdebug("proc_page_table_addr=%#018lx",proc_page_table_addr);
+    // kdebug("proc_page_table_addr=%#018lx", proc_page_table_addr);
     // 计算线性地址对应的pml4页表项的地址
     ul *tmp;
     if (is_phys)

+ 24 - 26
kernel/process/process.c

@@ -12,7 +12,7 @@
 #include <process/spinlock.h>
 
 spinlock_t process_global_pid_write_lock; // 增加pid的写锁
-long process_global_pid = 0;              // 系统中最大的pid
+long process_global_pid = 1;              // 系统中最大的pid
 
 extern void system_call(void);
 extern void kernel_thread_func(void);
@@ -371,7 +371,7 @@ ul do_execve(struct pt_regs *regs, char *path)
     regs->rflags = 0x200246;
     regs->rax = 1;
     regs->es = 0;
-    
+
     kdebug("do_execve is running...");
 
     // 当前进程正在与父进程共享地址空间,需要创建
@@ -427,15 +427,13 @@ ul do_execve(struct pt_regs *regs, char *path)
     // 清除进程的vfork标志位
     current_pcb->flags &= ~PF_VFORK;
 
+    struct vfs_file_t *filp = process_open_exec_file(path);
+    if ((unsigned long)filp <= 0)
+        return (unsigned long)filp;
 
-
-    struct vfs_file_t* filp = process_open_exec_file(path);
-    if((unsigned long)filp <= 0 )
-		return (unsigned long)filp;
-    
     memset((void *)code_start_addr, 0, PAGE_2M_SIZE);
     uint64_t pos = 0;
-    int retval = filp->file_ops->read(filp, code_start_addr, PAGE_2M_SIZE, &pos);
+    int retval = filp->file_ops->read(filp, (char *)code_start_addr, PAGE_2M_SIZE, &pos);
     kdebug("execve ok");
 
     return 0;
@@ -587,12 +585,6 @@ void process_init()
     initial_proc_union.pcb.state = PROC_RUNNING;
     initial_proc_union.pcb.preempt_count = 0;
     initial_proc_union.pcb.cpu_id = 0;
-    // 获取新的进程的pcb
-    // struct process_control_block *p = container_of(list_next(&current_pcb->list), struct process_control_block, list);
-
-    // kdebug("Ready to switch...");
-    //  切换到新的内核线程
-    //  switch_proc(current_pcb, p);
 }
 
 /**
@@ -613,7 +605,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
 
     // 为新的进程分配栈空间,并将pcb放置在底部
     tsk = (struct process_control_block *)kmalloc(STACK_SIZE, 0);
-    kdebug("struct process_control_block ADDRESS=%#018lx", (uint64_t)tsk);
+    // kdebug("struct process_control_block ADDRESS=%#018lx", (uint64_t)tsk);
 
     if (tsk == NULL)
     {
@@ -799,7 +791,7 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
     // 与父进程共享内存空间
     if (clone_flags & CLONE_VM)
     {
-        kdebug("copy_vm\t\t current_pcb->mm->pgd=%#018lx", current_pcb->mm->pgd);
+        // kdebug("copy_vm\t current_pcb->mm->pgd=%#018lx", current_pcb->mm->pgd);
         pcb->mm = current_pcb->mm;
 
         return retval;
@@ -819,46 +811,52 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
     memset(phys_2_virt(new_mms->pgd), 0, PAGE_4K_SIZE / 2);
 
     // 拷贝内核空间的页表指针
-    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]) + 256, PAGE_4K_SIZE / 2);
+    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]->mm->pgd) + 256, PAGE_4K_SIZE / 2);
 
-    pml4t_t *current_pgd = (pml4t_t *)phys_2_virt(current_pcb->mm->pgd);
+    uint64_t *current_pgd = (uint64_t *)phys_2_virt(current_pcb->mm->pgd);
 
+    uint64_t *new_pml4t = (uint64_t *)phys_2_virt(new_mms->pgd);
     // 迭代地拷贝用户空间
     for (int i = 0; i <= 255; ++i)
     {
         // 当前页表项为空
-        if ((current_pgd + i)->pml4t == 0)
+        if ((*(uint64_t *)(current_pgd + i)) == 0)
             continue;
 
         // 分配新的二级页表
         pdpt_t *new_pdpt = (pdpt_t *)kmalloc(PAGE_4K_SIZE, 0);
         memset(new_pdpt, 0, PAGE_4K_SIZE);
+
         // 在新的一级页表中设置新的二级页表表项
-        set_pml4t((uint64_t *)(current_pgd + i), mk_pml4t(virt_2_phys(new_pdpt), ((current_pgd + i)->pml4t) & 0xfffUL));
+        set_pml4t(new_pml4t + i, mk_pml4t(virt_2_phys(new_pdpt), (*(current_pgd + i)) & 0xfffUL));
 
-        pdpt_t *current_pdpt = (pdpt_t *)phys_2_virt((current_pgd + i)->pml4t & (~0xfffUL));
-        // 设置二级页表
+        pdpt_t *current_pdpt = (pdpt_t *)phys_2_virt(*(uint64_t *)(current_pgd + i) & (~0xfffUL));
+
+        // kdebug("current pdpt=%#018lx \t (current_pgd + i)->pml4t=%#018lx", current_pdpt, *(uint64_t *)(current_pgd+i));
+        //  设置二级页表
         for (int j = 0; j < 512; ++j)
         {
-            if ((current_pdpt + j)->pdpt == 0)
+            if (*(uint64_t *)(current_pdpt + j) == 0)
                 continue;
+
             // 分配新的三级页表
             pdt_t *new_pdt = (pdt_t *)kmalloc(PAGE_4K_SIZE, 0);
             memset(new_pdt, 0, PAGE_4K_SIZE);
 
             // 在新的二级页表中设置三级页表的表项
-            set_pdpt((uint64_t *)new_pdpt, mk_pdpt(virt_2_phys(new_pdt), (current_pdpt + j)->pdpt & 0xfffUL));
+            set_pdpt((uint64_t *)(new_pdpt + j), mk_pdpt(virt_2_phys(new_pdt), (*(uint64_t *)(current_pdpt + j)) & 0xfffUL));
 
-            pdt_t *current_pdt = (pdt_t *)phys_2_virt((current_pdpt + j)->pdpt & (~0xfffUL));
+            pdt_t *current_pdt = (pdt_t *)phys_2_virt((*(uint64_t *)(current_pdpt + j)) & (~0xfffUL));
 
             // 拷贝内存页
             for (int k = 0; k < 512; ++k)
             {
                 if ((current_pdt + k)->pdt == 0)
                     continue;
+
                 // 获取一个新页
                 struct Page *pg = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED);
-                set_pdt((uint64_t *)(current_pdt + k), mk_pdt(pg->addr_phys, (current_pdt + k)->pdt & 0x1fffUL));
+                set_pdt((uint64_t *)(new_pdt + k), mk_pdt(pg->addr_phys, (current_pdt + k)->pdt & 0x1fffUL));
 
                 // 拷贝数据
                 memcpy(phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1fffUL)), PAGE_2M_SIZE);

+ 4 - 4
kernel/sched/sched.c

@@ -12,7 +12,7 @@ struct process_control_block *sched_cfs_dequeue()
 {
     if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list))
     {
-        kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count);
+        // kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count);
         return &initial_proc_union.pcb;
     }
 
@@ -30,9 +30,9 @@ struct process_control_block *sched_cfs_dequeue()
  */
 void sched_cfs_enqueue(struct process_control_block *pcb)
 {
-    struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
-    if (proc == &initial_proc_union.pcb)
+    if (pcb == initial_proc[proc_current_cpu_id])
         return;
+    struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
     if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
     {
         while (proc->virtual_runtime < pcb->virtual_runtime)
@@ -59,7 +59,7 @@ void sched_cfs()
 
         if (current_pcb->state == PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
             sched_cfs_enqueue(current_pcb);
-
+        // kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
         if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
         {
             switch (proc->priority)

+ 1 - 1
user/Makefile

@@ -2,7 +2,7 @@ user_sub_dirs = libs
 
 SUBDIR_ROOTS := . 
 DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
-GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel 
+GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ sys_api_lib
 GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
 
 

+ 5 - 0
user/init.c

@@ -25,6 +25,11 @@ int main()
     read(fd, buf, 128);
     put_string(buf, COLOR_YELLOW, COLOR_BLACK);
     close(fd);
+    
+    pid_t p = fork();
+    if(p == 0)
+        put_string("subproc\n", COLOR_PURPLE, COLOR_BLACK);
+    else put_string("parent proc\n", COLOR_ORANGE, COLOR_BLACK);
 
     while (1)
         ;

BIN
user/sys_api_lib