diff --git a/kernel/vm.c b/kernel/vm.c index a1c36ba..3631c9c 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; } 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 @@ + +
+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. + +
+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: +
+ int alarm(int ticks, void (*handler)()); ++ +
+ 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? + +
+ make CPUS=1 qemu ++ +
+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. + + diff --git a/labs/xv6.html b/labs/xv6.html index fcbb234..8dc7786 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) $ @@ -178,16 +178,60 @@ initial file system. You just ran one of them: ls.
Optional: support regular expressions in name matching. Grep has some + primitive support for regular expressions. + +
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: +
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 +