Browse Source

:new: 在shell中启动另一个程序

fslongjin 2 years ago
parent
commit
4e04ab9eee

+ 2 - 1
.vscode/settings.json

@@ -100,7 +100,8 @@
         "elf.h": "c",
         "stdio.h": "c",
         "wait_queue.h": "c",
-        "stddef.h": "c"
+        "stddef.h": "c",
+        "spinlock.h": "c"
     },
     "C_Cpp.errorSquiggles": "Enabled",
     "esbonio.sphinx.confDir": ""

+ 2 - 0
kernel/common/glib.h

@@ -170,6 +170,8 @@ static inline struct List *list_next(struct List *entry)
 //计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
 static inline int strlen(char *s)
 {
+    if(s == NULL)
+        return 0;
     register int __res = 0;
     while (s[__res] != '\0')
     {

+ 6 - 2
kernel/driver/timers/timer.c

@@ -3,6 +3,7 @@
 #include <exception/softirq.h>
 #include <mm/slab.h>
 #include <driver/timers/HPET/HPET.h>
+#include <process/process.h>
 
 void test_timer()
 {
@@ -24,11 +25,14 @@ void timer_init()
 
 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");
         timer_func_del(tmp);
         tmp->func(tmp->data);
         kfree(tmp);

+ 8 - 0
kernel/driver/video/video.c

@@ -6,6 +6,9 @@
 #include <common/kprint.h>
 #include <mm/mm.h>
 #include <mm/slab.h>
+#include <process/spinlock.h>
+// 每个时刻只能有1个进程新增定时任务
+spinlock_t video_timer_func_add_lock;
 
 #define REFRESH_INTERVAL 15 // 启动刷新帧缓冲区任务的时间间隔
 
@@ -67,11 +70,15 @@ void init_frame_buffer(bool level)
  */
 static void video_refresh_framebuffer()
 {
+    if(current_pcb->pid==3)
+        kdebug("pid3 flush fb");
     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_add(tmp);
+    spin_unlock(&video_timer_func_add_lock);
 }
 
 /**
@@ -86,6 +93,7 @@ int video_init(bool level)
     init_frame_buffer(level);
     if (level)
     {
+        spin_init(&video_timer_func_add_lock);
         // 启用双缓冲后,使能printk滚动动画
         // printk_enable_animation();
         // 初始化第一个屏幕刷新任务

+ 9 - 7
kernel/mm/mm.c

@@ -68,7 +68,7 @@ void mm_init()
         //可用的内存
         if (mb2_mem_info->type == 1)
             Total_Memory += mb2_mem_info->len;
-        
+
         kdebug("[i=%d] mb2_mem_info[i].type=%d, mb2_mem_info[i].addr=%#018lx", i, mb2_mem_info[i].type, mb2_mem_info[i].addr);
         // 保存信息到mms
         memory_management_struct.e820[i].BaseAddr = mb2_mem_info[i].addr;
@@ -345,7 +345,7 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)
                         x->attr = attr;
                     }
                     // 成功分配了页面,返回第一个页面的指针
-                    kwarn("start page num=%d\n", start_page_num);
+                    // kwarn("start page num=%d\n", start_page_num);
                     return (struct Page *)(memory_management_struct.pages_struct + start_page_num);
                 }
             }
@@ -457,7 +457,7 @@ void page_table_init()
 {
     kinfo("Re-Initializing page table...");
     ul *global_CR3 = get_CR3();
-    
+
     int js = 0;
     ul *tmp_addr;
     for (int i = 0; i < memory_management_struct.count_zones; ++i)
@@ -472,9 +472,9 @@ void page_table_init()
         {
             // if (p->addr_phys)
             //     kdebug("(ul)phys_2_virt(p->addr_phys)=%#018lx",(ul)phys_2_virt(p->addr_phys));
-                //mm_map_phys_addr((ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE);
+            // mm_map_phys_addr((ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE);
             mm_map_proc_page_table((uint64_t)get_CR3(), true, (ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE, false, true);
-            
+
             ++p;
             ++js;
         }
@@ -483,7 +483,6 @@ void page_table_init()
     flush_tlb();
 
     kinfo("Page table Initialized. Affects:%d", js);
-
 }
 
 /**
@@ -582,7 +581,10 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_
                 ul *pde_ptr = pd_ptr + pde_id;
                 if (*pde_ptr != 0 && user)
                 {
-                    kwarn("page already mapped!");
+                    // kwarn("page already mapped!");
+                    // 如果是用户态可访问的页,则释放当前新获取的物理页
+                    free_pages(Phy_to_2M_Page((ul)phys_addr_start + length_mapped), 1);
+                    length_mapped += PAGE_2M_SIZE;
                     continue;
                 }
                 // 页面写穿,禁止缓存

+ 17 - 40
kernel/process/process.c

@@ -110,14 +110,6 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
     //  set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
     //           initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
 
-    if (next->pid == 2)
-    {
-
-        struct pt_regs *child_regs = (struct pt_regs *)next->thread->rsp;
-        kdebug("next->thd->rip=%#018lx", next->thread->rip);
-        kdebug("next proc's ret addr = %#018lx\t next child_regs->rsp = %#018lx, next new_rip=%#018lx)", child_regs->rip, child_regs->rsp, child_regs->rip);
-    }
-
     __asm__ __volatile__("movq	%%fs,	%0 \n\t"
                          : "=a"(prev->thread->fs));
     __asm__ __volatile__("movq	%%gs,	%0 \n\t"
@@ -214,7 +206,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
         retval = -EUNSUPPORTED;
         goto load_elf_failed;
     }
-    kdebug("filename=%s:\te_entry=%#018lx", path, ehdr.e_entry);
+    // kdebug("filename=%s:\te_entry=%#018lx", path, ehdr.e_entry);
     regs->rip = ehdr.e_entry;
     current_pcb->mm->code_addr_start = ehdr.e_entry;
 
@@ -246,7 +238,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
         pos = phdr->p_offset;
 
         uint64_t virt_base = phdr->p_vaddr;
-        kdebug("virt_base = %#018lx, &memory_management_struct=%#018lx", virt_base, &memory_management_struct);
+        // kdebug("virt_base = %#018lx, &memory_management_struct=%#018lx", virt_base, &memory_management_struct);
 
         while (remain_mem_size > 0)
         {
@@ -254,7 +246,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
             // todo: 改用slab分配4K大小内存块并映射到4K页
             if (!mm_check_mapped((uint64_t)current_pcb->mm->pgd, virt_base)) // 未映射,则新增物理页
             {
-                mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, virt_base, alloc_pages(ZONE_NORMAL, 10, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true);
+                mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, virt_base, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true);
 
                 memset((void *)virt_base, 0, PAGE_2M_SIZE);
             }
@@ -280,16 +272,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
     regs->rbp = current_pcb->mm->stack_start;
 
     uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
-    // pa+= PAGE_2M_SIZE;
-    kdebug("pa1=%#018lx", pa);
-    // 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, PAGE_2M_SIZE, PAGE_USER_PAGE, true, false);
-    // 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);
-    // pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
-    // kdebug("pa2=%#018lx", pa);
-    // // 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);
-
-    // pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
-    // kdebug("pa3=%#018lx", pa);
+
     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);
     // 清空栈空间
@@ -324,7 +307,7 @@ load_elf_failed:;
 ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
 {
 
-    kdebug("do_execve is running...");
+    // kdebug("do_execve is running...");
 
     // 当前进程正在与父进程共享地址空间,需要创建
     // 独立的地址空间才能使新程序正常运行
@@ -389,6 +372,10 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
 
         for (argc = 0; argc < 8 && argv[argc] != NULL; ++argc)
         {
+
+            if (*argv[argc] == NULL)
+                break;
+
             // 测量参数的长度(最大1023)
             int argv_len = strnlen_user(argv[argc], 1023) + 1;
             strncpy((char *)(str_addr - argv_len), argv[argc], argv_len - 1);
@@ -407,7 +394,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;
@@ -671,7 +658,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
     // 拷贝成功
     retval = tsk->pid;
 
-    kdebug("fork done: tsk->pid=%d", tsk->pid);
+    // kdebug("fork done: tsk->pid=%d", tsk->pid);
 
     // kdebug("current_pcb->mm->brk_end=%#018lx", current_pcb->mm->brk_end);
     // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, 0x0000500000000000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
@@ -838,7 +825,7 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
         // 当前页表项为空
         if ((*(uint64_t *)(current_pgd + i)) == 0)
             continue;
-        kdebug("user page [%d]", i);
+
         // 分配新的二级页表
         uint64_t *new_pdpt = (uint64_t *)kmalloc(PAGE_4K_SIZE, 0);
         memset(new_pdpt, 0, PAGE_4K_SIZE);
@@ -847,7 +834,7 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
         set_pml4t(new_pml4t + i, mk_pml4t(virt_2_phys(new_pdpt), (*(current_pgd + i)) & 0xfffUL));
 
         uint64_t *current_pdpt = (uint64_t *)phys_2_virt((*(uint64_t *)(current_pgd + i)) & (~0xfffUL));
-        kdebug("current_pdpt=%#018lx, current_pid=%d", current_pdpt, current_pcb->pid);
+        // kdebug("current_pdpt=%#018lx, current_pid=%d", current_pdpt, current_pcb->pid);
         for (int j = 0; j < 512; ++j)
         {
             if (*(current_pdpt + j) == 0)
@@ -861,7 +848,8 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
             set_pdpt((uint64_t *)(new_pdpt + j), mk_pdpt(virt_2_phys(new_pdt), (*(current_pdpt + j)) & 0xfffUL));
 
             uint64_t *current_pdt = (uint64_t *)phys_2_virt((*(current_pdpt + j)) & (~0xfffUL));
-            kdebug("current_pdt=%#018lx", current_pdt);
+            // kdebug("current_pdt=%#018lx", current_pdt);
+
             // 循环拷贝三级页表
             for (int k = 0; k < 512; ++k)
             {
@@ -878,21 +866,10 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
 
                 // 拷贝数据
                 memcpy(phys_2_virt(pa), phys_2_virt((*(current_pdt + k)) & (~0x1ffUL)), PAGE_2M_SIZE);
-
-                // 计算当前虚拟地址
-                // uint64_t current_vaddr = 0;
-                // current_vaddr = ((1UL * i) << PAGE_GDT_SHIFT) | ((1UL * j) << PAGE_1G_SHIFT) | ((1UL * k) << PAGE_2M_SHIFT);
-
-                // mm_map_proc_page_table((uint64_t)pcb->mm->pgd, true, current_vaddr, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, false);
-
-                // memcpy((void *)phys_2_virt(pa), (void *)current_vaddr, PAGE_2M_SIZE);
             }
         }
-        
     }
 
-   
-
     return retval;
 }
 
@@ -986,13 +963,13 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
     thd->fs = current_pcb->thread->fs;
     thd->gs = current_pcb->thread->gs;
 
-    kdebug("pcb->flags=%ld", pcb->flags);
+    // kdebug("pcb->flags=%ld", pcb->flags);
     // 根据是否为内核线程,设置进程的开始执行的地址
     if (pcb->flags & PF_KTHREAD)
         thd->rip = (uint64_t)kernel_thread_func;
     else
         thd->rip = (uint64_t)ret_from_system_call;
-    kdebug("new proc's ret addr = %#018lx\tthd->rip=%#018lx   stack_start=%#018lx  child_regs->rsp = %#018lx, new_rip=%#018lx)", child_regs->rbx, thd->rip, stack_start, child_regs->rsp, child_regs->rip);
+    // kdebug("new proc's ret addr = %#018lx\tthd->rip=%#018lx   stack_start=%#018lx  child_regs->rsp = %#018lx, new_rip=%#018lx)", child_regs->rbx, thd->rip, stack_start, child_regs->rsp, child_regs->rip);
     return 0;
 }
 

+ 5 - 5
kernel/syscall/syscall.c

@@ -361,7 +361,7 @@ uint64_t sys_lseek(struct pt_regs *regs)
 
 uint64_t sys_fork(struct pt_regs *regs)
 {
-    kdebug("sys_fork");
+    // kdebug("sys_fork");
     return do_fork(regs, 0, regs->rsp, 0);
 }
 uint64_t sys_vfork(struct pt_regs *regs)
@@ -560,13 +560,13 @@ uint64_t sys_getdents(struct pt_regs *regs)
  */
 uint64_t sys_execve(struct pt_regs *regs)
 {
-    kdebug("sys_execve");
+    // kdebug("sys_execve");
     char *user_path = (char *)regs->r8;
     char **argv = (char **)regs->r9;
 
     int path_len = strnlen_user(user_path, PAGE_4K_SIZE);
 
-    kdebug("path_len=%d", path_len);
+    // kdebug("path_len=%d", path_len);
     if (path_len >= PAGE_4K_SIZE)
         return -ENAMETOOLONG;
     else if (path_len <= 0)
@@ -578,12 +578,12 @@ uint64_t sys_execve(struct pt_regs *regs)
 
     memset(path, 0, path_len + 1);
 
-    kdebug("before copy file path from user");
+    // kdebug("before copy file path from user");
     // 拷贝文件路径
     strncpy_from_user(path, user_path, path_len);
     path[path_len] = '\0';
 
-    kdebug("before do_execve, path = %s", path);
+    // kdebug("before do_execve, path = %s", path);
     // 执行新的程序
     uint64_t retval = do_execve(regs, path, argv, NULL);
 

+ 2 - 1
run.sh

@@ -88,10 +88,11 @@ else
   flag_can_run=1
 fi
 
-# 拷贝shell到硬盘
+# 拷贝应用程序到硬盘
 cd tools
 bash m*
 sudo cp ${root_folder}/bin/user/shell.elf ${root_folder}/bin/disk_mount
+sudo cp ${root_folder}/bin/user/about.elf ${root_folder}/bin/disk_mount
 sync
 bash u*
 cd ..

+ 1 - 1
user/apps/Makefile

@@ -1,5 +1,5 @@
 
-user_apps_sub_dirs=shell
+user_apps_sub_dirs=shell about
 
 all:
 	@list='$(user_apps_sub_dirs)'; for subdir in $$list; do \

+ 1 - 1
user/apps/about/Makefile

@@ -1,6 +1,6 @@
 all: about.o
 
-	ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/about  $(shell find . -name "*.o") $(shell find $(sys_libs_dir) -name "*.o") -T shell.lds
+	ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/about  $(shell find . -name "*.o") $(shell find $(sys_libs_dir) -name "*.o") -T about.lds
 
 	objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/about $(output_dir)/about.elf
 about.o: about.c

+ 1 - 0
user/apps/about/about.c

@@ -3,5 +3,6 @@
 int main()
 {
     printf("Hello World!\n");
+    exit(0);
     while(1);
 }

+ 50 - 0
user/apps/about/about.lds

@@ -0,0 +1,50 @@
+
+OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(main)
+
+SECTIONS
+{
+
+	. = 0x800000;
+	
+	
+	.text :
+	{
+		_text = .;
+		
+		*(.text)
+		
+		_etext = .;
+	}
+	. = ALIGN(8);
+	
+	.data :
+	{
+		_data = .;
+		*(.data)
+		
+		_edata = .;
+	}
+
+
+	rodata_start_pa = .;
+	.rodata :
+	{
+		_rodata = .;	
+		*(.rodata)
+		_erodata = .;
+	}
+
+	
+	.bss :
+	{
+		_bss = .;
+		*(.bss)
+		_ebss = .;
+	}
+
+	_end = .;
+
+
+}

+ 5 - 6
user/apps/shell/cmd.c

@@ -369,16 +369,15 @@ int shell_cmd_exec(int argc, char **argv)
 {
     pid_t pid = fork();
     int retval = 0;
-    printf("  pid=%d  \n",pid);
+    // printf("  pid=%d  \n",pid);
 
-    while(1);
     if (pid == 0)
     {
-        printf("child proc\n");
+        // printf("child proc\n");
         // 子进程
         int path_len = 0;
         char *file_path = get_target_filepath(argv[1], &path_len);
-        printf("before execv, path=%s\n", file_path);
+        // printf("before execv, path=%s, argc=%d\n", file_path, argc);
         execv(file_path, argv);
         free(argv);
         while(1);
@@ -387,13 +386,13 @@ int shell_cmd_exec(int argc, char **argv)
     else
     {
         printf("parent process wait for pid:[ %d ]\n", pid);
-        while(1);
+ 
         waitpid(pid, &retval, 0);
         printf("parent process wait pid [ %d ], exit code=%d\n", pid, retval);
         free(argv);
     }
 
-    while(1);
+
 }
 
 /**

+ 1 - 14
user/apps/shell/shell.c

@@ -42,23 +42,10 @@ void main_loop(int kb_fd)
 
     unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
 
-    sbrk(24);
-    // brk(0x700000000000 + (1<<21));
-    pid_t pid = fork();
-    int retval = 0;
-    
-
-    for(int i=0;i<10;++i)
-        printf("  @pid=%d  ", pid);
-    
-    if(pid == 0)
-    {
-        int a = 1/0;
-    }
     // 初始化当前工作目录的路径
     shell_current_path = (char *)malloc(3);
 
-        memset(shell_current_path, 0, 3);
+    memset(shell_current_path, 0, 3);
     shell_current_path[0] = '/';
     shell_current_path[1] = '\0';