int main()
{
printf("hello world\n");
- while(1);
exit(0);
return 0;
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();
else if(pid == 0)
{
printf("child\n");
- execv("/bin/hello", 0);
+ //execv("/bin/hello", 0);
+ printf(">child\n");
while(1)
{
systest();
SYSC_FORK,
SYSC_CLONE,
SYSC_EXEC,
+ SYSC_WAIT,
SYSC_OPEN,
SYSC_READ,
SYSC_STAT,
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
list_head_t list;
- //pFile fps[NR_OPENS];
+ wait_queue_head_t wait;
unsigned int cnt; // debug only
};
return current->pid;
}
+task_union *find_task(pid_t pid);
#define ROOT_TSK_PID (0)
#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
{
int sysc_exit(int status)
{
-
- //if(current == &RootTsk)
- // panic("Root Task is Exiting...");
-
- /* 先简要实现 */
+ // simple implement.
current->state = TASK_EXITING;
task_union *t = current;
//{
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;
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];
list_add(&tsk->list, &root_task.list);
irq_restore(iflags);
-
printk("%s:%d\n", __func__, __LINE__);
return (int)tsk->pid;
}
void root_task_entry()
{
+ kernel_task(init_task_entry);
kernel_task(init_task_entry);
kernel_task(init_task_entry);
kernel_task(user_task_entry);
{
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();
);
}
+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;
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);
}
-int sysc_none()
+int sysc_none()
{
int sysc_nr;
asm("":"=a"(sysc_nr));
return 0;
}
-int sysc_pause()
+int sysc_pause(unsigned long tick)
{
return 0;
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++)
_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);
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;
+}
{
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);
-}
*/
#include <syscall.h>
-int exit(int status)
+int exit(int status)
{
syscall1(SYSC_EXIT, status);
}
{
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);
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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);
+}
struct buddy_system
{
page_t *page_map;
+ page_t *page_map_end;
free_area_t free_area[MAX_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;
}
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));
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);
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;
}
load_cr3(current);
+#endif
}