update lab1-8 codes and docs. now version is 0.2
This commit is contained in:
		
							parent
							
								
									15f7ebf37b
								
							
						
					
					
						commit
						d537948e30
					
				
							
								
								
									
										26
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README
									
									
									
									
									
								
							@ -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.
 | 
			
		||||
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 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
 | 
			
		||||
lab2: physical memory management
 | 
			
		||||
lab3: virtual memory management
 | 
			
		||||
@ -12,14 +16,34 @@ lab6: scheduling
 | 
			
		||||
lab7: mutex/sync
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
LEARNING DISSCUSS GROUPS
 | 
			
		||||
------------------------
 | 
			
		||||
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.)
 | 
			
		||||
To post to this group, send email to oscourse@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.
 | 
			
		||||
 | 
			
		||||
DEVELOPMENT DISCUSS GROUPS
 | 
			
		||||
--------------------------
 | 
			
		||||
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.)
 | 
			
		||||
To post to this group, send email to ucore_dev@googlegroups.com.
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <trap.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
 | 
			
		||||
/* *
 | 
			
		||||
@ -78,7 +78,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
			
		||||
/***** Implementations of basic kernel monitor commands *****/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
monitor(struct trapframe *tf) {
 | 
			
		||||
kmonitor(struct trapframe *tf) {
 | 
			
		||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
			
		||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#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_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,9 @@
 | 
			
		||||
#include <clock.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <pmm.h>
 | 
			
		||||
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sync.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <mmu.h>
 | 
			
		||||
#include <trap.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
 | 
			
		||||
/* *
 | 
			
		||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
			
		||||
/***** Implementations of basic kernel monitor commands *****/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
monitor(struct trapframe *tf) {
 | 
			
		||||
kmonitor(struct trapframe *tf) {
 | 
			
		||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
			
		||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#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_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,10 @@
 | 
			
		||||
#include <clock.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <pmm.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sync.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <mmu.h>
 | 
			
		||||
#include <trap.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
 | 
			
		||||
/* *
 | 
			
		||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
			
		||||
/***** Implementations of basic kernel monitor commands *****/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
monitor(struct trapframe *tf) {
 | 
			
		||||
kmonitor(struct trapframe *tf) {
 | 
			
		||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
			
		||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#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_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,9 +11,10 @@
 | 
			
		||||
#include <vmm.h>
 | 
			
		||||
#include <ide.h>
 | 
			
		||||
#include <swap.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
                  break;
 | 
			
		||||
          }          
 | 
			
		||||
          assert(!PageReserved(page));
 | 
			
		||||
          //assert(!PageReserved(page));
 | 
			
		||||
 | 
			
		||||
          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
			
		||||
          
 | 
			
		||||
@ -272,8 +272,8 @@ check_swap(void)
 | 
			
		||||
         struct Page *p = le2page(le, page_link);
 | 
			
		||||
         count --, total -= p->property;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     assert(count == 0);
 | 
			
		||||
     cprintf("count is %d, total is %d\n",count,total);
 | 
			
		||||
     //assert(count == 0);
 | 
			
		||||
     
 | 
			
		||||
     cprintf("check_swap() succeeded!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sync.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <mmu.h>
 | 
			
		||||
#include <trap.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
 | 
			
		||||
/* *
 | 
			
		||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
			
		||||
/***** Implementations of basic kernel monitor commands *****/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
monitor(struct trapframe *tf) {
 | 
			
		||||
kmonitor(struct trapframe *tf) {
 | 
			
		||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
			
		||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#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_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,10 @@
 | 
			
		||||
#include <ide.h>
 | 
			
		||||
#include <swap.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -482,7 +482,7 @@ check_slab(void) {
 | 
			
		||||
    void *v0, *v1;
 | 
			
		||||
 | 
			
		||||
    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 */
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
@ -628,7 +628,7 @@ check_pass:
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
    assert(slab_allocated() == 0);
 | 
			
		||||
    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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
                  break;
 | 
			
		||||
          }          
 | 
			
		||||
          assert(!PageReserved(page));
 | 
			
		||||
          //assert(!PageReserved(page));
 | 
			
		||||
 | 
			
		||||
          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
			
		||||
          
 | 
			
		||||
@ -182,7 +182,7 @@ check_swap(void)
 | 
			
		||||
     list_entry_t *le = &free_list;
 | 
			
		||||
     while ((le = list_next(le)) != &free_list) {
 | 
			
		||||
        struct Page *p = le2page(le, page_link);
 | 
			
		||||
        //assert(PageProperty(p));
 | 
			
		||||
        assert(PageProperty(p));
 | 
			
		||||
        count ++, total += p->property;
 | 
			
		||||
     }
 | 
			
		||||
     assert(total == nr_free_pages());
 | 
			
		||||
@ -272,8 +272,8 @@ check_swap(void)
 | 
			
		||||
         struct Page *p = le2page(le, page_link);
 | 
			
		||||
         count --, total -= p->property;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     assert(count == 0);
 | 
			
		||||
     cprintf("count is %d, total is %d\n",count,total);
 | 
			
		||||
     //assert(count == 0);
 | 
			
		||||
     
 | 
			
		||||
     cprintf("check_swap() succeeded!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -304,8 +304,11 @@ quick_check() {
 | 
			
		||||
## kernel image
 | 
			
		||||
osimg=$(make_print ucoreimg)
 | 
			
		||||
 | 
			
		||||
## swap image
 | 
			
		||||
swapimg=$(make_print swapimg)
 | 
			
		||||
 | 
			
		||||
## set default qemu-options
 | 
			
		||||
qemuopts="-hda $osimg"
 | 
			
		||||
qemuopts="-hda $osimg -drive file=$swapimg,media=disk,cache=writeback"
 | 
			
		||||
 | 
			
		||||
## set break-function, default is readline
 | 
			
		||||
brkfun=readline
 | 
			
		||||
@ -316,7 +319,7 @@ quick_run 'Check VMM'
 | 
			
		||||
 | 
			
		||||
pts=5
 | 
			
		||||
quick_check 'check pmm'                                         \
 | 
			
		||||
    'memory management: buddy_pmm_manager'                      \
 | 
			
		||||
    'memory management: default_pmm_manager'                      \
 | 
			
		||||
    'check_alloc_page() succeeded!'                             \
 | 
			
		||||
    'check_pgdir() succeeded!'                                  \
 | 
			
		||||
    'check_boot_pgdir() succeeded!'
 | 
			
		||||
@ -340,11 +343,29 @@ quick_check 'check vmm'                                         \
 | 
			
		||||
    'check_pgfault() 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
 | 
			
		||||
quick_check 'check ticks'                                       \
 | 
			
		||||
    '++ setup timer interrupts'                                 \
 | 
			
		||||
    '100 ticks'                                                 \
 | 
			
		||||
    'End of Test.'
 | 
			
		||||
    '++ setup timer interrupts'
 | 
			
		||||
 | 
			
		||||
pts=30
 | 
			
		||||
quick_check 'check initproc'                                    \
 | 
			
		||||
    'this initproc, pid = 1, name = "init"'                     \
 | 
			
		||||
    'To U: "Hello world!!".'                                    \
 | 
			
		||||
    'To U: "en.., Bye, Bye. :)"'
 | 
			
		||||
 | 
			
		||||
## print final-score
 | 
			
		||||
show_final
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
#include <vmm.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <mmu.h>
 | 
			
		||||
#include <trap.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
 | 
			
		||||
/* *
 | 
			
		||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
			
		||||
/***** Implementations of basic kernel monitor commands *****/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
monitor(struct trapframe *tf) {
 | 
			
		||||
kmonitor(struct trapframe *tf) {
 | 
			
		||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
			
		||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#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_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,10 @@
 | 
			
		||||
#include <ide.h>
 | 
			
		||||
#include <swap.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
			
		||||
    void *v0, *v1;
 | 
			
		||||
 | 
			
		||||
    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 */
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
@ -633,7 +633,7 @@ check_pass:
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
    assert(slab_allocated() == 0);
 | 
			
		||||
    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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
			
		||||
     list_entry_t *le = &free_list;
 | 
			
		||||
     while ((le = list_next(le)) != &free_list) {
 | 
			
		||||
        struct Page *p = le2page(le, page_link);
 | 
			
		||||
        //assert(PageProperty(p));
 | 
			
		||||
        assert(PageProperty(p));
 | 
			
		||||
        count ++, total += p->property;
 | 
			
		||||
     }
 | 
			
		||||
     assert(total == nr_free_pages());
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
			
		||||
    *    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) {
 | 
			
		||||
            struct Page *page=NULL;
 | 
			
		||||
 | 
			
		||||
@ -103,6 +103,12 @@ alloc_proc(void) {
 | 
			
		||||
     *       uint32_t flags;                             // Process flag
 | 
			
		||||
     *       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;
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
			
		||||
    //    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:
 | 
			
		||||
    return ret;
 | 
			
		||||
 | 
			
		||||
@ -771,7 +786,7 @@ user_main(void *arg) {
 | 
			
		||||
static int
 | 
			
		||||
init_main(void *arg) {
 | 
			
		||||
    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);
 | 
			
		||||
    if (pid <= 0) {
 | 
			
		||||
@ -788,7 +803,7 @@ init_main(void *arg) {
 | 
			
		||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
			
		||||
    assert(slab_allocated_store == kallocated());
 | 
			
		||||
    assert(kernel_allocated_store == kallocated());
 | 
			
		||||
    cprintf("init check memory pass.\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -210,7 +210,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
			
		||||
        break;
 | 
			
		||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
			
		||||
#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. 
 | 
			
		||||
#endif
 | 
			
		||||
        /* LAB1 YOUR CODE : STEP 3 */
 | 
			
		||||
 | 
			
		||||
@ -512,6 +512,45 @@ run_test -prog 'forktest'   -check default_check
 | 
			
		||||
    !   'wait got too many'                                     \
 | 
			
		||||
    ! - '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
 | 
			
		||||
show_final
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define DEPTH 2
 | 
			
		||||
#define DEPTH 4
 | 
			
		||||
 | 
			
		||||
void forktree(const char *cur);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
#include <vmm.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										132
									
								
								code/lab6/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab6/kern/debug/kmonitor.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								code/lab6/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab6/kern/debug/kmonitor.h
									
									
									
									
									
										Normal 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__ */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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__ */
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,10 @@
 | 
			
		||||
#include <ide.h>
 | 
			
		||||
#include <swap.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
			
		||||
    void *v0, *v1;
 | 
			
		||||
 | 
			
		||||
    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 */
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
@ -633,7 +633,7 @@ check_pass:
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
    assert(slab_allocated() == 0);
 | 
			
		||||
    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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
			
		||||
     list_entry_t *le = &free_list;
 | 
			
		||||
     while ((le = list_next(le)) != &free_list) {
 | 
			
		||||
        struct Page *p = le2page(le, page_link);
 | 
			
		||||
        //assert(PageProperty(p));
 | 
			
		||||
        assert(PageProperty(p));
 | 
			
		||||
        count ++, total += p->property;
 | 
			
		||||
     }
 | 
			
		||||
     assert(total == nr_free_pages());
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
			
		||||
    *    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) {
 | 
			
		||||
            struct Page *page=NULL;
 | 
			
		||||
 | 
			
		||||
@ -103,6 +103,22 @@ alloc_proc(void) {
 | 
			
		||||
     *       uint32_t flags;                             // Process flag
 | 
			
		||||
     *       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;
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
			
		||||
    //    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:
 | 
			
		||||
    return ret;
 | 
			
		||||
 | 
			
		||||
@ -771,7 +796,7 @@ user_main(void *arg) {
 | 
			
		||||
static int
 | 
			
		||||
init_main(void *arg) {
 | 
			
		||||
    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);
 | 
			
		||||
    if (pid <= 0) {
 | 
			
		||||
@ -788,7 +813,7 @@ init_main(void *arg) {
 | 
			
		||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
			
		||||
    assert(slab_allocated_store == kallocated());
 | 
			
		||||
    assert(kernel_allocated_store == kallocated());
 | 
			
		||||
    cprintf("init check memory pass.\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <default_sched.h>
 | 
			
		||||
 | 
			
		||||
// the list of timer
 | 
			
		||||
static list_entry_t timer_list;
 | 
			
		||||
 | 
			
		||||
static struct sched_class *sched_class;
 | 
			
		||||
@ -48,7 +49,7 @@ sched_init(void) {
 | 
			
		||||
    sched_class = &default_sched_class;
 | 
			
		||||
 | 
			
		||||
    rq = &__rq;
 | 
			
		||||
    rq->max_time_slice = 20;
 | 
			
		||||
    rq->max_time_slice = MAX_TIME_SLICE;
 | 
			
		||||
    sched_class->init(rq);
 | 
			
		||||
 | 
			
		||||
    cprintf("sched class: %s\n", sched_class->name);
 | 
			
		||||
@ -98,6 +99,7 @@ schedule(void) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add timer to timer_list
 | 
			
		||||
void
 | 
			
		||||
add_timer(timer_t *timer) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// del timer from timer_list
 | 
			
		||||
void
 | 
			
		||||
del_timer(timer_t *timer) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
			
		||||
void
 | 
			
		||||
run_timer_list(void) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
 | 
			
		||||
@ -5,17 +5,20 @@
 | 
			
		||||
#include <list.h>
 | 
			
		||||
#include <skew_heap.h>
 | 
			
		||||
 | 
			
		||||
#define MAX_TIME_SLICE 20
 | 
			
		||||
 | 
			
		||||
struct proc_struct;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned int expires;
 | 
			
		||||
    struct proc_struct *proc;
 | 
			
		||||
    list_entry_t timer_link;
 | 
			
		||||
    unsigned int expires;       //the expire time
 | 
			
		||||
    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;    //the timer list
 | 
			
		||||
} timer_t;
 | 
			
		||||
 | 
			
		||||
#define le2timer(le, member)            \
 | 
			
		||||
to_struct((le), timer_t, member)
 | 
			
		||||
 | 
			
		||||
// init a timer
 | 
			
		||||
static inline timer_t *
 | 
			
		||||
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
			
		||||
    timer->expires = expires;
 | 
			
		||||
@ -62,9 +65,9 @@ struct run_queue {
 | 
			
		||||
void sched_init(void);
 | 
			
		||||
void wakeup_proc(struct proc_struct *proc);
 | 
			
		||||
void schedule(void);
 | 
			
		||||
void add_timer(timer_t *timer);
 | 
			
		||||
void del_timer(timer_t *timer);
 | 
			
		||||
void run_timer_list(void);
 | 
			
		||||
void add_timer(timer_t *timer);     // add timer to timer_list
 | 
			
		||||
void del_timer(timer_t *timer);     // del timer from timer_list
 | 
			
		||||
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__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t
 | 
			
		||||
static int
 | 
			
		||||
sys_gettime(uint32_t arg[]) {
 | 
			
		||||
    return (int)ticks;
 | 
			
		||||
}
 | 
			
		||||
static uint32_t
 | 
			
		||||
static int
 | 
			
		||||
sys_lab6_set_priority(uint32_t arg[])
 | 
			
		||||
{
 | 
			
		||||
    uint32_t priority = (uint32_t)arg[0];
 | 
			
		||||
 | 
			
		||||
@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
			
		||||
        break;
 | 
			
		||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
			
		||||
#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. 
 | 
			
		||||
#endif
 | 
			
		||||
        /* 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):
 | 
			
		||||
         *    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;
 | 
			
		||||
    case IRQ_OFFSET + IRQ_COM1:
 | 
			
		||||
        c = cons_getc();
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ sys_pgdir(void) {
 | 
			
		||||
    return syscall(SYS_pgdir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
int
 | 
			
		||||
sys_gettime(void) {
 | 
			
		||||
    return syscall(SYS_gettime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ int sys_kill(int pid);
 | 
			
		||||
int sys_getpid(void);
 | 
			
		||||
int sys_putc(int c);
 | 
			
		||||
int sys_pgdir(void);
 | 
			
		||||
int sys_gettime(void);
 | 
			
		||||
/* FOR LAB6 ONLY */
 | 
			
		||||
void sys_lab6_set_priority(uint32_t priority);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
#include <vmm.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										132
									
								
								code/lab7/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab7/kern/debug/kmonitor.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								code/lab7/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab7/kern/debug/kmonitor.h
									
									
									
									
									
										Normal 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__ */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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__ */
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,10 @@
 | 
			
		||||
#include <ide.h>
 | 
			
		||||
#include <swap.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
int kern_init(void) __attribute__((noreturn));
 | 
			
		||||
 | 
			
		||||
void grade_backtrace(void);
 | 
			
		||||
static void lab1_switch_test(void);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 | 
			
		||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
			
		||||
    void *v0, *v1;
 | 
			
		||||
 | 
			
		||||
    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 */
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
@ -633,7 +633,7 @@ check_pass:
 | 
			
		||||
    check_slab_empty();
 | 
			
		||||
    assert(slab_allocated() == 0);
 | 
			
		||||
    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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
			
		||||
     list_entry_t *le = &free_list;
 | 
			
		||||
     while ((le = list_next(le)) != &free_list) {
 | 
			
		||||
        struct Page *p = le2page(le, page_link);
 | 
			
		||||
        //assert(PageProperty(p));
 | 
			
		||||
        assert(PageProperty(p));
 | 
			
		||||
        count ++, total += p->property;
 | 
			
		||||
     }
 | 
			
		||||
     assert(total == nr_free_pages());
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
			
		||||
    *    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) {
 | 
			
		||||
            struct Page *page=NULL;
 | 
			
		||||
 | 
			
		||||
@ -103,6 +103,22 @@ alloc_proc(void) {
 | 
			
		||||
     *       uint32_t flags;                             // Process flag
 | 
			
		||||
     *       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;
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
			
		||||
    //    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:
 | 
			
		||||
    return ret;
 | 
			
		||||
 | 
			
		||||
@ -771,7 +796,7 @@ user_main(void *arg) {
 | 
			
		||||
static int
 | 
			
		||||
init_main(void *arg) {
 | 
			
		||||
    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);
 | 
			
		||||
    if (pid <= 0) {
 | 
			
		||||
@ -790,7 +815,7 @@ init_main(void *arg) {
 | 
			
		||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
			
		||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
			
		||||
    assert(slab_allocated_store == kallocated());
 | 
			
		||||
    assert(kernel_allocated_store == kallocated());
 | 
			
		||||
    cprintf("init check memory pass.\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <default_sched.h>
 | 
			
		||||
 | 
			
		||||
// the list of timer
 | 
			
		||||
static list_entry_t timer_list;
 | 
			
		||||
 | 
			
		||||
static struct sched_class *sched_class;
 | 
			
		||||
@ -98,6 +99,7 @@ schedule(void) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add timer to timer_list
 | 
			
		||||
void
 | 
			
		||||
add_timer(timer_t *timer) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// del timer from timer_list
 | 
			
		||||
void
 | 
			
		||||
del_timer(timer_t *timer) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
 | 
			
		||||
    local_intr_restore(intr_flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
			
		||||
void
 | 
			
		||||
run_timer_list(void) {
 | 
			
		||||
    bool intr_flag;
 | 
			
		||||
 | 
			
		||||
@ -5,17 +5,20 @@
 | 
			
		||||
#include <list.h>
 | 
			
		||||
#include <skew_heap.h>
 | 
			
		||||
 | 
			
		||||
#define MAX_TIME_SLICE 20
 | 
			
		||||
 | 
			
		||||
struct proc_struct;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned int expires;
 | 
			
		||||
    struct proc_struct *proc;
 | 
			
		||||
    list_entry_t timer_link;
 | 
			
		||||
    unsigned int expires;       //the expire time
 | 
			
		||||
    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;    //the timer list
 | 
			
		||||
} timer_t;
 | 
			
		||||
 | 
			
		||||
#define le2timer(le, member)            \
 | 
			
		||||
to_struct((le), timer_t, member)
 | 
			
		||||
 | 
			
		||||
// init a timer
 | 
			
		||||
static inline timer_t *
 | 
			
		||||
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
			
		||||
    timer->expires = expires;
 | 
			
		||||
@ -62,9 +65,9 @@ struct run_queue {
 | 
			
		||||
void sched_init(void);
 | 
			
		||||
void wakeup_proc(struct proc_struct *proc);
 | 
			
		||||
void schedule(void);
 | 
			
		||||
void add_timer(timer_t *timer);
 | 
			
		||||
void del_timer(timer_t *timer);
 | 
			
		||||
void run_timer_list(void);
 | 
			
		||||
void add_timer(timer_t *timer);     // add timer to timer_list
 | 
			
		||||
void del_timer(timer_t *timer);     // del timer from timer_list
 | 
			
		||||
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__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t
 | 
			
		||||
static int
 | 
			
		||||
sys_gettime(uint32_t arg[]) {
 | 
			
		||||
    return (int)ticks;
 | 
			
		||||
}
 | 
			
		||||
static uint32_t
 | 
			
		||||
static int
 | 
			
		||||
sys_lab6_set_priority(uint32_t arg[])
 | 
			
		||||
{
 | 
			
		||||
    uint32_t priority = (uint32_t)arg[0];
 | 
			
		||||
 | 
			
		||||
@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
			
		||||
        break;
 | 
			
		||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
			
		||||
#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. 
 | 
			
		||||
#endif
 | 
			
		||||
        /* 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):
 | 
			
		||||
         *    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;
 | 
			
		||||
    case IRQ_OFFSET + IRQ_COM1:
 | 
			
		||||
        c = cons_getc();
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define DEPTH 4
 | 
			
		||||
#define SLEEP_TIME 400
 | 
			
		||||
 | 
			
		||||
void forktree(const char *cur);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -31,8 +31,6 @@ forktree(const char *cur) {
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(void) {
 | 
			
		||||
    cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME);
 | 
			
		||||
    sleep(SLEEP_TIME);
 | 
			
		||||
    forktree("");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ sys_pgdir(void) {
 | 
			
		||||
    return syscall(SYS_pgdir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
int
 | 
			
		||||
sys_gettime(void) {
 | 
			
		||||
    return syscall(SYS_gettime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ int sys_kill(int pid);
 | 
			
		||||
int sys_getpid(void);
 | 
			
		||||
int sys_putc(int c);
 | 
			
		||||
int sys_pgdir(void);
 | 
			
		||||
int sys_gettime(void);
 | 
			
		||||
/* FOR LAB6 ONLY */
 | 
			
		||||
void sys_lab6_set_priority(uint32_t priority);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(void) {
 | 
			
		||||
    int pid, ret, i ,j;
 | 
			
		||||
    int pid, ret;
 | 
			
		||||
    cprintf("I am the parent. Forking the child...\n");
 | 
			
		||||
    pid = fork();
 | 
			
		||||
    if (pid== 0) {
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
#include <vmm.h>
 | 
			
		||||
#include <proc.h>
 | 
			
		||||
#include <kdebug.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define STACKFRAME_DEPTH 20
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										132
									
								
								code/lab8/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab8/kern/debug/kmonitor.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								code/lab8/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab8/kern/debug/kmonitor.h
									
									
									
									
									
										Normal 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__ */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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__ */
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include <defs.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <intr.h>
 | 
			
		||||
#include <monitor.h>
 | 
			
		||||
#include <kmonitor.h>
 | 
			
		||||
 | 
			
		||||
static bool is_panic = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
			
		||||
panic_dead:
 | 
			
		||||
    intr_disable();
 | 
			
		||||
    while (1) {
 | 
			
		||||
        monitor(NULL);
 | 
			
		||||
        kmonitor(NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_disk0.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_disk0.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdin.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdin.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdout.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdout.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/file.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/file.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/file.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/file.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										2
									
								
								code/lab8/kern/fs/fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								code/lab8/kern/fs/fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -78,7 +78,7 @@ files_closeall(struct files_struct *filesp) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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");
 | 
			
		||||
    assert(to != NULL && from != NULL);
 | 
			
		||||
    assert(files_count(to) == 0 && files_count(from) > 0);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								code/lab8/kern/fs/fs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/fs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/iobuf.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/iobuf.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/iobuf.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/iobuf.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_inode.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_inode.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_io.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_io.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_lock.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_lock.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sysfile.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sysfile.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user