Since the csc331 container mounts the workspace directory on the host machine into /workspace, you are able to edit contents directly from the host machine via an IDE. The screenshot belows show a VSCode IDE session into the xv6-riscv repo that had been cloned into the host machine’s workspace folder and editing a file called xv6-test.txt.
WarningDo not open git repository of parent folder
You can also leverage the Terminal space of VSCode to docker exec into the container and test your code modifications.
This file also shows up inside the csc331 container.
Screenshot: Contents of /workspace inside container
Going forward, you can edit all files in the workspace directory from your host computer and they will be reflected immediately inside the container. This will help with all hands-on activities, labs, and assignments for the class.
How does fork() behave in xv6?
Using the code browser, create a file called p1.c inside the user directory of xv6-riscv directory with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include"kernel/types.h"
#include"user/user.h"intmain(){intpid=fork();if(pid==0){printf("Child: my pid is %d\n",getpid());exit(0);}else{printf("Parent: my pid is %d, child is %d\n",getpid(),pid);}exit(0);}
Screenshot: creating p1.c inside xv6-riscv/user
In Makefile under xv6-riscv, find the section UPROGS= and edit to include the $U/_p1\ line.
Screenshot: Edit xv6-riscv/Makefile
Let’s rebuild and relaunch xv6. In a terminal, run the followings
1
2
3
4
cd ~/xv6-riscv
make clean
make
make qemu
When you run ls, you will see the content of the available commands in xv6, which now includes p1.
Run p1 several times.
Screenshot: content of lsWhat do you expect to see, and what do you have? Why?
What about wait()?
Using the code browser, create a file called p2.c inside the user directory of xv6-riscv directory with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include"kernel/types.h"
#include"user/user.h"intmain(){intpid=fork();if(pid==0){printf("Child: my pid is %d\n",getpid());exit(0);}else{wait(0);printf("Parent: my pid is %d, child is %d\n",getpid(),pid);}exit(0);}
Screenshot: creating p2.c inside xv6-riscv/user
In Makefile under xv6-riscv, find the section UPROGS= and edit to include the $U/_p2\ line.
Screenshot: Edit xv6-riscv/Makefile
Let’s rebuild and relaunch xv6. In a terminal, run the followings
1
2
3
4
cd ~/xv6-riscv
make clean
make
make qemu
When you run ls, you will see the content of the available commands in xv6, which now includes p1 and p2.
Run p2 several times. Observe the change in output.
The implementation of fork() in xv6
Source code of fork() can be found in kernel/proc.c.
This is the kernel implementation of the fork() system call.
Goal: Create a new process that is an (almost) exact copy of the calling process.
InfoDetails
1
2
3
inti,pid;structproc*np;structproc*p=myproc();
p = myproc() retrieves the current running process (caller of fork()).
myproc() is defined in kernel/proc.c.
Uses r_tp() (thread pointer register) to find the process on the current CPU.