• Stars
    star
    295
  • Rank 140,902 (Top 3 %)
  • Language
    C
  • Created about 4 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

MIT undergraduate operating system course

MIT 6.S081 2020fall

This repository contains my solution to the labs for MIT's 6.S081 operating system.

How to use it ?

First, you need to clone this repository by

git clone https://github.com/PKUFlyingPig/MIT6.S081-2020fall.git

Then cd into the file, you are now in the master branch of the projects, to see my answer to a specific lab, e.g. util, syscall ...... , you just checkout into that branch by for example

git checkout util

and now you are in the utils branch which contains my solution to the specific lab.

if you want to have a clean copy of the original lab handout, just go to the course website and follow the lab guidance. Also, you can watch the course videos on the course website. Hope you enjoy your OS journey.

Lab Reports

For each lab, I wrote a brief report on my implementation, explaining the important part of my code and how to complete the lab step by step. (I wrote these reports in Chinese)

Reading materials

I highly recommend you read the xv6 book before watching the course videos and doing the labs.

Wanna Learn More ?

Check out this repository which contains all my self-learning materials : )

Hints for each lab

You should do the labs on your own at first, but if you encounter some bugs or want to get some high-level hints, this part may help you.

lab1 : util

every program must end with exit(0)!!

  • sleep (easy) : just follow the guidance
  • pingpong (easy) : You only need to transfer any byte you want, but not transfer "pingpong" the string itself. When the parent send the byte, remember to explicitly wait for the child to reply.
  • Primes (moderate) : Remeber that when you create a pipe and then call fork(). There are 4 file descriptors open. So be careful to turn off the file descriptor that you don't need.
  • Find (moderate) : nothing special. Don't recurse into "." and "..".
  • xargs (moderate) : A little tricky to read in the string because you need to read one byte at a time. You can refer to my solution. I read in one line at a time. Also remember to wait for all the children to complete.

lab2 : syscall

read the chapter 2 and 3.5 4.4 4.5 carefully and make sure to understand what you are going to do

  • system call tracing (moderate) : all the modification you need to do are listed in the lab guidance except for the entry you need to add for the syscall declaration and the syscall function pointer array in the kernel/syscall.c (about line 90 to 120).
  • sysinfo (moderate) :
    • remember to add the definition of your newly added two helper functions in kernel/defs.h, otherwise you will receive compile error.
    • read the lab guid carefully, especially that nproc field should be set to the number of processes whose state is not UNUSED. I spent one hour to find this stupid bug.
    • use argaddr to get the sysinfo structure address provided by user in sys_sysinfo function implementation.
    • nproc : allocproc function in proc.c may give you some hints.
    • freemem : read chapter 3.5 in xv6 book may make you understand what happens in the kalloc.c. (kmem is a list of free pages and each page is 4096 bytes)

lab3 : pgtbl

warning : this lab is extremly time-consuming

read the chapter 3 and the code in proc.c/ vm.c carefully, understand the difference between the user address space and kernel address space

because there are so many details in this lab, I wrapper my solution code with the title "solution for pgtbl ---- part x", I only modified the following files(vm.c, exec.c, proc.c, proc.h, defs.h), so you can search the title in these files to see my modification.

  • Print a page table (easy) :
    • just follow the guidance
    • see freewalk function for inspiration
  • kernel page table per process(hard) :
    • to understand my solution(especially the kvmcreate function), you need to first read the part3 problem, and notice that the user will not use virtual address over PLIC(0xC000000) ---- I think this condition is just for simplification. After you understand this, you should find that the user will only modify the address lies in the first entry of the pagetable. That is why I just copy the 1 to 511 entry of kernel_pagetable into per process's pagetable. Then the kvmfree function is also easy to understand.
    • the second step is to call the two function above to create a new kernel pagetable for a new process that is allocated (in allocproc()) and free the kernel pagetable when the process is killed (in freeproc()).
    • the last step is to modify the scheduler() to switch the kernel pagetable for each process. Remember that the scheduler will use the original kernel page table !
  • simplify copyin / copyinstr (hard) :
    • add a new function to copy PTEs from the user page table into process's kernel pagetable. (see kvmmapuser() in vm.c for more details)
    • At each point where the kernel changes a process's user mappings, change the process's kernel page table in the same way. Such points include fork(), exec(), and growproc(). The guidance says that you need to modify the sbrk(). I instead modified growproc(). Both are ok.
    • Don't forget to modify the copyin() and copyinstr() methods to call copyin_new and copyinstr_new.
    • You also need to add the newly added functions into defs.h.

lab4 : traps

  • RISCV - assembly (easy) :

    • a0-7 contains arguments to functions. a2 holds 13 in main's call to printf.
    • at address 0x26, we can see the complier directly loads 12 into a1 register, which is just the return value of f(8) + 1.
    • printf lies at address 0x630
    • just after the jalr to printf, ra saves the return address, which is 0x38
    • the output is "He110 world". If the RISC-V were instead big-endian, we need to set i to 0x726c6400 in order to yield the same output. We don't need to change 57616 to a different value.
    • the value in register a2 will be printed after 'y=', which is quite random.
  • Backtrace (moderate) :

    • use r_fp() in backtrace to get current frame pointer
    • using PGROUNDDOWN(fp) and PGROUNDUP(fp) (see kernel/riscv.h. These number are helpful for backtrace to terminate its loop).
  • Alarm (hard) :

    • this lab is not as hard as the pgtbl, so do not think too complicatedly, the answer is quite straight-forward and easy to get.
    • follow the guidance step by step, all the details are all in the guidance
    • I add a new field (allow_entrance_handler) in proc structure to avoid handler re-entrant.
    • the bugs that I encountered :
      • At first I add one more trapframe to save all the registers, but this implementation will not pass the usertests
      • You need to save s-registers, but I am a little confused about it. Since if the handler function follows the RISC-V calling convention, it needs to save the s-register before using it. So why the original process's s-registers get corrupted ?

lab5 : lazy

  • eliminate allocation from sbrk() (easy)
    • so easy
  • lazy allocation (moderate)
    • You need to modify trap.c/usertrap() to handle the page fault. You can check whether a fault is a page fault by seeing if r_scause() is 13 or 15. If so, use kalloc() to allocate physical memory and then use mappage() to add this physical memory into the user pagetable.
    • Modify uvmunmap() function. Because when the OS want to unmap the address which is requested by the user program but have not yet been allocated, it orginally will call panic() to abort. But since it may because of lazy allocation, we will allow this to happen.(you can simply change the "panic" into "continue")
  • Lazytests and Usertests (moderate)
    • handle negative sbrk() arguments : remember to deallocate.
    • you need to kill the process if the address is illegal (below the stack or above the heap). the p->sz and p->trapframe-sp may help you. Remeber that in xv6, user address space's heap is above its stack, which may be not consistent with your common knowledge.
    • If you see the error "incomplete type proc", include "spinlock.h" then "proc.h".
    • Handle the parent-to-child memory copy in fork() correctly : modify uvmcopy(), which is similar to the modification you made to the uvmunmap() funcation.
    • Handle the case in which a process passes a valid address from sbrk() to a system call such as read or write, but the memory for that address has not yet been allocated : you only need to modify copyin() and copyout() function. Why we need to do that? because usertrap() only handle the page fault in the user program, but copyin() and copyout() are called in the kernel, which can not be handled by usertrap(). So you can just copy the code from usertrap() to handle this case.

Lab6 : COW

MIT's Q&A session will go through this lab step by step, you can check this video for help.

  • You need a lock to protect your ref_count array
  • decrement the ref_count in the kfree function, I used to decrement it in the uvmunmap function but failed to pass the usertests.
  • you can write a specific function e.g. cowhandler to handle the COW page fault, then call it in both usertrap and copyout function (I didn't do that, so my code may look a little messy).

lab7 : multithreading

  • Uthread (moderate) :
    • your code can be quite similar to the code in switch.S and proc.h (almost the same)
    • think twice when you assign value to the thread's stack pointer in thread_create ! ( remember that the stack is growing down in the address space)
  • Using threads :
    • when you call insert() in put(), you already give the current head of the bucket as a variable to the insert() function, so if one thread has called insert but has not updated the head of the bucket, and now another thread calls insert() with an old head of the bucket, then the wrong occurs.
  • Barrier :
    • nothing special, remember that when one thread wake up, it will immediately acquire the lock.

Lab8 : locking

  • Memory allocator (moderate) :
    • You can choose to allocate free pages evenly to each CPU at the beginning, although I didn't do that.
    • I choose to steal 1000 pages at a time.
  • Buffer cache (hard) :
    • I don't recommend my solution, which took me only 10 minutes to pass the hard lab.
    • I just copy the bcache 13 times to hack the lab.

Lab9 : file system

I know "Chapter 8: File system" in xv6 book is quite long and hard to understand, but read it patiently and thoroughly will save you a lot of time ! I personally find read the code first will help you understand (fs.c, file.c, sysfile.c, fs.h, file.h) .

  • Large files (moderate) :
    • easy and straightforward
  • Symbolic links (moderate) :
    • if you encounter "exec symlinktest failed", you may forget to add _symlinktest into the Makefile
    • the function readi and writei may be your friend, you don't bother to write your own code to write data into inode's data block.
    • if you encounter "panic: iget: no inodes", you may forget to iput(ip). I recommend you use iunlockput(ip) for convenience.

Lab10 : Mmap

mmap is a very important feature in today's OS, if you run strace for any program, you will see many mmap system call. This lab will let you have a taste for the memory mapped file.

  • use filedup to increment file's reference, use fileclose to decrement file's reference.

  • you can write the pagefault handler code in usertrap based on your Lazy lab implementation.

  • the mmaptest only tests files whose size is PGSIZE-aligned, so I didn't handle the common case. You may make use of this to simplify your code.

More Repositories

1

cs-self-learning

计算机自学指南
HTML
54,539
star
2

Self-learning-Computer-Science

the resources I use to learn computer science in my spare time
2,961
star
3

CS61A

JavaScript
589
star
4

CS61B

course resources for UCB_CS61B 2018 summer
Java
326
star
5

CS144-Computer-Network

Learning materials for Stanford Computer Network course : CS144
C++
281
star
6

CS186

Learning materials for UCB CS186: Introduction to Database System
229
star
7

CS61C-summer20

all the course resources of UCB's CS61C course -- Great ideas in computer architecture
C
175
star
8

CS229

Jupyter Notebook
167
star
9

UCB-CS70

discrete mathematics and probability theory
163
star
10

CS106L

CS106L : Standard C++ Programming Course
C++
155
star
11

NandToTetris

all the course resources and my completion for all the projects
Hack
149
star
12

Computer-Network-A-Top-Down-Approach

My learning materials for Computer Networking : A Top Down Approach
Python
138
star
13

CMU10-714

Learning material for CMU10-714: Deep Learning System
Jupyter Notebook
137
star
14

CS149-parallel-computing

Learning materials for Stanford CS149 : Parallel Computing
C
122
star
15

MIT6.824

distributed system
Go
109
star
16

Princeton-Algorithm

Java
75
star
17

EECS126

UCB EECS126 : probability theory and random processes.
Jupyter Notebook
64
star
18

UCB-CS170

This repo contains all the learning materials for UC Berkeley's course CS170 : Efficient Algorithms and Intractable Problems
Jupyter Notebook
61
star
19

Standford_CVX101

Stanford convex optimization course
Jupyter Notebook
56
star
20

MIT6.031-software-construction

learning materials and implementation for MIT6.031: software construction problemsets
Java
55
star
21

cs50_ai

cs50 AI course resources
HTML
54
star
22

CS61C-labs

my implementation for the CS61C labs in 2020 summer version
C
51
star
23

CS224n

all the notes, ppts and homework for CS224n
JavaScript
49
star
24

CS169-Software-Engineering

Learning materials for UCB CS169 : software engineering
36
star
25

CS110L

Stanford CS110L: Safety in Systems Programming
Rust
33
star
26

EE16A

UCB EECS16A Designing Information Devices and Systems I
Jupyter Notebook
30
star
27

UCB-EE120

UC Berkeley signal and system course
Jupyter Notebook
30
star
28

pku-cs-self-learning

This repo is deprecated.
27
star
29

CS186-Rookiedb

My implementation for CS186 proj2 - proj5
Java
27
star
30

pku-os-course

Course website for Operating System course in Peking University.
HTML
13
star
31

PKUFlyingPig

my personal repo
12
star
32

UCB-CS161

computer security
Jupyter Notebook
12
star
33

Hadoop_vs_Spark

研究生课《网络大数据管理理论和应用》大作业项目代码
Java
10
star
34

Thesis-Template

Thesis template for undergraduate students at Peking University.
10
star
35

MIT18.330

undergraduate numerical analysis course in MIT
Jupyter Notebook
8
star
36

CS143-compiler

Learning materials for Stanford Compiler course : CS143
Java
6
star
37

MIT6.1600

Learning resources for MIT6.1600: Foundations of Computer Security.
Python
5
star
38

CS186-proj1

Project 1 for CS186: SQL
Python
4
star
39

ArchiveMachine

the backend of the project of Software Engineering
HTML
4
star
40

RISC-V_CPU

UCB-CS61C project3 : RISC-V CPU design
Python
3
star
41

homepage

My homepage
HTML
3
star
42

os-course

website for operating system course at Peking University
HTML
2
star
43

machine-learning-exercises

codes for the exercises of Machine-Learning by ZhouZhihua
Jupyter Notebook
2
star
44

CS179

CS179 : GPU computing
C++
2
star
45

NeuralNetwork-by-RISC-V

implement a simple MNIST classifier by RISC-V
Python
2
star
46

GameOfLife

C implementation of the Game Of Life
C
1
star
47

dotfiles_MacOS

FlyingPig's Dotfiles repository
Shell
1
star
48

CS186-proj6

My implementation for CS186 project 6: NoSQL
Python
1
star