Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 39 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,55 @@
# 01 Lab 赛道
Repo to store 2025 Hackthon contest entries.

> Ask: samuka007@dragonos.org

## 背景
关键词:operating system, computer network
## 基本信息

提供给大家一个学习的机会和契机,鼓励大家尝试自己尚未有机会开始接触的lab!
赛道:mit6.1810

> [!WARNING]
> 本赛道有五个赛题,请选择其中一个赛题参赛!
姓名:林润新

## 规定
- 1 人一组,完成一项 Lab 赛题
- 最终lab学习成果及文档需要提交 PR 到当前仓库
或提交至 https://gitea.scutosc.cn/ 并发送邮件告知评委
- 选择 DragonOS 系的题目有加分

## 综合评分细则
1. 创新性与难度(25%)
1. 完成的实验难度
2. 实验的新颖度
3. 对现实问题的指导意义
2. 功能完备性(55%)
1. 完成了实验 / 实现了预期功能(35%)
2. 需要实践测试
1. 实践有启发性,实践的可复现性、应用性(15%)
3. 需要写代码的
1. 运行性能(10%)
2. 代码质量(5%)
3. 展示效果(20%)
1. 文档展示
2. 路演效果

## 操作系统方向
## 完成的实验

### 赛题一:MIT 6.S081: Operating System Engineering
[Lab traps: Traps](https://pdos.csail.mit.edu/6.828/2022/labs/traps.html)

#### 背景
麻省理工学院大名鼎鼎的 PDOS 实验室开设的面向MIT本科生的操作系统课程。
[Lab cow: Copy-on-write fork](https://pdos.csail.mit.edu/6.828/2022/labs/cow.html)

#### 任务
[Lab fs: File system](https://pdos.csail.mit.edu/6.828/2022/labs/fs.html):完成了bigfile

参考:
- https://csdiy.wiki/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/MIT6.S081/
- https://pdos.csail.mit.edu/6.828/2021/schedule.html
## 说明
### 测试项目
```lang
git clone https://github.com/Mico-rstar/01-lab-hackthon.git
```

> [!NOTE]
> 要求:完成两个及以上的 Lab 题目
### 目录结构
```plaintext
docs
|
|-----lab-fs.md
|
|-----lab-cow.md
|
|-----lab-traps.md

题目见绿色 Assignment 字体后的链接
![题目见绿色 Assignment 字体后的链接](https://github.com/user-attachments/assets/c348efcb-1c71-4472-bf03-e487aee96ce1)
README.md
```

### 分支
```C
// lab:traps
git checkout traps
// test
bttest
alarmtest

### 赛题二:DragonOS 系统调用 & 修复
// lab:cow
git checkout cow
// test
cowtest

#### 背景
DragonOS 是使用 Rust 编写的,以 Linux 架构作为参考的操作系统。

Repo: https://github.com/DragonOS-Community/DragonOS

当前 DragonOS 内,有不少系统调用,由于各种原因 ( C 与 Rust 语言差异等 ) ,导致调用时常不符合语义/行为不一致。

#### 任务
- 参考 https://bbs.dragonos.org.cn/t/topic/460 (以及最新引入的系统调用注册表,
参考 https://github.com/DragonOS-Community/DragonOS/pull/1164 )在 DragonOS
内添加一个新的系统调用,并在用户态成功调用
- 寻找内核中行为与预期有出入的系统调用,建议寻找静态、接口不一致的错误

#### 参考
一个内核中静态分析得出行为不一致的 Shutdown 错误:

https://github.com/DragonOS-Community/DragonOS/issues/887

## 网络方向

### 赛题三:CS144: Introduction to Computer Networking

#### 背景
CS144 通过提前为网卡硬件、TCP 等组件定义抽象,提供了一套精巧设计的框架,为同学们理解网络模型提供了恰到好处的“题目”,
即,通过框架可以一窥整个计算机网络实现的意图与设计,又得以从重复的工作中抽离出来,将时间投入到理解网络模型与底层原理
当中来。

#### 任务
https://csdiy.wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/CS144/

努力完成一个 TCP 协议栈吧!
- 实现至 checkpoint 3 及以上

### 赛题四:DragonOS Socket Implementation
#### 背景
DragonOS 网络子系统中,Inet 协议簇依赖于 [smoltcp] 库实现。
在Repo https://github.com/Samuka007/dragonos-berkeley-socket 中将网络子系统相关
的框架实现抽离了出来,基于 tap 设备与 Linux Epoll 机制模拟中断,允许在用户空间测试
[`Inet 协议簇`](https://github.com/Samuka007/dragonos-berkeley-socket/tree/master/src/socket/inet)
的功能。

#### 任务
目前实现的协议栈涉及TCP多层状态机的转换,由于 Rust 的借用机制,以及 [smoltcp] 的 Socket 接口不完全与
Berkeley 定义相一致,因此实现上会出现一些冗余的情况,让各层状态机之间的转换变得复杂。

本实验的任务是尝试基于已有的网卡抽象,参考现有的 Inet 协议簇 实现,基于 [smoltcp] 自己实现 TCP Socket,
并尝试在现有的 TCP 实现上予以优化。

## 其他方向
自选实验,需要体现技术栈深度


[smoltcp]: https://crates.io/crates/smoltcp
// lab: fs
git checkout fs
// test
bigfile
```
Binary file added docs/assets/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image-9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 133 additions & 0 deletions docs/lab-cow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
## 题目
https://pdos.csail.mit.edu/6.828/2022/labs/cow.html


## 思路
![alt text](./assets/image-5.png)
1. fork时,直接将子进程页表映射到父进程的物理地址,将父子进程的写权限禁用,标记为cow页
2. 进程写时,触发page fault后trap到内核,在usertrap中处理:
- 如果是cow页,申请新物理页,将内容拷贝到新物理页,修改页表,标记为非cow页,断掉旧的映射(unmap)
- 如果不是cow页,panic
3. 修改kfree,只有引用计数为1时才释放内存
4. 修改kalloc,初始化引用计数=1
5. 修改uvmcopy,引用计数++


## 代码
```C
// 将原来copy的逻辑注释掉,直接将子进程页表映射到父进程的物理地址,将父子进程的写权限禁用,标记为cow页
int
uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
{
pte_t *pte;
uint64 pa, i;
uint flags;
// char *mem;

for(i = 0; i < sz; i += PGSIZE){
if((pte = walk(old, i, 0)) == 0)
panic("uvmcopy: pte should exist");
if((*pte & PTE_V) == 0)
panic("uvmcopy: page not present");

// disable the writing permission if it had,
// make the COW bit 1 if it could write
*pte = PTE_ONCOW(*pte);
pa = PTE2PA(*pte);
flags = PTE_FLAGS(*pte);
// if((mem = kalloc()) == 0)
// goto err;
// memmove(mem, (char*)pa, PGSIZE);
if(mappages(new, i, PGSIZE, pa, flags) != 0){
//kfree(mem);
goto err;
}
incr(pa);
}

return 0;

err:
uvmunmap(new, 0, i / PGSIZE, 1);
return -1;
}
```

在trap处理入口,处理page fault
![alt text](./assets/image-6.png)
```c
// trap.c
else if(r_scause() == 12 || r_scause() == 15 )
{
// page fault
uint64 va = r_stval();
pte_t *pte;
if(va >= MAXVA) goto err;
if((pte = walk(p->pagetable, va, 0)) == 0)
{
printf("usertrap: walk\n");
setkilled(p);
}
if((*pte) & PTE_COW)
{
//printf("before cow: pte = %p\n", *pte);
if(uvmcow(p->pagetable, va) < 0)
{
panic("usertrap: uvmcow");
}
} else{
printf("usertrap: page fault but not cow page\n");
printf("name = %s\n", p->name);
printf("pte = %p\n", *pte);
printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
printf(" sepc=%p stval=%p\n", r_sepc(), r_stval());
setkilled(p);
}

}
```
对于cow页,我们调用uvmcow方法,将cow页映射到新的物理页,并修改pte
```C
// this method can only use when (*pte & PTE_COW) != 0
// unmap the old mapping
// alloc a new writable page for va,
// and map the new page to pgtbl
// return -1 while it is not a cow pte
// return -0 while succeed
int
uvmcow(pagetable_t pgtbl, uint64 va)
{
va = PGROUNDDOWN(va);
pte_t *pte;
if((pte = walk(pgtbl, va, 0)) == 0)
panic("uvmunmap: walk");
if((*pte) & PTE_COW)
{
uint64 pa = PTE2PA(*pte);
uint64 flags = PTE_FLAGS(*pte);
flags &= (~PTE_COW);
flags |= (PTE_W);
// alloc a new page
char *mem;
if((mem = kalloc()) == 0)
panic("uvmcow: not enough page");
memmove(mem, (char*)pa, PGSIZE);

uvmunmap(pgtbl, va, 1, 1);

mappages(pgtbl, va, 1,(uint64) mem, flags);
} else
{
return -1;
}
return 0;
}
```




## 测试结果
![alt text](./assets/image-2.png)


Loading