update lab1-8 codes and docs. now version is 0.2

This commit is contained in:
chyyuu 2012-08-26 18:04:26 +08:00
parent 15f7ebf37b
commit d537948e30
134 changed files with 1268 additions and 1005 deletions

26
README
View File

@ -1,8 +1,12 @@
INTRODUCTION
------------
ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University. ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University.
The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License. The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License.
The codes in the files that constitute OS/161 are written by David A. Holland. The codes in the files that constitute OS/161 are written by David A. Holland.
The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License.
--------------------------------------------------------------
CONTENTS
--------
lab1: boot/protect mode/stack/interrupt lab1: boot/protect mode/stack/interrupt
lab2: physical memory management lab2: physical memory management
lab3: virtual memory management lab3: virtual memory management
@ -12,14 +16,34 @@ lab6: scheduling
lab7: mutex/sync lab7: mutex/sync
lab8: filesystem lab8: filesystem
EXERCISE STEPS
--------------
1 $cd labX
2 read codes (specially the modified or added files)
3 add your code
4 compile your code
$make
5 check your code
$make qemu
OR
$make grade
6 handin your code
$make handin
RESOURCE REPOSITORY
-------------------
The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub
LEARNING DISSCUSS GROUPS
------------------------
If you have any questions about ucore labs, If you have any questions about ucore labs,
you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.) you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.)
To post to this group, send email to oscourse@googlegroups.com. To post to this group, send email to oscourse@googlegroups.com.
To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com. To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/oscourse?hl=en. For more options, visit this group at http://groups.google.com/group/oscourse?hl=en.
DEVELOPMENT DISCUSS GROUPS
--------------------------
If you want to be a developer of ucore or pay attention to the development of ucore, If you want to be a developer of ucore or pay attention to the development of ucore,
you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.) you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.)
To post to this group, send email to ucore_dev@googlegroups.com. To post to this group, send email to ucore_dev@googlegroups.com.

View File

@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <trap.h> #include <trap.h>
#include <monitor.h> #include <kmonitor.h>
#include <kdebug.h> #include <kdebug.h>
/* * /* *
@ -78,7 +78,7 @@ runcmd(char *buf, struct trapframe *tf) {
/***** Implementations of basic kernel monitor commands *****/ /***** Implementations of basic kernel monitor commands *****/
void void
monitor(struct trapframe *tf) { kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n"); cprintf("Type 'help' for a list of commands.\n");

View File

@ -3,7 +3,7 @@
#include <trap.h> #include <trap.h>
void monitor(struct trapframe *tf); void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf);

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -8,9 +8,9 @@
#include <clock.h> #include <clock.h>
#include <intr.h> #include <intr.h>
#include <pmm.h> #include <pmm.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -5,7 +5,7 @@
#include <string.h> #include <string.h>
#include <sync.h> #include <sync.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -2,7 +2,7 @@
#include <string.h> #include <string.h>
#include <mmu.h> #include <mmu.h>
#include <trap.h> #include <trap.h>
#include <monitor.h> #include <kmonitor.h>
#include <kdebug.h> #include <kdebug.h>
/* * /* *
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
/***** Implementations of basic kernel monitor commands *****/ /***** Implementations of basic kernel monitor commands *****/
void void
monitor(struct trapframe *tf) { kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n"); cprintf("Type 'help' for a list of commands.\n");

View File

@ -3,7 +3,7 @@
#include <trap.h> #include <trap.h>
void monitor(struct trapframe *tf); void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf);

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -8,9 +8,10 @@
#include <clock.h> #include <clock.h>
#include <intr.h> #include <intr.h>
#include <pmm.h> #include <pmm.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -5,7 +5,7 @@
#include <string.h> #include <string.h>
#include <sync.h> #include <sync.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -2,7 +2,7 @@
#include <string.h> #include <string.h>
#include <mmu.h> #include <mmu.h>
#include <trap.h> #include <trap.h>
#include <monitor.h> #include <kmonitor.h>
#include <kdebug.h> #include <kdebug.h>
/* * /* *
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
/***** Implementations of basic kernel monitor commands *****/ /***** Implementations of basic kernel monitor commands *****/
void void
monitor(struct trapframe *tf) { kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n"); cprintf("Type 'help' for a list of commands.\n");

View File

@ -3,7 +3,7 @@
#include <trap.h> #include <trap.h>
void monitor(struct trapframe *tf); void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf);

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -11,9 +11,10 @@
#include <vmm.h> #include <vmm.h>
#include <ide.h> #include <ide.h>
#include <swap.h> #include <swap.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
cprintf("i %d, swap_out: call swap_out_victim failed\n",i); cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
break; break;
} }
assert(!PageReserved(page)); //assert(!PageReserved(page));
//cprintf("SWAP: choose victim page 0x%08x\n", page); //cprintf("SWAP: choose victim page 0x%08x\n", page);
@ -272,8 +272,8 @@ check_swap(void)
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
count --, total -= p->property; count --, total -= p->property;
} }
cprintf("count is %d, total is %d\n",count,total);
assert(count == 0); //assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

View File

@ -5,7 +5,7 @@
#include <string.h> #include <string.h>
#include <sync.h> #include <sync.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -2,7 +2,7 @@
#include <string.h> #include <string.h>
#include <mmu.h> #include <mmu.h>
#include <trap.h> #include <trap.h>
#include <monitor.h> #include <kmonitor.h>
#include <kdebug.h> #include <kdebug.h>
/* * /* *
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
/***** Implementations of basic kernel monitor commands *****/ /***** Implementations of basic kernel monitor commands *****/
void void
monitor(struct trapframe *tf) { kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n"); cprintf("Type 'help' for a list of commands.\n");

View File

@ -3,7 +3,7 @@
#include <trap.h> #include <trap.h>
void monitor(struct trapframe *tf); void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf);

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -12,9 +12,10 @@
#include <ide.h> #include <ide.h>
#include <swap.h> #include <swap.h>
#include <proc.h> #include <proc.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -482,7 +482,7 @@ check_slab(void) {
void *v0, *v1; void *v0, *v1;
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = slab_allocated(); size_t kernel_allocated_store = slab_allocated();
/* slab must be empty now */ /* slab must be empty now */
check_slab_empty(); check_slab_empty();
@ -628,7 +628,7 @@ check_pass:
check_slab_empty(); check_slab_empty();
assert(slab_allocated() == 0); assert(slab_allocated() == 0);
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == slab_allocated()); assert(kernel_allocated_store == slab_allocated());
cprintf("check_slab() succeeded!\n"); cprintf("check_slab() succeeded!\n");
} }

View File

@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
cprintf("i %d, swap_out: call swap_out_victim failed\n",i); cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
break; break;
} }
assert(!PageReserved(page)); //assert(!PageReserved(page));
//cprintf("SWAP: choose victim page 0x%08x\n", page); //cprintf("SWAP: choose victim page 0x%08x\n", page);
@ -182,7 +182,7 @@ check_swap(void)
list_entry_t *le = &free_list; list_entry_t *le = &free_list;
while ((le = list_next(le)) != &free_list) { while ((le = list_next(le)) != &free_list) {
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
//assert(PageProperty(p)); assert(PageProperty(p));
count ++, total += p->property; count ++, total += p->property;
} }
assert(total == nr_free_pages()); assert(total == nr_free_pages());
@ -272,8 +272,8 @@ check_swap(void)
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
count --, total -= p->property; count --, total -= p->property;
} }
cprintf("count is %d, total is %d\n",count,total);
assert(count == 0); //assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

View File

@ -304,8 +304,11 @@ quick_check() {
## kernel image ## kernel image
osimg=$(make_print ucoreimg) osimg=$(make_print ucoreimg)
## swap image
swapimg=$(make_print swapimg)
## set default qemu-options ## set default qemu-options
qemuopts="-hda $osimg" qemuopts="-hda $osimg -drive file=$swapimg,media=disk,cache=writeback"
## set break-function, default is readline ## set break-function, default is readline
brkfun=readline brkfun=readline
@ -316,7 +319,7 @@ quick_run 'Check VMM'
pts=5 pts=5
quick_check 'check pmm' \ quick_check 'check pmm' \
'memory management: buddy_pmm_manager' \ 'memory management: default_pmm_manager' \
'check_alloc_page() succeeded!' \ 'check_alloc_page() succeeded!' \
'check_pgdir() succeeded!' \ 'check_pgdir() succeeded!' \
'check_boot_pgdir() succeeded!' 'check_boot_pgdir() succeeded!'
@ -340,11 +343,29 @@ quick_check 'check vmm' \
'check_pgfault() succeeded!' \ 'check_pgfault() succeeded!' \
'check_vmm() succeeded.' 'check_vmm() succeeded.'
pts=20
quick_check 'check swap page fault' \
'page fault at 0x00001000: K/W [no page found].' \
'page fault at 0x00002000: K/W [no page found].' \
'page fault at 0x00003000: K/W [no page found].' \
'page fault at 0x00004000: K/W [no page found].' \
'write Virt Page e in fifo_check_swap' \
'page fault at 0x00005000: K/W [no page found].' \
'page fault at 0x00001000: K/W [no page found]' \
'page fault at 0x00002000: K/W [no page found].' \
'page fault at 0x00003000: K/W [no page found].' \
'page fault at 0x00004000: K/W [no page found].' \
'check_swap() succeeded!'
pts=5 pts=5
quick_check 'check ticks' \ quick_check 'check ticks' \
'++ setup timer interrupts' \ '++ setup timer interrupts'
'100 ticks' \
'End of Test.' pts=30
quick_check 'check initproc' \
'this initproc, pid = 1, name = "init"' \
'To U: "Hello world!!".' \
'To U: "en.., Bye, Bye. :)"'
## print final-score ## print final-score
show_final show_final

View File

@ -8,7 +8,7 @@
#include <vmm.h> #include <vmm.h>
#include <proc.h> #include <proc.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -2,7 +2,7 @@
#include <string.h> #include <string.h>
#include <mmu.h> #include <mmu.h>
#include <trap.h> #include <trap.h>
#include <monitor.h> #include <kmonitor.h>
#include <kdebug.h> #include <kdebug.h>
/* * /* *
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
/***** Implementations of basic kernel monitor commands *****/ /***** Implementations of basic kernel monitor commands *****/
void void
monitor(struct trapframe *tf) { kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n"); cprintf("Type 'help' for a list of commands.\n");

View File

@ -3,7 +3,7 @@
#include <trap.h> #include <trap.h>
void monitor(struct trapframe *tf); void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf);

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -12,9 +12,10 @@
#include <ide.h> #include <ide.h>
#include <swap.h> #include <swap.h>
#include <proc.h> #include <proc.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -487,7 +487,7 @@ check_slab(void) {
void *v0, *v1; void *v0, *v1;
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = slab_allocated(); size_t kernel_allocated_store = slab_allocated();
/* slab must be empty now */ /* slab must be empty now */
check_slab_empty(); check_slab_empty();
@ -633,7 +633,7 @@ check_pass:
check_slab_empty(); check_slab_empty();
assert(slab_allocated() == 0); assert(slab_allocated() == 0);
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == slab_allocated()); assert(kernel_allocated_store == slab_allocated());
cprintf("check_slab() succeeded!\n"); cprintf("check_slab() succeeded!\n");
} }

View File

@ -184,7 +184,7 @@ check_swap(void)
list_entry_t *le = &free_list; list_entry_t *le = &free_list;
while ((le = list_next(le)) != &free_list) { while ((le = list_next(le)) != &free_list) {
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
//assert(PageProperty(p)); assert(PageProperty(p));
count ++, total += p->property; count ++, total += p->property;
} }
assert(total == nr_free_pages()); assert(total == nr_free_pages());

View File

@ -459,6 +459,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
* find the addr of disk page, read the content of disk page into this memroy page * find the addr of disk page, read the content of disk page into this memroy page
* page_insert build the map of phy addr of an Page with the linear addr la * page_insert build the map of phy addr of an Page with the linear addr la
* swap_map_swappable set the page swappable * swap_map_swappable set the page swappable
*/
/*
* LAB5 CHALLENGE ( the implmentation Copy on Write)
There are 2 situlations when code comes here.
1) *ptep & PTE_P == 1, it means one process try to write a readonly page.
If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry.
We should add the LAB3's results here.
*/ */
if(swap_init_ok) { if(swap_init_ok) {
struct Page *page=NULL; struct Page *page=NULL;

View File

@ -103,6 +103,12 @@ alloc_proc(void) {
* uint32_t flags; // Process flag * uint32_t flags; // Process flag
* char name[PROC_NAME_LEN + 1]; // Process name * char name[PROC_NAME_LEN + 1]; // Process name
*/ */
//LAB5 YOUR CODE : (update LAB4 steps)
/*
* below fields(add in LAB5) in proc_struct need to be initialized
* uint32_t wait_state; // waiting state
* struct proc_struct *cptr, *yptr, *optr; // relations between processes
*/
} }
return proc; return proc;
} }
@ -389,6 +395,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
// 5. insert proc_struct into hash_list && proc_list // 5. insert proc_struct into hash_list && proc_list
// 6. call wakup_proc to make the new child process RUNNABLE // 6. call wakup_proc to make the new child process RUNNABLE
// 7. set ret vaule using child proc's pid // 7. set ret vaule using child proc's pid
//LAB5 YOUR CODE : (update LAB4 steps)
/* Some Functions
* set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process
* -------------------
* update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
* update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
*/
fork_out: fork_out:
return ret; return ret;
@ -771,7 +786,7 @@ user_main(void *arg) {
static int static int
init_main(void *arg) { init_main(void *arg) {
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = kallocated(); size_t kernel_allocated_store = kallocated();
int pid = kernel_thread(user_main, NULL, 0); int pid = kernel_thread(user_main, NULL, 0);
if (pid <= 0) { if (pid <= 0) {
@ -788,7 +803,7 @@ init_main(void *arg) {
assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_next(&proc_list) == &(initproc->list_link));
assert(list_prev(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link));
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == kallocated()); assert(kernel_allocated_store == kallocated());
cprintf("init check memory pass.\n"); cprintf("init check memory pass.\n");
return 0; return 0;
} }

View File

@ -210,7 +210,7 @@ trap_dispatch(struct trapframe *tf) {
break; break;
case IRQ_OFFSET + IRQ_TIMER: case IRQ_OFFSET + IRQ_TIMER:
#if 0 #if 0
LAB3 : If some page replacement algorithm need tick to change the priority of pages, LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
then you can add code here. then you can add code here.
#endif #endif
/* LAB1 YOUR CODE : STEP 3 */ /* LAB1 YOUR CODE : STEP 3 */

View File

@ -512,6 +512,45 @@ run_test -prog 'forktest' -check default_check
! 'wait got too many' \ ! 'wait got too many' \
! - 'user panic at .*' ! - 'user panic at .*'
pts=10
run_test -prog 'forktree' -check default_check \
'kernel_execve: pid = 2, name = "forktree".' \
- '....: I am '\'''\' \
- '....: I am '\''0'\' \
- '....: I am '\'''\' \
- '....: I am '\''1'\' \
- '....: I am '\''0'\' \
- '....: I am '\''01'\' \
- '....: I am '\''00'\' \
- '....: I am '\''11'\' \
- '....: I am '\''10'\' \
- '....: I am '\''101'\' \
- '....: I am '\''100'\' \
- '....: I am '\''111'\' \
- '....: I am '\''110'\' \
- '....: I am '\''001'\' \
- '....: I am '\''000'\' \
- '....: I am '\''011'\' \
- '....: I am '\''010'\' \
- '....: I am '\''0101'\' \
- '....: I am '\''0100'\' \
- '....: I am '\''0111'\' \
- '....: I am '\''0110'\' \
- '....: I am '\''0001'\' \
- '....: I am '\''0000'\' \
- '....: I am '\''0011'\' \
- '....: I am '\''0010'\' \
- '....: I am '\''1101'\' \
- '....: I am '\''1100'\' \
- '....: I am '\''1111'\' \
- '....: I am '\''1110'\' \
- '....: I am '\''1001'\' \
- '....: I am '\''1000'\' \
- '....: I am '\''1011'\' \
- '....: I am '\''1010'\' \
'all user-mode processes have quit.' \
'init check memory pass.'
## print final-score ## print final-score
show_final show_final

View File

@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define DEPTH 2 #define DEPTH 4
void forktree(const char *cur); void forktree(const char *cur);

View File

@ -8,7 +8,7 @@
#include <vmm.h> #include <vmm.h>
#include <proc.h> #include <proc.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <kmonitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -0,0 +1,19 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,132 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <monitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
monitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -1,19 +0,0 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void monitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -12,9 +12,10 @@
#include <ide.h> #include <ide.h>
#include <swap.h> #include <swap.h>
#include <proc.h> #include <proc.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -487,7 +487,7 @@ check_slab(void) {
void *v0, *v1; void *v0, *v1;
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = slab_allocated(); size_t kernel_allocated_store = slab_allocated();
/* slab must be empty now */ /* slab must be empty now */
check_slab_empty(); check_slab_empty();
@ -633,7 +633,7 @@ check_pass:
check_slab_empty(); check_slab_empty();
assert(slab_allocated() == 0); assert(slab_allocated() == 0);
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == slab_allocated()); assert(kernel_allocated_store == slab_allocated());
cprintf("check_slab() succeeded!\n"); cprintf("check_slab() succeeded!\n");
} }

View File

@ -184,7 +184,7 @@ check_swap(void)
list_entry_t *le = &free_list; list_entry_t *le = &free_list;
while ((le = list_next(le)) != &free_list) { while ((le = list_next(le)) != &free_list) {
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
//assert(PageProperty(p)); assert(PageProperty(p));
count ++, total += p->property; count ++, total += p->property;
} }
assert(total == nr_free_pages()); assert(total == nr_free_pages());

View File

@ -459,6 +459,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
* find the addr of disk page, read the content of disk page into this memroy page * find the addr of disk page, read the content of disk page into this memroy page
* page_insert build the map of phy addr of an Page with the linear addr la * page_insert build the map of phy addr of an Page with the linear addr la
* swap_map_swappable set the page swappable * swap_map_swappable set the page swappable
*/
/*
* LAB5 CHALLENGE ( the implmentation Copy on Write)
There are 2 situlations when code comes here.
1) *ptep & PTE_P == 1, it means one process try to write a readonly page.
If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry.
We should add the LAB3's results here.
*/ */
if(swap_init_ok) { if(swap_init_ok) {
struct Page *page=NULL; struct Page *page=NULL;

View File

@ -103,6 +103,22 @@ alloc_proc(void) {
* uint32_t flags; // Process flag * uint32_t flags; // Process flag
* char name[PROC_NAME_LEN + 1]; // Process name * char name[PROC_NAME_LEN + 1]; // Process name
*/ */
//LAB5 YOUR CODE : (update LAB4 steps)
/*
* below fields(add in LAB5) in proc_struct need to be initialized
* uint32_t wait_state; // waiting state
* struct proc_struct *cptr, *yptr, *optr; // relations between processes
*/
//LAB6 YOUR CODE : (update LAB5 steps)
/*
* below fields(add in LAB6) in proc_struct need to be initialized
* struct run_queue *rq; // running queue contains Process
* list_entry_t run_link; // the entry linked in run queue
* int time_slice; // time slice for occupying the CPU
* skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool
* uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process
* uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t)
*/
} }
return proc; return proc;
} }
@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
// 5. insert proc_struct into hash_list && proc_list // 5. insert proc_struct into hash_list && proc_list
// 6. call wakup_proc to make the new child process RUNNABLE // 6. call wakup_proc to make the new child process RUNNABLE
// 7. set ret vaule using child proc's pid // 7. set ret vaule using child proc's pid
//LAB5 YOUR CODE : (update LAB4 steps)
/* Some Functions
* set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process
* -------------------
* update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
* update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
*/
fork_out: fork_out:
return ret; return ret;
@ -771,7 +796,7 @@ user_main(void *arg) {
static int static int
init_main(void *arg) { init_main(void *arg) {
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = kallocated(); size_t kernel_allocated_store = kallocated();
int pid = kernel_thread(user_main, NULL, 0); int pid = kernel_thread(user_main, NULL, 0);
if (pid <= 0) { if (pid <= 0) {
@ -788,7 +813,7 @@ init_main(void *arg) {
assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_next(&proc_list) == &(initproc->list_link));
assert(list_prev(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link));
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == kallocated()); assert(kernel_allocated_store == kallocated());
cprintf("init check memory pass.\n"); cprintf("init check memory pass.\n");
return 0; return 0;
} }

View File

@ -6,6 +6,7 @@
#include <assert.h> #include <assert.h>
#include <default_sched.h> #include <default_sched.h>
// the list of timer
static list_entry_t timer_list; static list_entry_t timer_list;
static struct sched_class *sched_class; static struct sched_class *sched_class;
@ -48,7 +49,7 @@ sched_init(void) {
sched_class = &default_sched_class; sched_class = &default_sched_class;
rq = &__rq; rq = &__rq;
rq->max_time_slice = 20; rq->max_time_slice = MAX_TIME_SLICE;
sched_class->init(rq); sched_class->init(rq);
cprintf("sched class: %s\n", sched_class->name); cprintf("sched class: %s\n", sched_class->name);
@ -98,6 +99,7 @@ schedule(void) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// add timer to timer_list
void void
add_timer(timer_t *timer) { add_timer(timer_t *timer) {
bool intr_flag; bool intr_flag;
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// del timer from timer_list
void void
del_timer(timer_t *timer) { del_timer(timer_t *timer) {
bool intr_flag; bool intr_flag;
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
void void
run_timer_list(void) { run_timer_list(void) {
bool intr_flag; bool intr_flag;

View File

@ -5,17 +5,20 @@
#include <list.h> #include <list.h>
#include <skew_heap.h> #include <skew_heap.h>
#define MAX_TIME_SLICE 20
struct proc_struct; struct proc_struct;
typedef struct { typedef struct {
unsigned int expires; unsigned int expires; //the expire time
struct proc_struct *proc; struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
list_entry_t timer_link; list_entry_t timer_link; //the timer list
} timer_t; } timer_t;
#define le2timer(le, member) \ #define le2timer(le, member) \
to_struct((le), timer_t, member) to_struct((le), timer_t, member)
// init a timer
static inline timer_t * static inline timer_t *
timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
timer->expires = expires; timer->expires = expires;
@ -62,9 +65,9 @@ struct run_queue {
void sched_init(void); void sched_init(void);
void wakeup_proc(struct proc_struct *proc); void wakeup_proc(struct proc_struct *proc);
void schedule(void); void schedule(void);
void add_timer(timer_t *timer); void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); void del_timer(timer_t *timer); // del timer from timer_list
void run_timer_list(void); void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
#endif /* !__KERN_SCHEDULE_SCHED_H__ */ #endif /* !__KERN_SCHEDULE_SCHED_H__ */

View File

@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
return 0; return 0;
} }
static uint32_t static int
sys_gettime(uint32_t arg[]) { sys_gettime(uint32_t arg[]) {
return (int)ticks; return (int)ticks;
} }
static uint32_t static int
sys_lab6_set_priority(uint32_t arg[]) sys_lab6_set_priority(uint32_t arg[])
{ {
uint32_t priority = (uint32_t)arg[0]; uint32_t priority = (uint32_t)arg[0];

View File

@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
break; break;
case IRQ_OFFSET + IRQ_TIMER: case IRQ_OFFSET + IRQ_TIMER:
#if 0 #if 0
LAB3 : If some page replacement algorithm need tick to change the priority of pages, LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
then you can add code here. then you can add code here.
#endif #endif
/* LAB1 YOUR CODE : STEP 3 */ /* LAB1 YOUR CODE : STEP 3 */
@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) {
/* you should upate you lab1 code (just add ONE or TWO lines of code): /* you should upate you lab1 code (just add ONE or TWO lines of code):
* Every TICK_NUM cycle, you should set current process's current->need_resched = 1 * Every TICK_NUM cycle, you should set current process's current->need_resched = 1
*/ */
/* LAB6 YOUR CODE */
/* IMPORTANT FUNCTIONS:
* run_timer_list
*----------------------
* you should update your lab5 code (just add ONE or TWO lines of code):
* Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
* You can use one funcitons to finish all these things.
*/
break; break;
case IRQ_OFFSET + IRQ_COM1: case IRQ_OFFSET + IRQ_COM1:
c = cons_getc(); c = cons_getc();

View File

@ -70,7 +70,7 @@ sys_pgdir(void) {
return syscall(SYS_pgdir); return syscall(SYS_pgdir);
} }
size_t int
sys_gettime(void) { sys_gettime(void) {
return syscall(SYS_gettime); return syscall(SYS_gettime);
} }

View File

@ -9,6 +9,7 @@ int sys_kill(int pid);
int sys_getpid(void); int sys_getpid(void);
int sys_putc(int c); int sys_putc(int c);
int sys_pgdir(void); int sys_pgdir(void);
int sys_gettime(void);
/* FOR LAB6 ONLY */ /* FOR LAB6 ONLY */
void sys_lab6_set_priority(uint32_t priority); void sys_lab6_set_priority(uint32_t priority);

View File

@ -8,7 +8,7 @@
#include <vmm.h> #include <vmm.h>
#include <proc.h> #include <proc.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <kmonitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -0,0 +1,19 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,132 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <monitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
monitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -1,19 +0,0 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void monitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

View File

@ -12,9 +12,10 @@
#include <ide.h> #include <ide.h>
#include <swap.h> #include <swap.h>
#include <proc.h> #include <proc.h>
#include <kmonitor.h>
int kern_init(void) __attribute__((noreturn)); int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void); static void lab1_switch_test(void);
int int

View File

@ -487,7 +487,7 @@ check_slab(void) {
void *v0, *v1; void *v0, *v1;
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = slab_allocated(); size_t kernel_allocated_store = slab_allocated();
/* slab must be empty now */ /* slab must be empty now */
check_slab_empty(); check_slab_empty();
@ -633,7 +633,7 @@ check_pass:
check_slab_empty(); check_slab_empty();
assert(slab_allocated() == 0); assert(slab_allocated() == 0);
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == slab_allocated()); assert(kernel_allocated_store == slab_allocated());
cprintf("check_slab() succeeded!\n"); cprintf("check_slab() succeeded!\n");
} }

View File

@ -184,7 +184,7 @@ check_swap(void)
list_entry_t *le = &free_list; list_entry_t *le = &free_list;
while ((le = list_next(le)) != &free_list) { while ((le = list_next(le)) != &free_list) {
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
//assert(PageProperty(p)); assert(PageProperty(p));
count ++, total += p->property; count ++, total += p->property;
} }
assert(total == nr_free_pages()); assert(total == nr_free_pages());

View File

@ -459,6 +459,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
* find the addr of disk page, read the content of disk page into this memroy page * find the addr of disk page, read the content of disk page into this memroy page
* page_insert build the map of phy addr of an Page with the linear addr la * page_insert build the map of phy addr of an Page with the linear addr la
* swap_map_swappable set the page swappable * swap_map_swappable set the page swappable
*/
/*
* LAB5 CHALLENGE ( the implmentation Copy on Write)
There are 2 situlations when code comes here.
1) *ptep & PTE_P == 1, it means one process try to write a readonly page.
If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry.
We should add the LAB3's results here.
*/ */
if(swap_init_ok) { if(swap_init_ok) {
struct Page *page=NULL; struct Page *page=NULL;

View File

@ -103,6 +103,22 @@ alloc_proc(void) {
* uint32_t flags; // Process flag * uint32_t flags; // Process flag
* char name[PROC_NAME_LEN + 1]; // Process name * char name[PROC_NAME_LEN + 1]; // Process name
*/ */
//LAB5 YOUR CODE : (update LAB4 steps)
/*
* below fields(add in LAB5) in proc_struct need to be initialized
* uint32_t wait_state; // waiting state
* struct proc_struct *cptr, *yptr, *optr; // relations between processes
*/
//LAB6 YOUR CODE : (update LAB5 steps)
/*
* below fields(add in LAB6) in proc_struct need to be initialized
* struct run_queue *rq; // running queue contains Process
* list_entry_t run_link; // the entry linked in run queue
* int time_slice; // time slice for occupying the CPU
* skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool
* uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process
* uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t)
*/
} }
return proc; return proc;
} }
@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
// 5. insert proc_struct into hash_list && proc_list // 5. insert proc_struct into hash_list && proc_list
// 6. call wakup_proc to make the new child process RUNNABLE // 6. call wakup_proc to make the new child process RUNNABLE
// 7. set ret vaule using child proc's pid // 7. set ret vaule using child proc's pid
//LAB5 YOUR CODE : (update LAB4 steps)
/* Some Functions
* set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process
* -------------------
* update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
* update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
*/
fork_out: fork_out:
return ret; return ret;
@ -771,7 +796,7 @@ user_main(void *arg) {
static int static int
init_main(void *arg) { init_main(void *arg) {
size_t nr_free_pages_store = nr_free_pages(); size_t nr_free_pages_store = nr_free_pages();
size_t slab_allocated_store = kallocated(); size_t kernel_allocated_store = kallocated();
int pid = kernel_thread(user_main, NULL, 0); int pid = kernel_thread(user_main, NULL, 0);
if (pid <= 0) { if (pid <= 0) {
@ -790,7 +815,7 @@ init_main(void *arg) {
assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_next(&proc_list) == &(initproc->list_link));
assert(list_prev(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link));
assert(nr_free_pages_store == nr_free_pages()); assert(nr_free_pages_store == nr_free_pages());
assert(slab_allocated_store == kallocated()); assert(kernel_allocated_store == kallocated());
cprintf("init check memory pass.\n"); cprintf("init check memory pass.\n");
return 0; return 0;
} }

View File

@ -6,6 +6,7 @@
#include <assert.h> #include <assert.h>
#include <default_sched.h> #include <default_sched.h>
// the list of timer
static list_entry_t timer_list; static list_entry_t timer_list;
static struct sched_class *sched_class; static struct sched_class *sched_class;
@ -98,6 +99,7 @@ schedule(void) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// add timer to timer_list
void void
add_timer(timer_t *timer) { add_timer(timer_t *timer) {
bool intr_flag; bool intr_flag;
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// del timer from timer_list
void void
del_timer(timer_t *timer) { del_timer(timer_t *timer) {
bool intr_flag; bool intr_flag;
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
local_intr_restore(intr_flag); local_intr_restore(intr_flag);
} }
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
void void
run_timer_list(void) { run_timer_list(void) {
bool intr_flag; bool intr_flag;

View File

@ -5,17 +5,20 @@
#include <list.h> #include <list.h>
#include <skew_heap.h> #include <skew_heap.h>
#define MAX_TIME_SLICE 20
struct proc_struct; struct proc_struct;
typedef struct { typedef struct {
unsigned int expires; unsigned int expires; //the expire time
struct proc_struct *proc; struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
list_entry_t timer_link; list_entry_t timer_link; //the timer list
} timer_t; } timer_t;
#define le2timer(le, member) \ #define le2timer(le, member) \
to_struct((le), timer_t, member) to_struct((le), timer_t, member)
// init a timer
static inline timer_t * static inline timer_t *
timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
timer->expires = expires; timer->expires = expires;
@ -62,9 +65,9 @@ struct run_queue {
void sched_init(void); void sched_init(void);
void wakeup_proc(struct proc_struct *proc); void wakeup_proc(struct proc_struct *proc);
void schedule(void); void schedule(void);
void add_timer(timer_t *timer); void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); void del_timer(timer_t *timer); // del timer from timer_list
void run_timer_list(void); void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
#endif /* !__KERN_SCHEDULE_SCHED_H__ */ #endif /* !__KERN_SCHEDULE_SCHED_H__ */

View File

@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
return 0; return 0;
} }
static uint32_t static int
sys_gettime(uint32_t arg[]) { sys_gettime(uint32_t arg[]) {
return (int)ticks; return (int)ticks;
} }
static uint32_t static int
sys_lab6_set_priority(uint32_t arg[]) sys_lab6_set_priority(uint32_t arg[])
{ {
uint32_t priority = (uint32_t)arg[0]; uint32_t priority = (uint32_t)arg[0];

View File

@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
break; break;
case IRQ_OFFSET + IRQ_TIMER: case IRQ_OFFSET + IRQ_TIMER:
#if 0 #if 0
LAB3 : If some page replacement algorithm need tick to change the priority of pages, LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
then you can add code here. then you can add code here.
#endif #endif
/* LAB1 YOUR CODE : STEP 3 */ /* LAB1 YOUR CODE : STEP 3 */
@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) {
/* you should upate you lab1 code (just add ONE or TWO lines of code): /* you should upate you lab1 code (just add ONE or TWO lines of code):
* Every TICK_NUM cycle, you should set current process's current->need_resched = 1 * Every TICK_NUM cycle, you should set current process's current->need_resched = 1
*/ */
/* LAB6 YOUR CODE */
/* IMPORTANT FUNCTIONS:
* run_timer_list
*----------------------
* you should update your lab5 code (just add ONE or TWO lines of code):
* Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
* You can use one funcitons to finish all these things.
*/
break; break;
case IRQ_OFFSET + IRQ_COM1: case IRQ_OFFSET + IRQ_COM1:
c = cons_getc(); c = cons_getc();

View File

@ -3,7 +3,7 @@
#include <string.h> #include <string.h>
#define DEPTH 4 #define DEPTH 4
#define SLEEP_TIME 400
void forktree(const char *cur); void forktree(const char *cur);
void void
@ -31,8 +31,6 @@ forktree(const char *cur) {
int int
main(void) { main(void) {
cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME);
sleep(SLEEP_TIME);
forktree(""); forktree("");
return 0; return 0;
} }

View File

@ -70,7 +70,7 @@ sys_pgdir(void) {
return syscall(SYS_pgdir); return syscall(SYS_pgdir);
} }
size_t int
sys_gettime(void) { sys_gettime(void) {
return syscall(SYS_gettime); return syscall(SYS_gettime);
} }

View File

@ -9,6 +9,7 @@ int sys_kill(int pid);
int sys_getpid(void); int sys_getpid(void);
int sys_putc(int c); int sys_putc(int c);
int sys_pgdir(void); int sys_pgdir(void);
int sys_gettime(void);
/* FOR LAB6 ONLY */ /* FOR LAB6 ONLY */
void sys_lab6_set_priority(uint32_t priority); void sys_lab6_set_priority(uint32_t priority);

View File

@ -3,7 +3,7 @@
int int
main(void) { main(void) {
int pid, ret, i ,j; int pid, ret;
cprintf("I am the parent. Forking the child...\n"); cprintf("I am the parent. Forking the child...\n");
pid = fork(); pid = fork();
if (pid== 0) { if (pid== 0) {

View File

@ -8,7 +8,7 @@
#include <vmm.h> #include <vmm.h>
#include <proc.h> #include <proc.h>
#include <kdebug.h> #include <kdebug.h>
#include <monitor.h> #include <kmonitor.h>
#include <assert.h> #include <assert.h>
#define STACKFRAME_DEPTH 20 #define STACKFRAME_DEPTH 20

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <kmonitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
kmonitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -0,0 +1,19 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void kmonitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,132 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <mmu.h>
#include <trap.h>
#include <monitor.h>
#include <kdebug.h>
/* *
* Simple command-line kernel monitor useful for controlling the
* kernel and exploring the system interactively.
* */
struct command {
const char *name;
const char *desc;
// return -1 to force monitor to exit
int(*func)(int argc, char **argv, struct trapframe *tf);
};
static struct command commands[] = {
{"help", "Display this list of commands.", mon_help},
{"kerninfo", "Display information about the kernel.", mon_kerninfo},
{"backtrace", "Print backtrace of stack frame.", mon_backtrace},
};
/* return if kernel is panic, in kern/debug/panic.c */
bool is_kernel_panic(void);
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
/***** Kernel monitor command interpreter *****/
#define MAXARGS 16
#define WHITESPACE " \t\n\r"
/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
int argc = 0;
while (1) {
// find global whitespace
while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
*buf ++ = '\0';
}
if (*buf == '\0') {
break;
}
// save and scan past next arg
if (argc == MAXARGS - 1) {
cprintf("Too many arguments (max %d).\n", MAXARGS);
}
argv[argc ++] = buf;
while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
buf ++;
}
}
return argc;
}
/* *
* runcmd - parse the input string, split it into separated arguments
* and then lookup and invoke some related commands/
* */
static int
runcmd(char *buf, struct trapframe *tf) {
char *argv[MAXARGS];
int argc = parse(buf, argv);
if (argc == 0) {
return 0;
}
int i;
for (i = 0; i < NCOMMANDS; i ++) {
if (strcmp(commands[i].name, argv[0]) == 0) {
return commands[i].func(argc - 1, argv + 1, tf);
}
}
cprintf("Unknown command '%s'\n", argv[0]);
return 0;
}
/***** Implementations of basic kernel monitor commands *****/
void
monitor(struct trapframe *tf) {
cprintf("Welcome to the kernel debug monitor!!\n");
cprintf("Type 'help' for a list of commands.\n");
if (tf != NULL) {
print_trapframe(tf);
}
char *buf;
while (1) {
if ((buf = readline("K> ")) != NULL) {
if (runcmd(buf, tf) < 0) {
break;
}
}
}
}
/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
int i;
for (i = 0; i < NCOMMANDS; i ++) {
cprintf("%s - %s\n", commands[i].name, commands[i].desc);
}
return 0;
}
/* *
* mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
* print the memory occupancy in kernel.
* */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
print_kerninfo();
return 0;
}
/* *
* mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
* print a backtrace of the stack.
* */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
print_stackframe();
return 0;
}

View File

@ -1,19 +0,0 @@
#ifndef __KERN_DEBUG_MONITOR_H__
#define __KERN_DEBUG_MONITOR_H__
#include <trap.h>
void monitor(struct trapframe *tf);
int mon_help(int argc, char **argv, struct trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
int mon_continue(int argc, char **argv, struct trapframe *tf);
int mon_step(int argc, char **argv, struct trapframe *tf);
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
#endif /* !__KERN_DEBUG_MONITOR_H__ */

View File

@ -1,7 +1,7 @@
#include <defs.h> #include <defs.h>
#include <stdio.h> #include <stdio.h>
#include <intr.h> #include <intr.h>
#include <monitor.h> #include <kmonitor.h>
static bool is_panic = 0; static bool is_panic = 0;
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
panic_dead: panic_dead:
intr_disable(); intr_disable();
while (1) { while (1) {
monitor(NULL); kmonitor(NULL);
} }
} }

0
code/lab8/kern/fs/devs/dev.c Normal file → Executable file
View File

0
code/lab8/kern/fs/devs/dev.h Normal file → Executable file
View File

0
code/lab8/kern/fs/devs/dev_disk0.c Normal file → Executable file
View File

0
code/lab8/kern/fs/devs/dev_stdin.c Normal file → Executable file
View File

0
code/lab8/kern/fs/devs/dev_stdout.c Normal file → Executable file
View File

0
code/lab8/kern/fs/file.c Normal file → Executable file
View File

0
code/lab8/kern/fs/file.h Normal file → Executable file
View File

2
code/lab8/kern/fs/fs.c Normal file → Executable file
View File

@ -78,7 +78,7 @@ files_closeall(struct files_struct *filesp) {
} }
int int
dup_fs(struct files_struct *to, struct files_struct *from) { dup_files(struct files_struct *to, struct files_struct *from) {
// cprintf("[dup_fs]\n"); // cprintf("[dup_fs]\n");
assert(to != NULL && from != NULL); assert(to != NULL && from != NULL);
assert(files_count(to) == 0 && files_count(from) > 0); assert(files_count(to) == 0 && files_count(from) > 0);

0
code/lab8/kern/fs/fs.h Normal file → Executable file
View File

0
code/lab8/kern/fs/iobuf.c Normal file → Executable file
View File

0
code/lab8/kern/fs/iobuf.h Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/bitmap.c Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/bitmap.h Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs.c Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs.h Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs_fs.c Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs_inode.c Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs_io.c Normal file → Executable file
View File

0
code/lab8/kern/fs/sfs/sfs_lock.c Normal file → Executable file
View File

0
code/lab8/kern/fs/swap/swapfs.c Normal file → Executable file
View File

0
code/lab8/kern/fs/swap/swapfs.h Normal file → Executable file
View File

0
code/lab8/kern/fs/sysfile.c Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More