]> Zhao Yanbai Git Server - kernel.git/commitdiff
add sysc_wait; rewrite mm/page.c
authorAceVest <zhaoyanbai@126.com>
Sun, 27 Jul 2014 15:36:15 +0000 (23:36 +0800)
committerAceVest <zhaoyanbai@126.com>
Sun, 27 Jul 2014 15:36:15 +0000 (23:36 +0800)
18 files changed:
bin/hello.c
bin/shell.c
include/syscall.h
include/task.h
include/wait.h
kernel/exit.c
kernel/fork.c
kernel/init.c
kernel/innerint.c
kernel/sched.c
kernel/syscall.c
kernel/wait.c
lib/exec.c
lib/exit.c
lib/lib.c
lib/wait.c [new file with mode: 0644]
mm/buddy.c
mm/page.c

index 532fe4bb172204ee69796ebd39267a4cf45d8e90..07043e9d58fa5d32f9251d918e28f410efad26af 100644 (file)
@@ -15,7 +15,6 @@
 int main()
 {
     printf("hello world\n");
-    while(1);
     exit(0);
 
     return 0;
index 1b3d2517f62c3ef6e9e436c3bd05eea7706748bc..3640d9ed5ac80c490dc5f5721b91e81a61884a39 100644 (file)
 
 int systest();
 int sysdebug();
+int pause(unsigned long tick);
 int main()
 {
     int pid = fork();
-
+    if(pid > 0)
+    {
+        int n = 10000000;
+        while(n--);
+        printf("parent\n");
+        while(1)
+        {
+        printf("parent\n");
+            systest();
+            //sysdebug(0x77777777);
+            sysdebug(0x44444444);
+        }
+    }
+    else
+    {
+        printf("child\n");
+        while(1) {
+        printf("child\n");
+            systest();
+            sysdebug(0xAABBCCDD);
+            sysdebug(0x0A0B0C0D);
+        }
+    }
     if(pid > 0)
     {
         printf("prarent child pid %u\n", pid);
+        wait(pid);
+        printf(">prarent child pid %u\n", pid);
         while(1)
         {
             systest();
@@ -31,7 +57,8 @@ int main()
     else if(pid == 0)
     {
         printf("child\n");
-        execv("/bin/hello", 0);
+        //execv("/bin/hello", 0);
+        printf(">child\n");
         while(1)
         {
             systest();
index da40042a8564113c26c11fcc8821a6470472afbd..a1f10673da802a5f031df1f6a352426d11a332ab 100644 (file)
@@ -43,6 +43,7 @@ enum
     SYSC_FORK,
     SYSC_CLONE,
     SYSC_EXEC,
+    SYSC_WAIT,
     SYSC_OPEN,
     SYSC_READ,
     SYSC_STAT,
index 9d59ad9419c72d55117d714e3ab715d08160cca8..5fe509ff5415d2b29e90eb646e6bc9c5b8bc0cf0 100644 (file)
@@ -30,12 +30,17 @@ enum
     TASK_UNUSED,
     TASK_RUNNING,
     TASK_WAIT,
-    TASK_EXEC,
     TASK_EXITING
 };
 
 #define TASK_NAME_SIZE  32
 
+typedef struct wait_queue_head
+{
+    list_head_t task_list;
+} wait_queue_head_t;
+
+
 typedef union task_union
 {
     struct
@@ -62,7 +67,7 @@ typedef union task_union
 
         list_head_t list;
 
-        //pFile        fps[NR_OPENS];
+        wait_queue_head_t wait;
 
         unsigned int cnt;   // debug only
     };
@@ -86,6 +91,7 @@ static inline pid_t sysc_getpid()
     return current->pid;
 }
 
+task_union *find_task(pid_t pid);
 
 #define ROOT_TSK_PID    (0)
 
index fd74d45a580b35137500c6b8f3f706099a83d5b8..ebcc8a29339522d8c8221417ae2c1454b66f4197 100644 (file)
 #pragma once
 
 #include <list.h>
-#include <task.h>
 #include <irq.h>
-
-typedef struct
-{
-    list_head_t task_list;
-} wait_queue_head_t;
+#include <task.h>
 
 typedef struct
 {
index 432ffdda7dfd8cc9f6e3ca05f2001e97bb978075..fc1ce7333f9de17504426c3b3125e0def0016e25 100644 (file)
 
 int sysc_exit(int status)
 {
-
-    //if(current == &RootTsk)
-    //    panic("Root Task is Exiting...");
-
-    /* 先简要实现 */
+    // simple implement.
     current->state = TASK_EXITING;
 
     task_union *t = current;
index 0d5f08f039078ad859a826e18d6ea93a28e55538..ee74d85fdf49f657ad9c8080a7d8aac524c71120 100644 (file)
@@ -35,10 +35,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
 
     //{
         tsk->cr3 = (unsigned long) alloc_one_page(0);
-        if(tsk->cr3 == 0)
-            panic("failed init tsk cr3");
-
-        task_union *t = current;
+        assert(tsk->cr3 != 0);
 
         unsigned int i, j;
         pde_t *pde_src = (pde_t*) current->cr3;
@@ -78,8 +75,6 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
             pte_t *pte_dst = pa2va(PAGE_ALIGN(dpde));
             for(j=0; j< PAGE_PTE_CNT; ++j)
             {
-
-                //printl(20, "[%d %d]", i, j);
                 pte_src[j] &= ~PAGE_WR;
                 pte_dst[j] = pte_src[j];
 
@@ -121,7 +116,6 @@ int do_fork(pt_regs_t *regs, unsigned long flags)
     list_add(&tsk->list, &root_task.list);
     irq_restore(iflags);
 
-
     printk("%s:%d\n", __func__, __LINE__);
     return (int)tsk->pid;
 }
index eb3f6aaef28caf6d48cc7bf01d928819eff555a4..d84bd196f73bfc52339e6c52de253e88e64bc1f5 100644 (file)
@@ -61,6 +61,7 @@ void kernel_task(void *entry)
 void root_task_entry()
 {
 
+    kernel_task(init_task_entry);
     kernel_task(init_task_entry);
     kernel_task(init_task_entry);
     kernel_task(user_task_entry);
index da05f74dbac336a1ccf36e31948badf9b054a7f1..77feb174b8b437145d8b350a601941da7db5f5f9 100644 (file)
@@ -82,38 +82,42 @@ void doGeneralProtection(pt_regs_t regs)
 {
     DIE_MSG();
 }
+
+void do_no_page(void *);
+void do_wp_page(void *);
 void doPageFault(pt_regs_t regs)
 {
+#if 0
+US RW  P - Description
+0  0  0 - Supervisory process tried to read a non-present page entry
+0  0  1 - Supervisory process tried to read a page and caused a protection fault
+0  1  0 - Supervisory process tried to write to a non-present page entry
+0  1  1 - Supervisory process tried to write a page and caused a protection fault
+1  0  0 - User process tried to read a non-present page entry
+1  0  1 - User process tried to read a page and caused a protection fault
+1  1  0 - User process tried to write to a non-present page entry
+1  1  1 - User process tried to write a page and caused a protection fault
+#endif
     //DIE_MSG();
     void    *addr;
     u32    errcode = regs.errcode;
 
     asm("movl %%cr2,%%eax":"=a"(addr));
 
-    unsigned long a = (unsigned long) addr;
-
-    a = 0;
-
-    //printd("do page fault errcode %x addr %08x\n", errcode, addr);
+    printk("do page fault errcode %x addr %08x [%08x]\n", errcode, addr, current);
 
-    if(errcode == 0 || errcode == 2)
-    {
-        unsigned long *pde_src = (unsigned long *) current->cr3;
-        printk("p=%x\n", pde_src[796]);
-        //panic("errcode %08x addr %08x", errcode, addr);
-    }
+    //assert(errcode != 2 && errcode != 6);
 
     if((errcode & PAGE_P) == 0)
     {
-        extern void do_no_page(void *);
         do_no_page(addr);
     }
     else
     {
-        extern void do_wp_page(void *);
         do_wp_page(addr);
     }
 }
+
 void doCoprocError(pt_regs_t regs)
 {
     DIE_MSG();
index cb864b161b98a668d3626bb883166882fd09fad0..d5626e0413d077354b3f96071b6943d297e3dc34 100644 (file)
@@ -124,6 +124,24 @@ inline void context_switch(task_union * prev, task_union * next)
     );
 }
 
+task_union *find_task(pid_t pid)
+{
+    task_union *p = 0;
+    list_head_t *pos = 0, *tmp=0;
+
+    unsigned long iflags;
+    irq_save(iflags);
+    list_for_each_safe(pos, tmp, &root_task.list)
+    {
+        p = list_entry(pos, task_union, list);
+        if(p->pid == pid)
+            break;
+    }
+    irq_restore(iflags);
+
+    return p;
+}
+
 unsigned long schedule()
 {
     static turn = 0;
index 5c658d5613c58cfbd89aec1622b5cfa4b7072253..a864bad6c0b069143b1d7601467316c01e6cb63c 100644 (file)
@@ -23,7 +23,7 @@ extern void init_sysc_handler_table();
 
 unsigned long sysc_handler_table[SYSC_NUM];
 
-void    setup_sysc()
+void setup_sysc()
 {
     wrmsr(MSR_SYSENTER_CS,  SELECTOR_KRNL_CS,   0);
     wrmsr(MSR_SYSENTER_EIP, syscall_entry,      0);
@@ -33,7 +33,7 @@ void    setup_sysc()
 }
 
 
-int    sysc_none()
+int sysc_none()
 {
     int sysc_nr;
     asm("":"=a"(sysc_nr));
@@ -42,7 +42,7 @@ int    sysc_none()
     return 0;
 }
 
-int sysc_pause()
+int sysc_pause(unsigned long tick)
 {
 
     return 0;
@@ -62,7 +62,7 @@ int sysc_debug(unsigned int v)
     printl(MPL_DEBUG, "Task Debug Syscall %u Value %08x", cnt++, v);
 }
 
-void    init_sysc_handler_table()
+void init_sysc_handler_table()
 {
     int i;
     for(i=0; i<SYSC_NUM; i++)
@@ -79,6 +79,7 @@ void    init_sysc_handler_table()
     _sysc_(SYSC_REBOOT,      sysc_reboot);
     _sysc_(SYSC_FORK,        sysc_fork);
     _sysc_(SYSC_EXEC,        sysc_exec);
+    _sysc_(SYSC_WAIT,        sysc_wait);
     _sysc_(SYSC_OPEN,        sysc_open);
     _sysc_(SYSC_READ,        sysc_read);
     _sysc_(SYSC_STAT,        sysc_stat);
index 658ae85f216c9b20c228e2779aae959bbfd6544e..40ac35cfcc4e0d4c9f36e2947ea485cb3e64da98 100644 (file)
@@ -87,3 +87,31 @@ int debug_wait_queue_put(unsigned int v)
     debug_global_var = v;
     wake_up(&debug_wq);
 }
+
+
+int sysc_wait(unsigned long pid)
+{
+    task_union *p = find_task(pid);
+
+    if(p == 0)
+        return 0;
+
+    task_union * task = current;
+    DECLARE_WAIT_QUEUE(wait, task);
+    add_wait_queue(&p->wait, &wait);
+
+    while(true)
+    {
+        task->state = TASK_WAIT;
+        
+        if(p->state == TASK_EXITING)    // no need irq_save
+            break;
+
+        schedule();
+    }
+
+    task->state = TASK_RUNNING;
+    del_wait_queue(&p->wait, &wait);
+
+    return 0;
+}
index 17453b9913cef3716db3917d939534eefcbf94df..208352c59054f72d8c2f207c446acb42800e293b 100644 (file)
@@ -15,14 +15,3 @@ int execv(const char *path, char *const argv[])
 {
     return syscall2(SYSC_EXEC, path, argv);
 }
-
-int systest()
-{
-    return syscall0(SYSC_TEST);
-}
-
-int sysdebug(unsigned int v)
-{
-    //return syscall1(SYSC_DEBUG, v);
-    return syscall1(SYSC_DEBUG, 1);
-}
index 6931fa231734132481d41cd5ae864a43de177125..9887dba83c00d02d24b852f14ec123f802b0cdc3 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <syscall.h>
-int    exit(int status)
+int exit(int status)
 {
     syscall1(SYSC_EXIT, status);
 }
index 7709d20580ab22855918dea2058af7e764f78649..c659370ff9847d1d65dde38491b15214489628b6 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -38,3 +38,18 @@ void poweroff()
 {
     syscall1(SYSC_REBOOT,1);
 }
+
+int systest()
+{
+    return syscall0(SYSC_TEST);
+}
+
+int sysdebug(unsigned int v)
+{
+    return syscall1(SYSC_DEBUG, v);
+}
+
+int pause(unsigned long tick)
+{
+    return syscall1(SYSC_PAUSE, tick);
+}
diff --git a/lib/wait.c b/lib/wait.c
new file mode 100644 (file)
index 0000000..8a9294d
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: wait.c
+ *      Author: Zhao Yanbai
+ *              Sun Jul 27 19:25:38 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <syscall.h>
+int wait(unsigned long pid)
+{
+    syscall1(SYSC_WAIT, pid);
+}
index ca9f5125144d25e6eefee24fe20e3396182609e3..596666f31c533f97f047d46f6170d166fb059c3a 100644 (file)
@@ -13,6 +13,7 @@
 struct buddy_system
 {
     page_t      *page_map;
+    page_t      *page_map_end;
     free_area_t free_area[MAX_ORDER];
 };
 
@@ -29,6 +30,10 @@ int buddy_is_free(page_t *page, unsigned int order)
 page_t *va2page(unsigned long addr)
 {
     page_t *page = buddy_system.page_map + va2pfn(addr);
+
+    assert(page >= buddy_system.page_map);
+    assert(page < buddy_system.page_map_end);
+
     return page;
 }
 
@@ -217,10 +222,12 @@ void init_buddy_system()
         while(1);
     }
 
-    printk("page_map begin %08x end %08x pfncnt %u page_t size %u\n", buddy_system.page_map, buddy_system.page_map + pfn_cnt + 1, pfn_cnt, sizeof(page_t));
+    buddy_system.page_map_end = buddy_system.page_map + pfn_cnt + 1;
+    printk("page_map begin %08x end %08x pfncnt %u page_t size %u\n", buddy_system.page_map, buddy_system.page_map_end, pfn_cnt, sizeof(page_t));
     for(i=0; i<pfn_cnt; ++i)
     {
         page = buddy_system.page_map + i;
+        memset((void *) page, 0, sizeof(page_t));
         page->private = 0;
         page->index   = i;
         INIT_LIST_HEAD(&(page->lru));
index 5b64628296ba8e697096ef060d59b1a9a8cefc08..fa4b16ea9ba17f7aefc84c7b421159ba37e4955e 100644 (file)
--- a/mm/page.c
+++ b/mm/page.c
 
 void do_no_page(void *addr)
 {
-    printk("%s   addr %08x\n", __func__, (unsigned long)addr);
+    //printk("%s   addr %08x\n", __func__, (unsigned long)addr);
+
+#if 1
+    pde_t *page_dir = (pde_t *)current->cr3;
+    pte_t *page_tbl = 0;
+
+    unsigned long page = alloc_one_page(0);
+    assert(page != 0);
+
+    int npde = get_npd(addr);
+    int npte = get_npt(addr);
+
+    if(page_dir[npde] == 0)
+    {
+        page_tbl = (pte_t *) alloc_one_page(0);
+        assert(page_tbl != 0);
+
+        memset((void *) page_tbl, 0, PAGE_SIZE);
+
+        page_dir[npde] = va2pa(page_tbl) | PAGE_P | PAGE_WR | PAGE_US;
+    }
+
+    page_tbl = (pte_t *)pa2va(PAGE_ALIGN(page_dir[npde]));
+    page_tbl[npte] = va2pa(page) | PAGE_P | PAGE_WR | PAGE_US;
+
+    load_cr3(current);
+
+#else
     pde_t *pde = (pde_t *)current->cr3;
     pte_t *pte;
     unsigned long page = alloc_one_page(0);
@@ -46,23 +73,50 @@ void do_no_page(void *addr)
         pte = pa2va(pte);
         pte[npte] = (u32) page | PAGE_P | PAGE_WR | PAGE_US;
     }
-
-    load_cr3(current);
+#endif
 }
 
 
 void do_wp_page(void *addr)
 {
+#if 1
+    int npde = get_npd(addr);
+    int npte = get_npt(addr);
+
+    pde_t *page_dir = (pde_t *)current->cr3;
+    pte_t *page_tbl = pa2va(PAGE_ALIGN(page_dir[npde]));
+
+    unsigned long wp_pa_addr = PAGE_ALIGN(page_tbl[npte]);
+   
+    page_t *page = pa2page(wp_pa_addr);
+
+    if(page->count > 0)
+    {
+        page->count --;
+        unsigned long flags = PAGE_FLAGS(page_tbl[npte]);
+        unsigned long wp_va_addr = (unsigned long) pa2va(wp_pa_addr);
+        unsigned long newtbl = alloc_one_page(0);
+        assert(newtbl != 0);
+
+        memcpy((void *)newtbl, (void *)wp_va_addr, PAGE_SIZE);
+
+        page_tbl[npte] = va2pa(newtbl) | flags;
+    }
+
+    page_tbl[npte] |= PAGE_WR;
+
+    load_cr3(current);
+
+#else
     //printk("%s   addr %08x\n", __func__, (unsigned long)addr);
     int npde = get_npd(addr);
     int npte = get_npt(addr);
 
-    //unsigned long *pd = (u32 *)pa2va(current->cr3);
-    //unsigned long *pd = (u32 *)va2pa(current->cr3);
     unsigned long *pd = (u32 *)(current->cr3);
     unsigned long *pt = NULL;
 
     pt = pa2va(PAGE_ALIGN(pd[npde]));
+    assert(va2pa(pt) != 0);
 
     unsigned long src, dst;
 
@@ -102,4 +156,5 @@ void do_wp_page(void *addr)
     }
 
     load_cr3(current);
+#endif
 }