From 8c12928cc59b5a0b1d9aa6aada2772d0d2320542 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 06:50:12 -0400 Subject: [PATCH 1/6] First draft of first lab assignment? --- labs/xv6.html | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/labs/xv6.html b/labs/xv6.html index fcbb234..2f6a4ae 100644 --- a/labs/xv6.html +++ b/labs/xv6.html @@ -178,6 +178,44 @@ initial file system. You just ran one of them: ls.
  • Don't recurse into "." and "..". +

    Optional: support regular expressions in name matching. Grep has some + primitive support for regular expressions. + +

    xargs

    + +

    Write a simple version of the UNIX xargs program: read lines from + standard in and run a command for each line, supplying the line as + arguments to the command. The following example illustrates xarg's + behavior: +

    +    $ xargs echo bye
    +    hello too
    +    bye hello too
    +    
    +    $
    +  
    + Note that the command here is "echo bye" and the additional + arguments are "hello too", making the command "echo bye hello too", + which outputs "bye hello too". + +

    xargs and find combine well: +

    +    find . b | xargs grep hello
    +  
    + will run "grep hello" on each file named b in the directories below ".". + +

    Some hints: +

    + +

    Optional: modify the shell

    Modify the shell to support wait. From 47c9721d785908f9102979b71eb86d60ef086c9a Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 06:59:07 -0400 Subject: [PATCH 2/6] a few name changes in panic msg --- kernel/vm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/vm.c b/kernel/vm.c index 33469d1..9c5798c 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -133,9 +133,9 @@ kvmpa(uint64 va) pte = walk(kernel_pagetable, va, 0); if(pte == 0) - panic("kernelpa"); + panic("kvmpa"); if((*pte & PTE_V) == 0) - panic("kernelpa"); + panic("kvmpa"); pa = PTE2PA(*pte); return pa+off; } @@ -343,7 +343,7 @@ uvmclear(pagetable_t pagetable, uint64 va) pte = walk(pagetable, va, 0); if(pte == 0) - panic("clearpteu"); + panic("uvmclear"); *pte &= ~PTE_U; } From c0b1c239ea97bb56ad5c24110e6d52e9633a2847 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 07:07:03 -0400 Subject: [PATCH 3/6] x --- labs/xv6.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/xv6.html b/labs/xv6.html index 2f6a4ae..de18ac7 100644 --- a/labs/xv6.html +++ b/labs/xv6.html @@ -109,7 +109,7 @@ initial file system. You just ran one of them: ls. $ make qemu ... init: starting sh - $ sleep 5 + $ sleep 10 (waits for a little while) $ From 808811f9f49a21ae1a00b2e5805cf62cc31c0518 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 07:47:22 -0400 Subject: [PATCH 4/6] Add syscall tracing to the first xv6 lab --- labs/xv6.html | 53 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/labs/xv6.html b/labs/xv6.html index de18ac7..7699b06 100644 --- a/labs/xv6.html +++ b/labs/xv6.html @@ -215,17 +215,58 @@ initial file system. You just ran one of them: ls. to declare an argv. +

    System call tracing

    +

    In this exercise you will modify the xv6 kernel to print out a line +for each system call invocation. It is enough to print the name of the +system call and the return value; you don't need to print the system +call arguments. + +

    +When you're done, you should see output like this when booting +xv6: + +

    +...
    +fork -> 2
    +exec -> 0
    +open -> 3
    +close -> 0
    +$write -> 1
    + write -> 1
    +
    + +

    +That's init forking and execing sh, sh making sure only two file descriptors are +open, and sh writing the $ prompt. (Note: the output of the shell and the +system call trace are intermixed, because the shell uses the write syscall to +print its output.) + +

    Hint: modify the syscall() function in kernel/syscall.c. + +

    Run the programs you wrote in the previous exercises and inspect + the system call trace. Are there many system calls? Which systems + calls correspond to code in the applications you wrote above? + +

    Optional: print the system call arguments. +

    Optional: modify the shell

    -

    Modify the shell to support wait. - -

    Modify the shell to support lists of commands, separated by ";" +There are endless ways in which the shell could be extended. Here are +some suggestions: -

    Modify the shell to support sub-shells by implementing "(" and ")" - -

    Modify the shell to allow users to edit the command line +

    + From 57a861bea1ef57a44574cfc74737d5b35db0e261 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 08:19:14 -0400 Subject: [PATCH 5/6] Checkpoint start syscall lab --- labs/xv6.html | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/labs/xv6.html b/labs/xv6.html index 7699b06..8dc7786 100644 --- a/labs/xv6.html +++ b/labs/xv6.html @@ -215,41 +215,6 @@ initial file system. You just ran one of them: ls. to declare an argv. -

    System call tracing

    - -

    In this exercise you will modify the xv6 kernel to print out a line -for each system call invocation. It is enough to print the name of the -system call and the return value; you don't need to print the system -call arguments. - -

    -When you're done, you should see output like this when booting -xv6: - -

    -...
    -fork -> 2
    -exec -> 0
    -open -> 3
    -close -> 0
    -$write -> 1
    - write -> 1
    -
    - -

    -That's init forking and execing sh, sh making sure only two file descriptors are -open, and sh writing the $ prompt. (Note: the output of the shell and the -system call trace are intermixed, because the shell uses the write syscall to -print its output.) - -

    Hint: modify the syscall() function in kernel/syscall.c. - -

    Run the programs you wrote in the previous exercises and inspect - the system call trace. Are there many system calls? Which systems - calls correspond to code in the applications you wrote above? - -

    Optional: print the system call arguments. -

    Optional: modify the shell

    There are endless ways in which the shell could be extended. Here are From 0358ee912bb37439d36a76ca4469aaa1ab6c2a48 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 25 Jul 2019 09:42:36 -0400 Subject: [PATCH 6/6] syscall lab/alarm --- labs/syscall.html | 196 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 labs/syscall.html diff --git a/labs/syscall.html b/labs/syscall.html new file mode 100644 index 0000000..a167885 --- /dev/null +++ b/labs/syscall.html @@ -0,0 +1,196 @@ + + +Lab: system calls + + + + +

    Lab: system calls

    + +This lab makes you familiar with the implementation of system calls. +In particular, you will implement a new system call: alarm. + + +

    Warmup: system call tracing

    + +

    In this exercise you will modify the xv6 kernel to print out a line +for each system call invocation. It is enough to print the name of the +system call and the return value; you don't need to print the system +call arguments. + +

    +When you're done, you should see output like this when booting +xv6: + +

    +...
    +fork -> 2
    +exec -> 0
    +open -> 3
    +close -> 0
    +$write -> 1
    + write -> 1
    +
    + +

    +That's init forking and execing sh, sh making sure only two file descriptors are +open, and sh writing the $ prompt. (Note: the output of the shell and the +system call trace are intermixed, because the shell uses the write syscall to +print its output.) + +

    Hint: modify the syscall() function in kernel/syscall.c. + +

    Run the programs you wrote in the lab and inspect the system call + trace. Are there many system calls? Which systems calls correspond + to code in the applications you wrote above? + +

    Optional: print the system call arguments. + +

    alarm

    + +

    +In this exercise you'll add a feature to xv6 that periodically alerts +a process as it uses CPU time. This might be useful for compute-bound +processes that want to limit how much CPU time they chew up, or for +processes that want to compute but also want to take some periodic +action. More generally, you'll be implementing a primitive form of +user-level interrupt/fault handlers; you could use something similar +to handle page faults in the application, for example. + +

    +You should add a new alarm(interval, handler) system call. +If an application calls alarm(n, fn), then after every +n "ticks" of CPU time that the program consumes, the kernel +will cause application function +fn to be called. When fn returns, the application +will resume where it left off. A tick is a fairly arbitrary unit of +time in xv6, determined by how often a hardware timer generates +interrupts. + +

    +You should put the following example program in user/alarmtest.c: + +

    +#include "kernel/param.h"
    +#include "kernel/types.h"
    +#include "kernel/stat.h"
    +#include "user/user.h"
    +
    +void periodic();
    +
    +int
    +main(int argc, char *argv[])
    +{
    +  int i;
    +  printf(1, "alarmtest starting\n");
    +  alarm(10, periodic);
    +  for(i = 0; i < 25*500000; i++){
    +    if((i % 250000) == 0)
    +      write(2, ".", 1);
    +  }
    +  exit();
    +}
    +
    +void
    +periodic()
    +{
    +  printf(1, "alarm!\n");
    +}
    +
    + +The program calls alarm(10, periodic) to ask the kernel to +force a call to periodic() every 10 ticks, and then spins for +a while. +After you have implemented the alarm() system call in the kernel, +alarmtest should produce output like this: + +
    +$ alarmtest
    +alarmtest starting
    +.....alarm!
    +....alarm!
    +.....alarm!
    +......alarm!
    +.....alarm!
    +....alarm!
    +....alarm!
    +......alarm!
    +.....alarm!
    +...alarm!
    +...$ 
    +
    +

    + +

    +(If you only see one "alarm!", try increasing the number of iterations in +alarmtest.c by 10x.) + +Here are some hints: +

      + +
    • You'll need to modify the Makefile to cause alarmtest.c +to be compiled as an xv6 user program. + +
    • The right declaration to put in user/user.h is: +
      +    int alarm(int ticks, void (*handler)());
      +
      + +
    • Update kernel/syscall.h and user/usys.S to +allow alarmtest to invoke the alarm system call. + +
    • Your sys_alarm() should store the alarm interval and the +pointer to the handler function in new fields in the proc +structure; see kernel/proc.h. + +
    • +You'll need to keep track of how many ticks have passed since +the last call +(or are left until the next call) to a process's alarm handler; +you'll need a new field in struct proc for this too. +You can initialize proc fields in allocproc() +in proc.c. + +
    • +Every tick, the hardware clock forces an interrupt, which +is handled in usertrap(); you should add some code here. + +
    • + You only want to manipulate a process's alarm ticks if there's a + a timer interrupt; you want something like +
      +    if(which_dev == 2) ..
      +
      + +

      +In your usertrap, when a process's alarm interval expires, +you'll want to cause it to execute its handler. How can you do that? + +

    • +You need to arrange things so that, when the handler returns, +the process resumes executing where it left off. How can you do that? + +
    • +You can see the assembly code for the alarmtest program in alarmtest.asm. + +
    • +It will be easier to look at traps with gdb if you tell qemu to use +only one CPU, which you can do by running +
      +    make CPUS=1 qemu
      +
      + +
    • +It's OK if your solution doesn't save the caller-saved user registers +when calling the handler. + +
        + +

        +Optional challenges: 1) Save and restore the caller-saved user registers around the +call to handler. 2) Prevent re-entrant calls to the handler -- if a handler +hasn't returned yet, don't call it again. 3) Assuming your code doesn't +check that tf->esp is valid, implement a security attack on the +kernel that exploits your alarm handler calling code. + +