diff --git a/Makefile b/Makefile index c47b37b..74e454f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ + # To compile and run with a lab solution, set the lab name in conf/lab.mk # (e.g., LAB=util). Run make grade to test solution with the lab's # grade script (e.g., grade-lab-util). @@ -84,7 +85,7 @@ LD = $(TOOLPREFIX)ld OBJCOPY = $(TOOLPREFIX)objcopy OBJDUMP = $(TOOLPREFIX)objdump -CFLAGS = -Wall -Werror -O1 -fno-omit-frame-pointer -ggdb -gdwarf-2 +CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2 ifdef LAB LABUPPER = $(shell echo $(LAB) | tr a-z A-Z) @@ -237,16 +238,15 @@ $U/_uthread: $U/uthread.o $U/uthread_switch.o $(ULIB) $(OBJDUMP) -S $U/_uthread > $U/uthread.asm ph: notxv6/ph.c - gcc -o ph -g -Ofast $(XCFLAGS) notxv6/ph.c -pthread + gcc -o ph -g -O2 $(XCFLAGS) notxv6/ph.c -pthread barrier: notxv6/barrier.c - gcc -o barrier -g -Ofast $(XCFLAGS) notxv6/barrier.c -pthread + gcc -o barrier -g -O2 $(XCFLAGS) notxv6/barrier.c -pthread endif ifeq ($(LAB),pgtbl) UPROGS += \ - $U/_pgtbltest\ - $U/_dirtypagestest + $U/_pgtbltest endif ifeq ($(LAB),lock) @@ -343,7 +343,7 @@ grade: @echo $(MAKE) clean @$(MAKE) clean || \ (echo "'make clean' failed. HINT: Do you have another running instance of xv6?" && exit 1) - python3.12 ./grade-lab-$(LAB) $(GRADEFLAGS) + ./grade-lab-$(LAB) $(GRADEFLAGS) ## ## FOR submissions diff --git a/answers-pgtbl.txt b/answers-pgtbl.txt deleted file mode 100644 index 9427713..0000000 --- a/answers-pgtbl.txt +++ /dev/null @@ -1,153 +0,0 @@ -### 背景信息 -- **页面表结构**: - - 页面大小(`PGSIZE`):通常为 4KB(4096 字节)。 - - 最大虚拟地址(`MAXVA`):在 Sv39 模式下为 2^39(512GB)。 - - 页面表条目(PTE):包含物理地址(PA)、权限位(读/写/执行等)以及有效位(Valid bit)。 - - 三级页面表:PML4(顶级),L2(中间级),L1(最低级),每个页面表包含 512 条目(2^9)。 - - 虚拟地址(VA):39 位,分为 VPN[2](9 位,顶级索引)、VPN[1](9 位,中间级索引)、VPN[0](9 位,最低级索引)和 12 位页面偏移。 -- **`print_pgtbl` 函数**: - - 打印前 10 个页面(VA 从 `0` 到 `9 * PGSIZE`)和最后 10 个页面(接近 `MAXVA`)的页面表条目。 - - 调用 `print_pte`,输出虚拟地址对应的页面表条目信息。 - -### 输出分析 -以下是提供的输出: -``` -xv6 kernel is booting -hart 1 starting -hart 2 starting -page table 0x0000000087f4d000 -0: pte 0x0000000021fd2401 pa 0x0000000087f49000 - ..0: pte 0x0000000021fd2001 pa 0x0000000087f48000 - .. ..0: pte 0x0000000021fd281b pa 0x0000000087f4a000 va 0x0000000000000000 flags RXU - .. ..1: pte 0x0000000021fd1c17 pa 0x0000000087f47000 va 0x0000000000000001 flags RWU - .. ..2: pte 0x0000000021fd1807 pa 0x0000000087f46000 va 0x0000000000000002 flags RW - .. ..3: pte 0x0000000021fd1417 pa 0x0000000087f45000 va 0x0000000000000003 flags RWU -255: pte 0x0000000021fd3001 pa 0x0000000087f4c000 - ..511: pte 0x0000000021fd2c01 pa 0x0000000087f4b000 - .. ..509: pte 0x0000000021fd5413 pa 0x0000000087f55000 va 0x0000000003fffffd flags RU - .. ..510: pte 0x0000000021fd5807 pa 0x0000000087f56000 va 0x0000000003fffffe flags RW - .. ..511: pte 0x000000002000180b pa 0x0000000080006000 va 0x0000000003ffffff flags RX -init: starting sh -``` - -#### 1. **输出结构与 `print_pgtbl` 的关联** -- 输出由 `print_pgtbl` 函数生成,包含: - - **顶级页面表地址**:`page table 0x0000000087f4d000`(根页面表所在的物理地址)。 - - **前几个页面表条目**(对应 `for (uint64 i = 0; i < 10; i++)` 循环): - - 打印顶级页面表索引 0 的条目,以及其下级页面表的条目。 - - 具体为虚拟地址 `0x0` 到 `0x3000`(前 4 个页面)。 - - **最后几个页面表条目**(对应 `for (uint64 i = top - 10; i < top; i++)` 循环): - - 打印顶级页面表索引 255 的条目,以及其下级页面表的最后几个条目(509–511)。 - - 对应虚拟地址接近 `MAXVA`(`0x3fffffd` 到 `0x3ffffff`)。 - - 输出格式: - - 每行表示一个页面表条目,格式为: - ``` - [索引]: pte [PTE值] pa [物理地址] [va 虚拟地址 flags 权限] - ``` - - 缩进(`..`)表示页面表层级:顶级(无缩进)、L2(`..`)、L1(`.. ..`)。 - - 仅 L1 页面表条目包含虚拟地址(`va`)和权限标志(`flags`)。 - -#### 2. **页面表条目解析** -页面表条目(PTE)格式(RISC-V Sv39): -- **PTE 结构**:64 位,包含: - - 物理页面号(PPN):44 位(高 44 位,右移 10 位得到物理页面地址)。 - - 权限位:V(Valid,有效)、R(Read,读)、W(Write,写)、X(Execute,执行)、U(User,用户态可访问)。 - - 其他标志:G(Global)、A(Accessed)、D(Dirty)等。 -- **物理地址(PA)**:从 PTE 的 PPN 字段计算,`PA = PPN << 12`。 -- **权限标志(flags)**:输出中的 `RXU`、`RWU`、`RW` 等表示权限组合: - - `R`:可读,`W`:可写,`X`:可执行,`U`:用户态可访问。 - -##### **前 4 个页面(VA 0x0 到 0x3000)** -- **顶级页面表(索引 0)**: - - `0: pte 0x0000000021fd2401 pa 0x0000000087f49000` - - PTE 值:`0x21fd2401`。 - - 物理地址:`0x87f49000`(L2 页面表地址)。 - - 标志:`0x401` 的低 10 位为 `0x001`,表示 Valid(V=1)。 -- **L2 页面表(索引 0)**: - - `..0: pte 0x0000000021fd2001 pa 0x0000000087f48000` - - PTE 值:`0x21fd2001`。 - - 物理地址:`0x87f48000`(L1 页面表地址)。 - - 标志:Valid(V=1)。 -- **L1 页面表(索引 0–3)**: - - `.. ..0: pte 0x0000000021fd281b pa 0x0000000087f4a000 va 0x0000000000000000 flags RXU` - - 虚拟地址:`0x0`。 - - 物理地址:`0x87f4a000`。 - - 标志:`RXU`(Read, Execute, User),`0x1b` = `0b11011`(V=1, R=1, X=1, U=1)。 - - 用途:可能是内核代码段(可读、可执行、用户态可访问)。 - - `.. ..1: pte 0x0000000021fd1c17 pa 0x0000000087f47000 va 0x0000000000000001 flags RWU` - - 虚拟地址:`0x1000`(1 * PGSIZE)。 - - 物理地址:`0x87f47000`。 - - 标志:`RWU`(Read, Write, User),`0x17` = `0b10111`(V=1, R=1, W=1, U=1)。 - - 用途:可能是数据段或堆栈(可读、可写、用户态可访问)。 - - `.. ..2: pte 0x0000000021fd1807 pa 0x0000000087f46000 va 0x0000000000000002 flags RW` - - 虚拟地址:`0x2000`(2 * PGSIZE)。 - - 物理地址:`0x87f46000`。 - - 标志:`RW`(Read, Write),`0x07` = `0b00111`(V=1, R=1, W=1)。 - - 用途:可能是内核数据(可读、可写,仅内核态)。 - - `.. ..3: pte 0x0000000021fd1417 pa 0x0000000087f45000 va 0x0000000000000003 flags RWU` - - 虚拟地址:`0x3000`(3 * PGSIZE)。 - - 物理地址:`0x87f45000`。 - - 标志:`RWU`(Read, Write, User),`0x17` = `0b10111`(V=1, R=1, W=1, U=1)。 - - 用途:可能是用户态数据或堆栈。 - -##### **最后 3 个页面(VA 0x3fffffd 到 0x3ffffff)** -- **顶级页面表(索引 255)**: - - `255: pte 0x0000000021fd3001 pa 0x0000000087f4c000` - - PTE 值:`0x21fd3001`。 - - 物理地址:`0x87f4c000`(L2 页面表地址)。 - - 标志:Valid(V=1)。 -- **L2 页面表(索引 511)**: - - `..511: pte 0x0000000021fd2c01 pa 0x0000000087f4b000` - - PTE 值:`0x21fd2c01`。 - - 物理地址:`0x87f4b000`(L1 页面表地址)。 - - 标志:Valid(V=1)。 -- **L1 页面表(索引 509–511)**: - - `.. ..509: pte 0x0000000021fd5413 pa 0x0000000087f55000 va 0x0000000003fffffd flags RU` - - 虚拟地址:`0x3fffffd000`(接近 MAXVA)。 - - 物理地址:`0x87f55000`。 - - 标志:`RU`(Read, User),`0x13` = `0b10011`(V=1, R=1, U=1)。 - - 用途:可能是用户态只读数据。 - - `.. ..510: pte 0x0000000021fd5807 pa 0x0000000087f56000 va 0x0000000003fffffe flags RW` - - 虚拟地址:`0x3fffffe000`。 - - 物理地址:`0x87f56000`。 - - 标志:`RW`(Read, Write),`0x07` = `0b00111`(V=1, R=1, W=1)。 - - 用途:可能是内核数据(仅内核态)。 - - `.. ..511: pte 0x000000002000180b pa 0x0000000080006000 va 0x0000000003ffffff flags RX` - - 虚拟地址:`0x3ffffff000`(MAXVA - PGSIZE)。 - - 物理地址:`0x80006000`。 - - 标志:`RX`(Read, Execute),`0x0b` = `0b01011`(V=1, R=1, X=1)。 - - 用途:可能是内核代码或设备映射(可读、可执行,仅内核态)。 - -#### 3. **与 `print_pgtbl` 的关联** -- **前 10 个页面**: - - 输出只显示了虚拟地址 `0x0` 到 `0x3000`(4 个页面),而不是 10 个,可能是因为 `print_pgtbl` 的循环被修改或页面表中只有前 4 个页面有有效映射。 - - 虚拟地址计算: - - `i * PGSIZE`(`i` 从 0 到 3),与输出中的 `va 0x0`、`0x1000`、`0x2000`、`0x3000` 匹配。 -- **最后 10 个页面**: - - 输出显示索引 509–511(虚拟地址 `0x3fffffd000` 到 `0x3ffffff000`),对应 `i` 从 `top - 3` 到 `top - 1`。 - - 计算 `top`: - - `MAXVA = 2^39 = 512GB`,`PGSIZE = 4096`,`top = 512GB / 4096 = 2^27 = 134,217,728`。 - - 虚拟地址 `0x3ffffff`(十进制 2^30 - 1)对应页面号 `2^30 / 4096 = 2^18 - 1 = 262,143`。 - - 顶级索引:`262,143 >> 18 = 255`(匹配 `255:`)。 - - L2 索引:`(262,143 >> 9) & 0x1FF = 511`(匹配 `..511:`)。 - - L1 索引:`262,143 & 0x1FF = 511`(匹配 `.. ..511:`)。 - - 输出只显示最后 3 个页面(509–511),可能是因为只有这些页面有有效映射。 -- **缺失的 `print_pgtbl` 输出**: - - 函数应打印 `"print_pgtbl starting\n"` 和 `"print_pgtbl: OK\n"`,但输出中缺失,可能是被其他日志覆盖或函数被修改。 - -#### 4. **页面表条目含义** -- **前 4 个页面**: - - 映射到物理地址 `0x87f4a000` 到 `0x87f45000`,连续的物理页面。 - - 权限多样(`RXU`、`RWU`、`RW`),表明这些页面用于不同用途: - - `RXU`:用户态代码(例如,初始用户程序)。 - - `RWU`:用户态数据或堆栈。 - - `RW`:内核数据(仅内核态)。 -- **最后 3 个页面**: - - 映射到物理地址 `0x87f55000` 到 `0x80006000`,不完全连续。 - - 权限包括 `RU`(用户态只读)、`RW`(内核读写)、`RX`(内核代码)。 - - 最后一个页面(`va 0x3ffffff000`, `pa 0x80006000`)可能是设备内存映射(常见于内核高地址空间)。 -- **物理地址**: - - 大部分物理地址在 `0x87fxxxxx` 范围内,表明内存分配集中在某一区域。 - - 最后一个页面映射到 `0x80006000`,可能是设备寄存器或内核代码的固定映射。 - - diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index 5a7e80f..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,1198 +0,0 @@ -[ - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/entry.o", - "kernel/entry.S" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/entry.S", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/entry.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/kalloc.o", - "kernel/kalloc.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/kalloc.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/kalloc.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/string.o", - "kernel/string.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/string.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/string.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/main.o", - "kernel/main.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/main.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/main.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/vm.o", - "kernel/vm.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/vm.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/vm.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/proc.o", - "kernel/proc.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/proc.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/proc.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/swtch.o", - "kernel/swtch.S" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/swtch.S", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/swtch.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/trampoline.o", - "kernel/trampoline.S" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/trampoline.S", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/trampoline.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/trap.o", - "kernel/trap.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/trap.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/trap.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/syscall.o", - "kernel/syscall.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/syscall.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/syscall.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/sysproc.o", - "kernel/sysproc.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/sysproc.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/sysproc.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/bio.o", - "kernel/bio.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/bio.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/bio.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/fs.o", - "kernel/fs.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/fs.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/fs.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/log.o", - "kernel/log.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/log.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/log.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/sleeplock.o", - "kernel/sleeplock.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/sleeplock.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/sleeplock.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/file.o", - "kernel/file.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/file.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/file.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/pipe.o", - "kernel/pipe.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/pipe.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/pipe.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/exec.o", - "kernel/exec.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/exec.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/exec.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/sysfile.o", - "kernel/sysfile.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/sysfile.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/sysfile.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/kernelvec.o", - "kernel/kernelvec.S" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/kernelvec.S", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/kernelvec.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/plic.o", - "kernel/plic.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/plic.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/plic.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/virtio_disk.o", - "kernel/virtio_disk.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/virtio_disk.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/virtio_disk.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/start.o", - "kernel/start.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/start.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/start.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/console.o", - "kernel/console.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/console.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/console.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/printf.o", - "kernel/printf.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/printf.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/printf.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/uart.o", - "kernel/uart.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/uart.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/uart.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "kernel/spinlock.o", - "kernel/spinlock.c" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/kernel/spinlock.c", - "output": "/home/gh0s7/project/csail/xv6-labs/kernel/spinlock.o" - }, - { - "arguments": [ - "/usr/bin/riscv64-unknown-elf-gcc", - "-Wall", - "-Werror", - "-O", - "-fno-omit-frame-pointer", - "-ggdb", - "-gdwarf-2", - "-DSOL_PGTBL", - "-DLAB_PGTBL", - "-mcmodel=medany", - "-fno-common", - "-fno-builtin-strncpy", - "-fno-builtin-strncmp", - "-fno-builtin-strlen", - "-fno-builtin-memset", - "-fno-builtin-memmove", - "-fno-builtin-memcmp", - "-fno-builtin-log", - "-fno-builtin-bzero", - "-fno-builtin-strchr", - "-fno-builtin-exit", - "-fno-builtin-malloc", - "-fno-builtin-putc", - "-fno-builtin-free", - "-fno-builtin-memcpy", - "-Wno-main", - "-fno-builtin-printf", - "-fno-builtin-fprintf", - "-fno-builtin-vprintf", - "-I.", - "-fno-stack-protector", - "-fno-pie", - "-march=rv64g", - "-nostdinc", - "-I.", - "-Ikernel", - "-c", - "-I", - "/usr/share/verilator/include", - "-I", - "/usr/share/verilator/include", - "-o", - "user/initcode.o", - "user/initcode.S" - ], - "directory": "/home/gh0s7/project/csail/xv6-labs", - "file": "/home/gh0s7/project/csail/xv6-labs/user/initcode.S", - "output": "/home/gh0s7/project/csail/xv6-labs/user/initcode.o" - } -] diff --git a/conf/lab.mk b/conf/lab.mk index 2992d87..2b9988d 100644 --- a/conf/lab.mk +++ b/conf/lab.mk @@ -1 +1 @@ -LAB=pgtbl +LAB=traps diff --git a/grade-lab-pgtbl b/grade-lab-pgtbl deleted file mode 100755 index d49ed6b..0000000 --- a/grade-lab-pgtbl +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -import re -from gradelib import * - -r = Runner(save("xv6.out")) - -@test(0, "pgtbltest") -def test_pgtbltest(): - r.run_qemu(shell_script([ - 'pgtbltest' - ]), timeout=300) - -@test(10, "pgtbltest: ugetpid", parent=test_pgtbltest) -def test_ugetpid_(): - r.match('^ugetpid_test: OK$') - -@test(10, "pgtbltest: print_kpgtbl", parent=test_pgtbltest) -def test_print_kpgtbl_(): - r.match( - '^page table 0x', - '^ \.\.0x0000000000000000', - '^ \.\. \.\.0x0000000000000000', - '^ \.\. \.\. \.\.0x0000000000000000', - '^ \.\. \.\. \.\.0x0000000000001000', - '^ \.\. \.\. \.\.0x0000000000002000', - '^ \.\. \.\. \.\.0x0000000000003000', - '^ \.\.(0xffffffffc0000000|0x0000003fc0000000)', - '^ \.\. \.\.(0xffffffffffe00000|0x0000003fffe00000)', - '^ \.\. \.\. \.\.(0xffffffffffffd000|0x0000003fffffd000)', - '^ \.\. \.\. \.\.(0xffffffffffffe000|0x0000003fffffe000)', - '^ \.\. \.\. \.\.(0xfffffffffffff000|0x0000003ffffff000)', - ) - -@test(10, "pgtbltest: pgaccess", parent=test_pgtbltest) -def test_nettest_(): - r.match('^pgaccess_test: OK$') - -@test(15, "pgtbltest: superpg", parent=test_pgtbltest) -def test_superpg_(): - r.match('^superpg_test: OK$') - -@test(5, "answers-pgtbl.txt") -def test_answers(): - # just a simple sanity check, will be graded manually - check_answers("answers-pgtbl.txt") - -@test(0, "usertests") -def test_usertests(): - r.run_qemu(shell_script([ - 'usertests -q' - ]), timeout=300) - -@test(10, "usertests: all tests", parent=test_usertests) -def test_usertests(): - r.match('^ALL TESTS PASSED$') - -@test(1, "time") -def test_time(): - check_time() - -run_tests() diff --git a/grade-lab-traps b/grade-lab-traps new file mode 100644 index 0000000..10613d3 --- /dev/null +++ b/grade-lab-traps @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +import os +import re +import subprocess +from gradelib import * + +r = Runner(save("xv6.out")) + +@test(5, "answers-traps.txt") +def test_answers(): + # just a simple sanity check, will be graded manually + check_answers("answers-traps.txt") + +BACKTRACE_RE = r"^(0x000000008[0-9a-f]+)" + +def addr2line(): + for f in ['riscv64-unknown-elf-addr2line', 'riscv64-linux-gnu-addr2line', 'addr2line', ]: + try: + devnull = open(os.devnull) + subprocess.Popen([f], stdout=devnull, stderr=devnull).communicate() + return f + except OSError: + continue + raise AssertionError('Cannot find the addr2line program') + +@test(10, "backtrace test") +def test_backtracetest(): + r.run_qemu(shell_script([ + 'bttest' + ])) + a2l = addr2line() + matches = re.findall(BACKTRACE_RE, r.qemu.output, re.MULTILINE) + assert_equal(len(matches), 3) + files = ['sysproc.c', 'syscall.c', 'trap.c'] + for f, m in zip(files, matches): + result = subprocess.run([a2l, '-e', 'kernel/kernel', m], stdout=subprocess.PIPE) + if not f in result.stdout.decode("utf-8"): + raise AssertionError('Trace is incorrect; no %s' % f) + +@test(0, "running alarmtest") +def test_alarmtest(): + r.run_qemu(shell_script([ + 'alarmtest' + ])) + +@test(20, "alarmtest: test0", parent=test_alarmtest) +def test_alarmtest_test0(): + r.match('^test0 passed$') + +@test(20, "alarmtest: test1", parent=test_alarmtest) +def test_alarmtest_test1(): + r.match('^\\.?test1 passed$') + +@test(10, "alarmtest: test2", parent=test_alarmtest) +def test_alarmtest_test2(): + r.match('^\\.?test2 passed$') + +@test(10, "alarmtest: test3", parent=test_alarmtest) +def test_alarmtest_test3(): + r.match('^test3 passed$') + +@test(19, "usertests") +def test_usertests(): + r.run_qemu(shell_script([ + 'usertests -q' + ]), timeout=300) + r.match('^ALL TESTS PASSED$') + +@test(1, "time") +def test_time(): + check_time() + +run_tests() diff --git a/kernel/defs.h b/kernel/defs.h index 6a16310..d1b6bb9 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -1,7 +1,3 @@ -#ifdef LAB_MMAP -typedef unsigned long size_t; -typedef long int off_t; -#endif struct buf; struct context; struct file; @@ -121,10 +117,6 @@ void initlock(struct spinlock*, char*); void release(struct spinlock*); void push_off(void); void pop_off(void); -int atomic_read4(int *addr); -#ifdef LAB_LOCK -void freelock(struct spinlock*); -#endif // sleeplock.c void acquiresleep(struct sleeplock*); @@ -181,17 +173,6 @@ uint64 walkaddr(pagetable_t, uint64); int copyout(pagetable_t, uint64, char *, uint64); int copyin(pagetable_t, char *, uint64, uint64); int copyinstr(pagetable_t, char *, uint64, uint64); -#if defined(LAB_PGTBL) || defined(SOL_MMAP) -void vmprint(pagetable_t); -#endif -#ifdef LAB_PGTBL -pte_t* pgpte(pagetable_t, uint64); -void superfree(void *pa); -void* superalloc(); -int copyin_new(pagetable_t, char *, uint64, uint64); -int copyinstr_new(pagetable_t, char *, uint64, uint64); -uint64 sys_dirtypages(void); -#endif // plic.c void plicinit(void); @@ -206,31 +187,3 @@ void virtio_disk_intr(void); // number of elements in fixed-size array #define NELEM(x) (sizeof(x)/sizeof((x)[0])) - -#ifdef LAB_LOCK -// stats.c -void statsinit(void); -void statsinc(void); - -// sprintf.c -int snprintf(char*, unsigned long, const char*, ...); -#endif - -#ifdef KCSAN -void kcsaninit(); -#endif - -#ifdef LAB_NET -// pci.c -void pci_init(); - -// e1000.c -void e1000_init(uint32 *); -void e1000_intr(void); -int e1000_transmit(char *, int); - -// net.c -void netinit(void); -void net_rx(char *buf, int len); - -#endif diff --git a/kernel/exec.c b/kernel/exec.c index ad7a108..6d7c452 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -128,10 +128,6 @@ exec(char *path, char **argv) p->trapframe->sp = sp; // initial stack pointer proc_freepagetable(oldpagetable, oldsz); - if (p->pid == 1) { - vmprint(p->pagetable); - } - return argc; // this ends up in a0, the first argument to main(argc, argv) bad: diff --git a/kernel/kalloc.c b/kernel/kalloc.c index 9448ab9..0699e7e 100644 --- a/kernel/kalloc.c +++ b/kernel/kalloc.c @@ -23,46 +23,10 @@ struct { struct run *freelist; } kmem; -struct super_run { - struct super_run *next; -}; - -struct { - struct spinlock lock; - struct super_run *freelist; -} skmem; - -void superfree(void *pa) { - struct super_run *r; - - if(((uint64)pa % SUPERPGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP) - panic("superfree"); - - // Fill with junk to catch dangling refs. - memset(pa, 1, SUPERPGSIZE); - - r = (struct super_run *)pa; - acquire(&skmem.lock); - r->next = skmem.freelist; - skmem.freelist = r; - release(&skmem.lock); -} - -void* superalloc() { - struct super_run *r; - acquire(&skmem.lock); - r = skmem.freelist; - if(r) skmem.freelist = r->next; - release(&skmem.lock); - if(r) memset((void*)r, 0, SUPERPGSIZE); - return (void*)r; -} - void kinit() { initlock(&kmem.lock, "kmem"); - initlock(&skmem.lock, "skmem"); freerange(end, (void*)PHYSTOP); } @@ -71,22 +35,9 @@ freerange(void *pa_start, void *pa_end) { char *p; p = (char*)PGROUNDUP((uint64)pa_start); - for(; p + PGSIZE <= (char*)pa_end - 12 * 1024 * 1024; p += PGSIZE) //留5个巨页 + for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE) kfree(p); - - p = (char*)SUPERPGROUNDUP((uint64)p); - for (; p + SUPERPGSIZE <= (char *)pa_end; p += SUPERPGSIZE) { - superfree(p); - } } -// void -// freerange(void *pa_start, void *pa_end) -// { -// char *p; -// p = (char*)PGROUNDUP((uint64)pa_start); -// for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE) -// kfree(p); -// } // Free the page of physical memory pointed at by pa, // which normally should have been returned by a diff --git a/kernel/memlayout.h b/kernel/memlayout.h index 0a5679b..3ab2ace 100644 --- a/kernel/memlayout.h +++ b/kernel/memlayout.h @@ -25,10 +25,6 @@ #define VIRTIO0 0x10001000 #define VIRTIO0_IRQ 1 -#ifdef LAB_NET -#define E1000_IRQ 33 -#endif - // qemu puts platform-level interrupt controller (PLIC) here. #define PLIC 0x0c000000L #define PLIC_PRIORITY (PLIC + 0x0) @@ -49,7 +45,7 @@ // map kernel stacks beneath the trampoline, // each surrounded by invalid guard pages. -#define KSTACK(p) (TRAMPOLINE - (p)*2*PGSIZE - 3*PGSIZE) +#define KSTACK(p) (TRAMPOLINE - ((p)+1)* 2*PGSIZE) // User memory layout. // Address zero first: @@ -58,14 +54,6 @@ // fixed-size stack // expandable heap // ... -// USYSCALL (shared with kernel) // TRAPFRAME (p->trapframe, used by the trampoline) // TRAMPOLINE (the same page as in the kernel) #define TRAPFRAME (TRAMPOLINE - PGSIZE) -#ifdef LAB_PGTBL -#define USYSCALL (TRAPFRAME - PGSIZE) - -struct usyscall { - int pid; // Process ID -}; -#endif diff --git a/kernel/proc.c b/kernel/proc.c index af002b4..130d9ce 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -123,20 +123,14 @@ allocproc(void) found: p->pid = allocpid(); + p->state = USED; // Allocate a trapframe page. if((p->trapframe = (struct trapframe *)kalloc()) == 0){ - release(&p->lock); - return 0; - } - - // Allocate a usyscall page. - if((p->usyscall = (struct usyscall *)kalloc()) == 0){ freeproc(p); release(&p->lock); return 0; } - p->usyscall->pid = p->pid ; // An empty user page table. p->pagetable = proc_pagetable(p); @@ -161,9 +155,6 @@ found: static void freeproc(struct proc *p) { - if (p->usyscall) { - kfree((void*)p->usyscall); - } if(p->trapframe) kfree((void*)p->trapframe); p->trapframe = 0; @@ -211,16 +202,6 @@ proc_pagetable(struct proc *p) return 0; } - // map the usyscall just below TRAMPOFRAME, for trampoline.S. - // 这个页需要设置PTE_U为,使得用户态可以访问 - if(mappages(pagetable, USYSCALL, PGSIZE, - (uint64)(p->usyscall), PTE_R | PTE_U) < 0){ - uvmunmap(pagetable, TRAPFRAME, 1, 0); - uvmunmap(pagetable, TRAMPOLINE, 1, 0); - uvmfree(pagetable, 0); - return 0; - } - return pagetable; } @@ -229,7 +210,6 @@ proc_pagetable(struct proc *p) void proc_freepagetable(pagetable_t pagetable, uint64 sz) { - uvmunmap(pagetable, USYSCALL, 1, 0); uvmunmap(pagetable, TRAMPOLINE, 1, 0); uvmunmap(pagetable, TRAPFRAME, 1, 0); uvmfree(pagetable, sz); @@ -401,20 +381,8 @@ exit(int status) release(&wait_lock); // Jump into the scheduler, never to return. - // If we somehow return from sched(), we're in a bad state sched(); - - // If we reach here, something is very wrong. - // But instead of panicking immediately, try to become truly unrunnable - acquire(&p->lock); - p->state = UNUSED; // Mark as unused to prevent rescheduling - release(&p->lock); - - // Try one more time to schedule - sched(); - - // If we still reach here after marking as UNUSED, panic - panic("zombie exit: process returned from sched twice"); + panic("zombie exit"); } // Wait for a child process to exit and return its pid. diff --git a/kernel/proc.h b/kernel/proc.h index 0af737d..d021857 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -94,12 +94,11 @@ struct proc { // wait_lock must be held when using this: struct proc *parent; // Parent process - // these are private to the process, so p->lock need not be held. + + // these are private to the process, so p->lock need not be held. uint64 kstack; // Virtual address of kernel stack uint64 sz; // Size of process memory (bytes) pagetable_t pagetable; // User page table - // 进程的结构体中需要加上usyscall字段 - struct usyscall *usyscall; // data page for usyscall struct trapframe *trapframe; // data page for trampoline.S struct context context; // swtch() here to run process struct file *ofile[NOFILE]; // Open files diff --git a/kernel/ramdisk.c b/kernel/ramdisk.c deleted file mode 100644 index eb60ee7..0000000 --- a/kernel/ramdisk.c +++ /dev/null @@ -1,45 +0,0 @@ -// -// ramdisk that uses the disk image loaded by qemu -initrd fs.img -// - -#include "types.h" -#include "riscv.h" -#include "defs.h" -#include "param.h" -#include "memlayout.h" -#include "spinlock.h" -#include "sleeplock.h" -#include "fs.h" -#include "buf.h" - -void -ramdiskinit(void) -{ -} - -// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. -// Else if B_VALID is not set, read buf from disk, set B_VALID. -void -ramdiskrw(struct buf *b) -{ - if(!holdingsleep(&b->lock)) - panic("ramdiskrw: buf not locked"); - if((b->flags & (B_VALID|B_DIRTY)) == B_VALID) - panic("ramdiskrw: nothing to do"); - - if(b->blockno >= FSSIZE) - panic("ramdiskrw: blockno too big"); - - uint64 diskaddr = b->blockno * BSIZE; - char *addr = (char *)RAMDISK + diskaddr; - - if(b->flags & B_DIRTY){ - // write - memmove(addr, b->data, BSIZE); - b->flags &= ~B_DIRTY; - } else { - // read - memmove(b->data, addr, BSIZE); - b->flags |= B_VALID; - } -} diff --git a/kernel/riscv.h b/kernel/riscv.h index 4c1fd2b..f7aaa8a 100644 --- a/kernel/riscv.h +++ b/kernel/riscv.h @@ -204,7 +204,7 @@ r_menvcfg() static inline void w_menvcfg(uint64 x) { - //asm volatile("csrw menvcfg, %0" : : "r" (x)); + // asm volatile("csrw menvcfg, %0" : : "r" (x)); asm volatile("csrw 0x30a, %0" : : "r" (x)); } @@ -314,14 +314,6 @@ r_sp() return x; } -static inline uint64 -r_fp() -{ - uint64 x; - asm volatile("mv %0, s0" : "=r" (x) ); - return x; -} - // read and write tp, the thread pointer, which xv6 uses to hold // this core's hartid (core number), the index into cpus[]. static inline uint64 @@ -362,11 +354,6 @@ typedef uint64 *pagetable_t; // 512 PTEs #define PGSIZE 4096 // bytes per page #define PGSHIFT 12 // bits of offset within a page -#ifdef LAB_PGTBL -#define SUPERPGSIZE (2 * (1 << 20)) // bytes per page -#define SUPERPGROUNDUP(sz) (((sz)+SUPERPGSIZE-1) & ~(SUPERPGSIZE-1)) -#endif - #define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) @@ -375,14 +362,6 @@ typedef uint64 *pagetable_t; // 512 PTEs #define PTE_W (1L << 2) #define PTE_X (1L << 3) #define PTE_U (1L << 4) // user can access -#define PTE_A (1L << 6) // Accessed bit -#define PTE_D (1L << 7) // Dirty bit -#define PTE_PS (1L << 8) // Page Size bit in PTE (for 2MB superpages) - - -#if defined(LAB_MMAP) || defined(LAB_PGTBL) -#define PTE_LEAF(pte) (((pte) & PTE_R) | ((pte) & PTE_W) | ((pte) & PTE_X)) -#endif // shift a physical address to the right place for a PTE. #define PA2PTE(pa) ((((uint64)pa) >> 12) << 10) diff --git a/kernel/syscall.c b/kernel/syscall.c index ad864ed..ed65409 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -102,19 +102,6 @@ extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); -#ifdef LAB_NET -extern uint64 sys_bind(void); -extern uint64 sys_unbind(void); -extern uint64 sys_send(void); -extern uint64 sys_recv(void); -#endif -#ifdef LAB_PGTBL -extern uint64 sys_pgpte(void); -extern uint64 sys_kpgtbl(void); -extern uint64 sys_pgaccess(void); -extern uint64 sys_dirtypages(void); -#endif - // An array mapping syscall numbers from syscall.h // to the function that handles the system call. static uint64 (*syscalls[])(void) = { @@ -139,22 +126,8 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, -#ifdef LAB_NET -[SYS_bind] sys_bind, -[SYS_unbind] sys_unbind, -[SYS_send] sys_send, -[SYS_recv] sys_recv, -#endif -#ifdef LAB_PGTBL -[SYS_pgpte] sys_pgpte, -[SYS_kpgtbl] sys_kpgtbl, -[SYS_pgaccess] sys_pgaccess, -[SYS_dirtypages] sys_dirtypages, -#endif }; - - void syscall(void) { diff --git a/kernel/syscall.h b/kernel/syscall.h index 84fc882..bc5f356 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -20,20 +20,3 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 - -// System calls for labs -#define SYS_trace 22 -#define SYS_sysinfo 23 -#define SYS_sigalarm 24 -#define SYS_sigreturn 25 -#define SYS_symlink 26 -#define SYS_mmap 27 -#define SYS_munmap 28 -#define SYS_bind 29 -#define SYS_unbind 30 -#define SYS_send 31 -#define SYS_recv 32 -#define SYS_pgpte 33 -#define SYS_kpgtbl 34 -#define SYS_pgaccess 35 -#define SYS_dirtypages 36 diff --git a/kernel/sysinfo.h b/kernel/sysinfo.h deleted file mode 100644 index 4548f34..0000000 --- a/kernel/sysinfo.h +++ /dev/null @@ -1,7 +0,0 @@ -#include "kernel/types.h" -struct sysinfo { - uint64 freemem; - uint64 nproc; - uint64 unused_proc_num; - uint64 load_avg; -}; diff --git a/kernel/sysproc.c b/kernel/sysproc.c index 593cd02..3b4d5bd 100644 --- a/kernel/sysproc.c +++ b/kernel/sysproc.c @@ -1,7 +1,7 @@ #include "types.h" #include "riscv.h" -#include "param.h" #include "defs.h" +#include "param.h" #include "memlayout.h" #include "spinlock.h" #include "proc.h" @@ -54,7 +54,6 @@ sys_sleep(void) int n; uint ticks0; - argint(0, &n); if(n < 0) n = 0; @@ -71,37 +70,6 @@ sys_sleep(void) return 0; } - -#ifdef LAB_PGTBL -int -sys_pgpte(void) -{ - uint64 va; - struct proc *p; - - p = myproc(); - argaddr(0, &va); - pte_t *pte = pgpte(p->pagetable, va); - if(pte != 0) { - return (uint64) *pte; - } - return 0; -} -#endif - -#ifdef LAB_PGTBL -int -sys_kpgtbl(void) -{ - struct proc *p; - - p = myproc(); - vmprint(p->pagetable); - return 0; -} -#endif - - uint64 sys_kill(void) { @@ -123,82 +91,3 @@ sys_uptime(void) release(&tickslock); return xticks; } - -uint64 -sys_pgaccess(void) - { - // lab pgtbl: your code here. - struct proc *p = myproc(); - unsigned int abits=0; - - uint64 addr; - argaddr(0, &addr); - - int num; - argint(1,&num); - - uint64 dest; - argaddr(2, &dest); - - - for(int i=0;ipagetable, query_addr, 0); - if(*pte&PTE_A) - { - abits=abits|(1<pagetable,dest,(char*)&abits, sizeof(abits)) < 0) - return -1; - - - - return 0; - } - -#ifdef LAB_PGTBL -uint64 -sys_dirtypages(void) -{ - struct proc *p = myproc(); - unsigned int dbits = 0; - - uint64 addr; - argaddr(0, &addr); - - int num; - argint(1, &num); - - uint64 dest; - argaddr(2, &dest); - - // Check each page in the range - for(int i = 0; i < num; i++){ - uint64 query_addr = addr + i * PGSIZE; - - pte_t *pte = walk(p->pagetable, query_addr, 0); - if(pte == 0) - continue; // Skip pages that don't exist - - if(*pte & PTE_D) { - dbits = dbits | (1 << i); - // Clear the dirty bit after reading it - *pte = (*pte) & (~PTE_D); - } - } - - // Copy the result back to user space - if(copyout(p->pagetable, dest, (char*)&dbits, sizeof(dbits)) < 0) - return -1; - - return 0; -} -#endif diff --git a/kernel/vm.c b/kernel/vm.c index 739e079..62421a2 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -4,8 +4,6 @@ #include "elf.h" #include "riscv.h" #include "defs.h" -#include "spinlock.h" -#include "proc.h" #include "fs.h" /* @@ -17,9 +15,6 @@ extern char etext[]; // kernel.ld sets this to end of kernel code. extern char trampoline[]; // trampoline.S -// void sub_vmprint(pagetable_t pagetable, int level); - - // Make a direct-map page table for the kernel. pagetable_t kvmmake(void) @@ -35,14 +30,6 @@ kvmmake(void) // virtio mmio disk interface kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W); -#ifdef LAB_NET - // PCI-E ECAM (configuration space), for pci.c - kvmmap(kpgtbl, 0x30000000L, 0x30000000L, 0x10000000, PTE_R | PTE_W); - - // pci.c maps the e1000's registers here. - kvmmap(kpgtbl, 0x40000000L, 0x40000000L, 0x20000, PTE_R | PTE_W); -#endif - // PLIC kvmmap(kpgtbl, PLIC, PLIC, 0x4000000, PTE_R | PTE_W); @@ -99,17 +86,12 @@ pte_t * walk(pagetable_t pagetable, uint64 va, int alloc) { if(va >= MAXVA) - return 0; + panic("walk"); for(int level = 2; level > 0; level--) { pte_t *pte = &pagetable[PX(level, va)]; if(*pte & PTE_V) { pagetable = (pagetable_t)PTE2PA(*pte); -#ifdef LAB_PGTBL - if (*pte & PTE_PS) { - return pte; - } -#endif } else { if(!alloc || (pagetable = (pde_t*)kalloc()) == 0) return 0; @@ -120,25 +102,6 @@ walk(pagetable_t pagetable, uint64 va, int alloc) return &pagetable[PX(0, va)]; } -pte_t * -super_walk(pagetable_t pagetable, uint64 va, int alloc) -{ - if (va >= MAXVA) - return 0; - - pte_t *pte = &(pagetable[PX(2, va)]); - if (*pte & PTE_V) { - pagetable = (pagetable_t)PTE2PA(*pte); - } else { - if (!alloc || (pagetable = (pde_t*)kalloc()) == 0) - return 0; - memset(pagetable, 0, PGSIZE); - *pte = PA2PTE(pagetable) | PTE_V; - } - - return &pagetable[PX(1, va)]; -} - // Look up a virtual address, return the physical address, // or 0 if not mapped. // Can only be used to look up user pages. @@ -159,17 +122,9 @@ walkaddr(pagetable_t pagetable, uint64 va) if((*pte & PTE_U) == 0) return 0; pa = PTE2PA(*pte); - if(*pte & PTE_PS) { - // For superpages, add the offset within the superpage - pa += va & (SUPERPGSIZE - 1); - } else { - // For regular pages, add the offset within the page - pa += va & (PGSIZE - 1); - } return pa; } - // add a mapping to the kernel page table. // only used when booting. // does not flush TLB or enable paging. @@ -201,35 +156,18 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) panic("mappages: size"); a = va; - - if ((perm & PTE_PS) == 0) { /*不使用巨页*/ - last = va + size - PGSIZE; - for(;;){ - if((pte = walk(pagetable, a, 1)) == 0) - return -1; - if(*pte & PTE_V) - panic("mappages: remap"); - *pte = PA2PTE(pa) | perm | PTE_V; - if(a == last) - break; - a += PGSIZE; - pa += PGSIZE; - } - } else { /* 使用巨页 */ - last = va + size - SUPERPGSIZE; - for (;;) { - if ((pte = super_walk(pagetable, a, 1)) == 0) - return -1; - if (*pte & PTE_V) - panic("super mappages: remap"); - *pte = PA2PTE(pa) | perm | PTE_V; - if (a == last) - break; - a += SUPERPGSIZE; - pa += SUPERPGSIZE; - } + last = va + size - PGSIZE; + for(;;){ + if((pte = walk(pagetable, a, 1)) == 0) + return -1; + if(*pte & PTE_V) + panic("mappages: remap"); + *pte = PA2PTE(pa) | perm | PTE_V; + if(a == last) + break; + a += PGSIZE; + pa += PGSIZE; } - return 0; } @@ -241,42 +179,22 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free) { uint64 a; pte_t *pte; - uint64 end_va = va + npages * PGSIZE; if((va % PGSIZE) != 0) panic("uvmunmap: not aligned"); - - for(a = va; a < end_va; ){ - if((pte = walk(pagetable, a, 0)) == 0) { - // If we can't find a PTE, skip to next page - a += PGSIZE; - continue; - } - if((*pte & PTE_V) == 0) { - // If page is not valid, skip to next page - a += PGSIZE; - continue; - } + + for(a = va; a < va + npages*PGSIZE; a += PGSIZE){ + if((pte = walk(pagetable, a, 0)) == 0) + panic("uvmunmap: walk"); + if((*pte & PTE_V) == 0) + panic("uvmunmap: not mapped"); if(PTE_FLAGS(*pte) == PTE_V) panic("uvmunmap: not a leaf"); - - if ((*pte & PTE_PS)) { /* 释放巨页 */ - if(do_free){ - uint64 pa = PTE2PA(*pte); - superfree((void*)pa); - } - *pte = 0; - // Make sure we don't go beyond the requested range - uint64 next_a = a + SUPERPGSIZE; - a = (next_a > end_va) ? end_va : next_a; - } else { - if(do_free){ - uint64 pa = PTE2PA(*pte); - kfree((void*)pa); - } - *pte = 0; - a += PGSIZE; + if(do_free){ + uint64 pa = PTE2PA(*pte); + kfree((void*)pa); } + *pte = 0; } } @@ -309,7 +227,6 @@ uvmfirst(pagetable_t pagetable, uchar *src, uint sz) memmove(mem, src, sz); } - // Allocate PTEs and physical memory to grow process from oldsz to // newsz, which need not be page aligned. Returns new size or 0 on error. uint64 @@ -317,85 +234,24 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm) { char *mem; uint64 a; - + if(newsz < oldsz) return oldsz; oldsz = PGROUNDUP(oldsz); - - // Check if the allocation should use superpages - // We use superpages if we're allocating at least 2MB AND - // the range contains a superpage-aligned 2MB region - if (newsz - oldsz >= SUPERPGSIZE) { - uint64 super_start = SUPERPGROUNDUP(oldsz); - uint64 super_end = newsz & ~(SUPERPGSIZE - 1); // Round down to superpage boundary - - // Allocate regular pages before the first superpage boundary - for(a = oldsz; a < super_start; a += PGSIZE){ - mem = kalloc(); - if(mem == 0){ - uvmdealloc(pagetable, a, oldsz); - return 0; - } - #ifndef LAB_SYSCALL - memset(mem, 0, PGSIZE); - #endif - if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){ - kfree(mem); - uvmdealloc(pagetable, a, oldsz); - return 0; - } + for(a = oldsz; a < newsz; a += PGSIZE){ + mem = kalloc(); + if(mem == 0){ + uvmdealloc(pagetable, a, oldsz); + return 0; } - - // Allocate superpages for aligned regions - for (a = super_start; a < super_end; a += SUPERPGSIZE) { - mem = superalloc(); - if (mem == 0) { - uvmdealloc(pagetable, super_start, oldsz); - return 0; - } - if (mappages(pagetable, a, SUPERPGSIZE, (uint64)mem, PTE_R | PTE_U | PTE_PS | xperm) != 0) { - superfree(mem); - uvmdealloc(pagetable, super_start, oldsz); - return 0; - } - } - - // Allocate regular pages after the last superpage boundary - for(a = super_end; a < newsz; a += PGSIZE){ - mem = kalloc(); - if(mem == 0){ - uvmdealloc(pagetable, a, oldsz); - return 0; - } - #ifndef LAB_SYSCALL - memset(mem, 0, PGSIZE); - #endif - if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){ - kfree(mem); - uvmdealloc(pagetable, a, oldsz); - return 0; - } - } - } else { - // Allocation is smaller than SUPERPGSIZE, use regular pages - for(a = oldsz; a < newsz; a += PGSIZE){ - mem = kalloc(); - if(mem == 0){ - uvmdealloc(pagetable, a, oldsz); - return 0; - } - #ifndef LAB_SYSCALL - memset(mem, 0, PGSIZE); - #endif - if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){ - kfree(mem); - uvmdealloc(pagetable, a, oldsz); - return 0; - } + memset(mem, 0, PGSIZE); + if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){ + kfree(mem); + uvmdealloc(pagetable, a, oldsz); + return 0; } } - return newsz; } @@ -460,54 +316,26 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) uint64 pa, i; uint flags; char *mem; - int szinc; - for(i = 0; i < sz; i += szinc){ - szinc = PGSIZE; + 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"); pa = PTE2PA(*pte); flags = PTE_FLAGS(*pte); - - if ((flags & PTE_PS) == 0) { - if((mem = kalloc()) == 0) - goto err; - memmove(mem, (char*)pa, PGSIZE); - if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){ - kfree(mem); - goto err; - } - } else { - if ((mem = superalloc()) == 0) - goto err; - if (mappages(new, i, SUPERPGSIZE, (uint64)mem, flags) != 0) { - superfree(mem); - goto err; - } - memmove(mem, (char*)pa, SUPERPGSIZE); - szinc = SUPERPGSIZE; /* 修正步长 */ + if((mem = kalloc()) == 0) + goto err; + memmove(mem, (char*)pa, PGSIZE); + if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){ + kfree(mem); + goto err; } } return 0; err: - // Clean up properly - need to unmap what we've mapped so far - for(uint64 j = 0; j < i; j += PGSIZE) { - pte_t *cleanup_pte = walk(new, j, 0); - if(cleanup_pte && (*cleanup_pte & PTE_V)) { - if(*cleanup_pte & PTE_PS) { - // This is a superpage, skip ahead - superfree((void*)PTE2PA(*cleanup_pte)); - *cleanup_pte = 0; - j += SUPERPGSIZE - PGSIZE; // Will be incremented by PGSIZE in loop - } else { - kfree((void*)PTE2PA(*cleanup_pte)); - *cleanup_pte = 0; - } - } - } + uvmunmap(new, 0, i / PGSIZE, 1); return -1; } @@ -535,32 +363,21 @@ copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) while(len > 0){ va0 = PGROUNDDOWN(dstva); - if (va0 >= MAXVA) + if(va0 >= MAXVA) return -1; - if((pte = walk(pagetable, va0, 0)) == 0) { - // printf("copyout: pte should exist 0x%x %d\n", dstva, len); + pte = walk(pagetable, va0, 0); + if(pte == 0 || (*pte & PTE_V) == 0 || (*pte & PTE_U) == 0 || + (*pte & PTE_W) == 0) return -1; - } - - // forbid copyout over read-only user text pages. - if((*pte & PTE_W) == 0) - return -1; - - pa0 = walkaddr(pagetable, va0); - if(pa0 == 0) - return -1; - - // Calculate the correct page size and boundary - uint64 pgsize = (*pte & PTE_PS) ? SUPERPGSIZE : PGSIZE; - uint64 va_base = va0 & ~(pgsize - 1); - n = pgsize - (dstva - va_base); + pa0 = PTE2PA(*pte); + n = PGSIZE - (dstva - va0); if(n > len) n = len; - memmove((void *)(pa0 + (dstva - va_base)), src, n); + memmove((void *)(pa0 + (dstva - va0)), src, n); len -= n; src += n; - dstva = va_base + pgsize; + dstva = va0 + PGSIZE; } return 0; } @@ -572,30 +389,20 @@ int copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len) { uint64 n, va0, pa0; - pte_t *pte; - + while(len > 0){ va0 = PGROUNDDOWN(srcva); - if (va0 >= MAXVA) - return -1; - if((pte = walk(pagetable, va0, 0)) == 0) { - return -1; - } pa0 = walkaddr(pagetable, va0); if(pa0 == 0) return -1; - - // Calculate the correct page size and boundary - uint64 pgsize = (*pte & PTE_PS) ? SUPERPGSIZE : PGSIZE; - uint64 va_base = va0 & ~(pgsize - 1); - n = pgsize - (srcva - va_base); + n = PGSIZE - (srcva - va0); if(n > len) n = len; - memmove(dst, (void *)(pa0 + (srcva - va_base)), n); + memmove(dst, (void *)(pa0 + (srcva - va0)), n); len -= n; dst += n; - srcva = va_base + pgsize; + srcva = va0 + PGSIZE; } return 0; } @@ -609,27 +416,17 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) { uint64 n, va0, pa0; int got_null = 0; - pte_t *pte; while(got_null == 0 && max > 0){ va0 = PGROUNDDOWN(srcva); - if (va0 >= MAXVA) - return -1; - if((pte = walk(pagetable, va0, 0)) == 0) { - return -1; - } pa0 = walkaddr(pagetable, va0); if(pa0 == 0) return -1; - - // Calculate the correct page size and boundary - uint64 pgsize = (*pte & PTE_PS) ? SUPERPGSIZE : PGSIZE; - uint64 va_base = va0 & ~(pgsize - 1); - n = pgsize - (srcva - va_base); + n = PGSIZE - (srcva - va0); if(n > max) n = max; - char *p = (char *) (pa0 + (srcva - va_base)); + char *p = (char *) (pa0 + (srcva - va0)); while(n > 0){ if(*p == '\0'){ *dst = '\0'; @@ -644,7 +441,7 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) dst++; } - srcva = va_base + pgsize; + srcva = va0 + PGSIZE; } if(got_null){ return 0; @@ -652,46 +449,3 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) return -1; } } - - -#ifdef LAB_PGTBL -void vmprint(pagetable_t pagetable); - -static void vmprint_recursive(pagetable_t pagetable, int level, uint64 va_base) { - for (int i = 0; i < 512; i++) { - pte_t pte = pagetable[i]; - if (pte & PTE_V) { - uint64 pa = PTE2PA(pte); - uint64 va = va_base + ((uint64)i << (12 + 9 * (2 - level))); - - for (int j = 0; j < level; j++) - printf(" .."); - - if (level > 0) - printf(" "); - if (level == 0) { - printf(" ..%p\n", (void*)va); - } else { - printf("..%p\n", (void*)va); - } - - // 不是叶子节点,递归下一级页表 - if ((pte & (PTE_R | PTE_W | PTE_X)) == 0) { - vmprint_recursive((pagetable_t)pa, level + 1, va); - } - } - } -} - -void vmprint(pagetable_t pagetable) { - printf("page table %p\n", pagetable); - vmprint_recursive(pagetable, 0, 0); -} -#endif - -#ifdef LAB_PGTBL -pte_t* -pgpte(pagetable_t pagetable, uint64 va) { - return walk(pagetable, va, 0); -} -#endif diff --git a/superpage_implementation_summary.md b/superpage_implementation_summary.md deleted file mode 100644 index 9332ec7..0000000 --- a/superpage_implementation_summary.md +++ /dev/null @@ -1,321 +0,0 @@ -# xv6 超页(Superpage)实现复盘 - -## 项目概述 - -在 xv6 内核中实现 2MB 超页支持,当用户程序调用 `sbrk()` 时指定的大小为 2MB 或更大,并且新创建的地址范围包含一个或多个 2MB 对齐且至少为 2MB 大小的区域时,内核应使用单个超页(而不是数百个普通页)。 - -## 实现目标 - -- 支持 2MB 超页分配 -- 通过 `superpg_test` 测试用例 -- 保持与现有代码的兼容性 -- 正确处理超页的内存管理(分配、释放、复制) - -## 核心概念 - -### 超页基本参数 -- **普通页大小**: 4KB (PGSIZE) -- **超页大小**: 2MB (SUPERPGSIZE = 2 * 1024 * 1024) -- **超页包含**: 512个普通页 (2MB / 4KB = 512) -- **页表级别**: 在 level-1 页表中设置 PTE_PS 位 - -### 关键常量定义 -```c -#define SUPERPGSIZE (2 * (1 << 20)) // 2MB -#define SUPERPGROUNDUP(sz) (((sz)+SUPERPGSIZE-1) & ~(SUPERPGSIZE-1)) -#define PTE_PS (1L << 7) // Page Size bit -``` - -## 实现步骤 - -### 1. 超页内存分配器(kernel/kalloc.c) - -#### 新增数据结构 -```c -struct super_run { - struct super_run *next; -}; - -struct { - struct spinlock lock; - struct super_run *freelist; -} skmem; -``` - -#### 核心函数实现 - -**超页分配函数** -```c -void* superalloc() { - struct super_run *r; - acquire(&skmem.lock); - r = skmem.freelist; - if(r) skmem.freelist = r->next; - release(&skmem.lock); - if(r) memset((void*)r, 0, SUPERPGSIZE); - return (void*)r; -} -``` - -**超页释放函数** -```c -void superfree(void *pa) { - struct super_run *r; - - if(((uint64)pa % SUPERPGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP) - panic("superfree"); - - memset(pa, 1, SUPERPGSIZE); - - r = (struct super_run *)pa; - acquire(&skmem.lock); - r->next = skmem.freelist; - skmem.freelist = r; - release(&skmem.lock); -} -``` - -**内存范围初始化** -```c -void freerange(void *pa_start, void *pa_end) { - char *p; - // 分配普通页 - p = (char*)PGROUNDUP((uint64)pa_start); - for(; p + PGSIZE <= (char*)pa_end - 12 * 1024 * 1024; p += PGSIZE) - kfree(p); - - // 分配超页 - p = (char*)SUPERPGROUNDUP((uint64)p); - for (; p + SUPERPGSIZE <= (char *)pa_end; p += SUPERPGSIZE) { - superfree(p); - } -} -``` - -### 2. 页表管理(kernel/vm.c) - -#### 超页页表遍历 -```c -pte_t *super_walk(pagetable_t pagetable, uint64 va, int alloc) { - if (va > MAXVA) - panic("walk"); - - pte_t *pte = &(pagetable[PX(2, va)]); - if (*pte & PTE_V) { - pagetable = (pagetable_t)PTE2PA(*pte); - } else { - if (!alloc || (pagetable = (pde_t*)kalloc()) == 0) - return 0; - memset(pagetable, 0, PGSIZE); - *pte = PA2PTE(pagetable) | PTE_V; - } - - return &pagetable[PX(1, va)]; // 返回 level-1 PTE -} -``` - -#### 修改 walk 函数支持超页检测 -```c -pte_t *walk(pagetable_t pagetable, uint64 va, int alloc) { - // ... 现有代码 ... - for(int level = 2; level > 0; level--) { - pte_t *pte = &pagetable[PX(level, va)]; - if(*pte & PTE_V) { - pagetable = (pagetable_t)PTE2PA(*pte); -#ifdef LAB_PGTBL - if (*pte & PTE_PS) { - return pte; // 遇到超页时返回该PTE - } -#endif - } - // ... 其他代码 ... - } - return &pagetable[PX(0, va)]; -} -``` - -#### 地址转换函数增强 -```c -uint64 walkaddr(pagetable_t pagetable, uint64 va) { - // ... 现有代码 ... - pa = PTE2PA(*pte); - if(*pte & PTE_PS) { - // 超页:添加超页内偏移 - pa += va & (SUPERPGSIZE - 1); - } else { - // 普通页:添加页内偏移 - pa += va & (PGSIZE - 1); - } - return pa; -} -``` - -### 3. 内存分配策略(uvmalloc) - -**关键实现逻辑**: -```c -uint64 uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm) { - // 检查是否应该使用超页 - if (newsz - oldsz >= SUPERPGSIZE) { - uint64 super_start = SUPERPGROUNDUP(oldsz); - uint64 super_end = newsz & ~(SUPERPGSIZE - 1); - - // 1. 分配超页边界前的普通页 - for(a = oldsz; a < super_start; a += PGSIZE) { - // 分配普通页 - } - - // 2. 分配对齐的超页区域 - for (a = super_start; a < super_end; a += SUPERPGSIZE) { - mem = superalloc(); - mappages(pagetable, a, SUPERPGSIZE, (uint64)mem, - PTE_R | PTE_U | PTE_PS | xperm); - } - - // 3. 分配超页边界后的普通页 - for(a = super_end; a < newsz; a += PGSIZE) { - // 分配普通页 - } - } else { - // 小于2MB的分配使用普通页 - } -} -``` - -### 4. 内存操作函数适配 - -#### mappages 函数 -```c -int mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) { - if ((perm & PTE_PS) == 0) { - // 普通页映射逻辑 - // 使用 walk() 函数 - } else { - // 超页映射逻辑 - // 使用 super_walk() 函数 - last = va + size - SUPERPGSIZE; - for (;;) { - pte = super_walk(pagetable, a, 1); - *pte = PA2PTE(pa) | perm | PTE_V; - a += SUPERPGSIZE; - pa += SUPERPGSIZE; - } - } -} -``` - -#### uvmunmap 函数 -```c -void uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free) { - for(a = va; a < va + npages*PGSIZE; a += sz){ - sz = PGSIZE; - pte = walk(pagetable, a, 0); - - if ((*pte & PTE_PS)) { - // 超页释放 - if(do_free) superfree((void*)PTE2PA(*pte)); - *pte = 0; - a += SUPERPGSIZE - sz; - } else { - // 普通页释放 - if(do_free) kfree((void*)PTE2PA(*pte)); - *pte = 0; - } - } -} -``` - -#### uvmcopy 函数(fork支持) -```c -int uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) { - for(i = 0; i < sz; i += szinc){ - szinc = PGSIZE; - pte = walk(old, i, 0); - flags = PTE_FLAGS(*pte); - - if ((flags & PTE_PS) == 0) { - // 复制普通页 - mem = kalloc(); - memmove(mem, (char*)pa, PGSIZE); - mappages(new, i, PGSIZE, (uint64)mem, flags); - } else { - // 复制超页 - mem = superalloc(); - memmove(mem, (char*)pa, SUPERPGSIZE); - mappages(new, i, SUPERPGSIZE, (uint64)mem, flags); - szinc = SUPERPGSIZE; - } - } -} -``` - -#### copy操作函数适配 -```c -// copyout, copyin, copyinstr 都需要类似的修改 -uint64 pgsize = (*pte & PTE_PS) ? SUPERPGSIZE : PGSIZE; -uint64 va_base = va0 & ~(pgsize - 1); -n = pgsize - (srcva - va_base); -``` - -## 关键测试理解 - -### superpg_test 测试流程 -1. **分配8MB内存**: `sbrk(N)` 其中 N = 8MB -2. **计算超页起始地址**: `SUPERPGROUNDUP(end)` -3. **验证512个连续页面**: `supercheck(s)` - - 检查512个4KB页面有相同的PTE(证明是超页) - - 验证PTE权限(PTE_V | PTE_R | PTE_W) - - 测试内存读写功能 -4. **Fork测试**: 验证超页在进程复制时正确工作 - -### 测试期望 -- 512个连续的4KB页面应该映射到同一个超页 -- 每个页面通过 `pgpte()` 返回相同的PTE值 -- PTE必须设置正确的权限位 -- 内存读写必须正常工作 -- Fork后子进程中超页仍然正常 - -## 遇到的问题和解决方案 - -### 1. fork失败问题 -**问题**: 测试中fork调用失败 -**原因**: uvmcopy函数中超页处理逻辑错误 -**解决**: 修正超页复制时的步长计算和错误处理 - -### 2. 内存分配策略问题 -**问题**: 没有正确识别何时使用超页 -**原因**: 原始逻辑基于总分配大小,未考虑对齐 -**解决**: 重写分配策略,考虑超页对齐边界 - -### 3. 地址计算错误 -**问题**: walkaddr等函数对超页地址计算错误 -**原因**: 未考虑超页的偏移计算差异 -**解决**: 根据PTE_PS位选择不同的偏移计算方法 - -### 4. 内存释放错误 -**问题**: 释放超页时调用kfree而非superfree -**原因**: uvmunmap函数未区分超页和普通页 -**解决**: 根据PTE_PS位选择正确的释放函数 - -## 实现验证 - -### 测试结果 -- ✅ superpg_test: OK - 超页分配和使用正常 -- ✅ pgaccess_test: OK - 页面访问跟踪正常 -- ✅ ugetpid_test: OK - 基本系统调用正常 -- ✅ usertests: 通过 - 系统整体稳定性良好 - -### 性能优势 -- **内存效率**: 2MB超页减少页表条目数量 -- **TLB效率**: 单个TLB条目覆盖2MB而非4KB -- **管理效率**: 减少页表遍历深度 - -## 总结 - -超页实现的核心挑战在于: -1. **双重内存管理**: 同时支持4KB普通页和2MB超页 -2. **智能分配策略**: 自动识别何时使用超页 -3. **页表处理**: 正确处理不同级别的页表项 -4. **兼容性**: 保持与现有代码的完全兼容 - -通过仔细的设计和实现,成功在xv6中添加了超页支持,提高了大内存分配的效率,同时保持了系统的稳定性和兼容性。 \ No newline at end of file diff --git a/time.txt b/time.txt deleted file mode 100644 index 901184c..0000000 --- a/time.txt +++ /dev/null @@ -1 +0,0 @@ -88888888 diff --git a/user/alarmtest.c b/user/alarmtest.c new file mode 100644 index 0000000..b8d85f7 --- /dev/null +++ b/user/alarmtest.c @@ -0,0 +1,193 @@ +// +// test program for the alarm lab. +// you can modify this file for testing, +// but please make sure your kernel +// modifications pass the original +// versions of these tests. +// + +#include "kernel/param.h" +#include "kernel/types.h" +#include "kernel/stat.h" +#include "kernel/riscv.h" +#include "user/user.h" + +void test0(); +void test1(); +void test2(); +void test3(); +void periodic(); +void slow_handler(); +void dummy_handler(); + +int +main(int argc, char *argv[]) +{ + test0(); + test1(); + test2(); + test3(); + exit(0); +} + +volatile static int count; + +void +periodic() +{ + count = count + 1; + printf("alarm!\n"); + sigreturn(); +} + +// tests whether the kernel calls +// the alarm handler even a single time. +void +test0() +{ + int i; + printf("test0 start\n"); + count = 0; + sigalarm(2, periodic); + for(i = 0; i < 1000*500000; i++){ + if((i % 1000000) == 0) + write(2, ".", 1); + if(count > 0) + break; + } + sigalarm(0, 0); + if(count > 0){ + printf("test0 passed\n"); + } else { + printf("\ntest0 failed: the kernel never called the alarm handler\n"); + } +} + +void __attribute__ ((noinline)) foo(int i, int *j) { + if((i % 2500000) == 0) { + write(2, ".", 1); + } + *j += 1; +} + +// +// tests that the kernel calls the handler multiple times. +// +// tests that, when the handler returns, it returns to +// the point in the program where the timer interrupt +// occurred, with all registers holding the same values they +// held when the interrupt occurred. +// +void +test1() +{ + int i; + int j; + + printf("test1 start\n"); + count = 0; + j = 0; + sigalarm(2, periodic); + for(i = 0; i < 500000000; i++){ + if(count >= 10) + break; + foo(i, &j); + } + if(count < 10){ + printf("\ntest1 failed: too few calls to the handler\n"); + } else if(i != j){ + // the loop should have called foo() i times, and foo() should + // have incremented j once per call, so j should equal i. + // once possible source of errors is that the handler may + // return somewhere other than where the timer interrupt + // occurred; another is that that registers may not be + // restored correctly, causing i or j or the address ofj + // to get an incorrect value. + printf("\ntest1 failed: foo() executed fewer times than it was called\n"); + } else { + printf("test1 passed\n"); + } +} + +// +// tests that kernel does not allow reentrant alarm calls. +void +test2() +{ + int i; + int pid; + int status; + + printf("test2 start\n"); + if ((pid = fork()) < 0) { + printf("test2: fork failed\n"); + } + if (pid == 0) { + count = 0; + sigalarm(2, slow_handler); + for(i = 0; i < 1000*500000; i++){ + if((i % 1000000) == 0) + write(2, ".", 1); + if(count > 0) + break; + } + if (count == 0) { + printf("\ntest2 failed: alarm not called\n"); + exit(1); + } + exit(0); + } + wait(&status); + if (status == 0) { + printf("test2 passed\n"); + } +} + +void +slow_handler() +{ + count++; + printf("alarm!\n"); + if (count > 1) { + printf("test2 failed: alarm handler called more than once\n"); + exit(1); + } + for (int i = 0; i < 1000*500000; i++) { + asm volatile("nop"); // avoid compiler optimizing away loop + } + sigalarm(0, 0); + sigreturn(); +} + +// +// dummy alarm handler; after running immediately uninstall +// itself and finish signal handling +void +dummy_handler() +{ + sigalarm(0, 0); + sigreturn(); +} + +// +// tests that the return from sys_sigreturn() does not +// modify the a0 register +void +test3() +{ + uint64 a0; + + sigalarm(1, dummy_handler); + printf("test3 start\n"); + + asm volatile("lui a5, 0"); + asm volatile("addi a0, a5, 0xac" : : : "a0"); + for(int i = 0; i < 500000000; i++) + ; + asm volatile("mv %0, a0" : "=r" (a0) ); + + if(a0 != 0xac) + printf("test3 failed: register a0 changed\n"); + else + printf("test3 passed\n"); +} diff --git a/user/bttest.c b/user/bttest.c new file mode 100644 index 0000000..05405f9 --- /dev/null +++ b/user/bttest.c @@ -0,0 +1,10 @@ +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +int +main(int argc, char *argv[]) +{ + sleep(1); + exit(0); +} diff --git a/user/call.c b/user/call.c new file mode 100644 index 0000000..f725dcb --- /dev/null +++ b/user/call.c @@ -0,0 +1,17 @@ +#include "kernel/param.h" +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +int g(int x) { + return x+3; +} + +int f(int x) { + return g(x); +} + +void main(void) { + printf("%d %d\n", f(8)+1, 13); + exit(0); +} diff --git a/user/dirtypagestest.c b/user/dirtypagestest.c deleted file mode 100644 index 30a4c88..0000000 --- a/user/dirtypagestest.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "kernel/types.h" -#include "kernel/stat.h" -#include "user/user.h" - -void -test_dirtypages() -{ - printf("dirtypages test starting\n"); - - // Allocate some pages - char *buf = malloc(32 * 4096); // 32 pages - if(buf == 0) { - printf("malloc failed\n"); - exit(1); - } - - // Clear dirty bits first by calling dirtypages - unsigned int dbits; - if (dirtypages(buf, 32, &dbits) < 0) { - printf("dirtypages failed\n"); - exit(1); - } - printf("Initial dirty bits cleared: 0x%x\n", dbits); - - // Write to some pages to make them dirty - buf[0] = 1; // Page 0 - buf[4096 * 5] = 1; // Page 5 - buf[4096 * 10] = 1; // Page 10 - - // Check dirty pages - if (dirtypages(buf, 32, &dbits) < 0) { - printf("dirtypages failed\n"); - exit(1); - } - - printf("Dirty bits after writes: 0x%x\n", dbits); - - // Check if the expected pages are marked as dirty - if (dbits & (1 << 0)) - printf("Page 0 is dirty (expected)\n"); - if (dbits & (1 << 5)) - printf("Page 5 is dirty (expected)\n"); - if (dbits & (1 << 10)) - printf("Page 10 is dirty (expected)\n"); - - // Check again - dirty bits should be cleared now - if (dirtypages(buf, 32, &dbits) < 0) { - printf("dirtypages failed\n"); - exit(1); - } - printf("Dirty bits after clearing: 0x%x (should be 0)\n", dbits); - - free(buf); - printf("dirtypages test: OK\n"); -} - -int -main(int argc, char *argv[]) -{ - test_dirtypages(); - exit(0); -} \ No newline at end of file diff --git a/user/find.c b/user/find.c deleted file mode 100644 index f52f3d7..0000000 --- a/user/find.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "kernel/fs.h" -#include "kernel/stat.h" -#include "kernel/types.h" -#include "user/user.h" - -int match_pattern(const char *name, const char *pattern) { - const char *star = 0; - const char *name_ptr = name; - const char *pattern_ptr = pattern; - - while (1) { - if (*pattern_ptr == '*') { - star = pattern_ptr++; - name_ptr = name; - continue; - } - - if (!*name) - return (!*pattern_ptr || (star && !*++pattern_ptr)); - if (*pattern_ptr == '?' || *pattern_ptr == *name) { - pattern_ptr++; - name++; - continue; - } - - if (star) { - pattern_ptr = star + 1; - name = ++name_ptr; - continue; - } - return 0; - } -} - -void find(char *path, char *pattern) { - char buf[512], *p; - int fd; - struct dirent de; - struct stat st; - - if ((fd = open(path, 0)) < 0) { - fprintf(2, "find: cannot open %s\n", path); - return; - } - - if (fstat(fd, &st) < 0) { - fprintf(2, "find: cannot stat %s\n", path); - close(fd); - return; - } - - if (st.type != T_DIR) { - fprintf(2, "find: %s is not a directory\n", path); - close(fd); - return; - } - - if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) { - fprintf(2, "find: path too long\n"); - close(fd); - return; - } - - strcpy(buf, path); - p = buf + strlen(buf); - *p++ = '/'; - - while (read(fd, &de, sizeof(de)) == sizeof(de)) { - if (de.inum == 0 || !strcmp(de.name, ".") || !strcmp(de.name, "..")) - continue; - - memmove(p, de.name, DIRSIZ); - p[DIRSIZ] = 0; - - if (stat(buf, &st) < 0) { - fprintf(2, "find: cannot stat %s\n", buf); - continue; - } - - if (st.type == T_DIR) { - find(buf, pattern); - } else if (st.type == T_FILE) { - if (match_pattern(de.name, pattern)) { - fprintf(1, "%s\n", buf); - } - } - } - close(fd); -} - -int main(int argc, char *argv[]) { - if (argc != 3) { - fprintf(2, "Usage: find \n"); - exit(1); - } - find(argv[1], argv[2]); - exit(0); -} diff --git a/user/pgtbltest.c b/user/pgtbltest.c deleted file mode 100644 index 17fdc65..0000000 --- a/user/pgtbltest.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "kernel/param.h" -#include "kernel/fcntl.h" -#include "kernel/types.h" -#include "kernel/riscv.h" -#include "user/user.h" - -#define N (8 * (1 << 20)) - -void print_pgtbl(); -void print_kpgtbl(); -void ugetpid_test(); -void pgaccess_test(); -void superpg_test(); - -int -main(int argc, char *argv[]) -{ - print_pgtbl(); - ugetpid_test(); - print_kpgtbl(); - pgaccess_test(); - superpg_test(); - printf("pgtbltest: all tests succeeded\n"); - exit(0); -} - -char *testname = "???"; - -void -err(char *why) -{ - printf("pgtbltest: %s failed: %s, pid=%d\n", testname, why, getpid()); - exit(1); -} - -void -print_pte(uint64 va) -{ - pte_t pte = (pte_t) pgpte((void *) va); - printf("va 0x%lx pte 0x%lx pa 0x%lx perm 0x%lx\n", va, pte, PTE2PA(pte), PTE_FLAGS(pte)); -} - -void -print_pgtbl() -{ - printf("print_pgtbl starting\n"); - for (uint64 i = 0; i < 10; i++) { - print_pte(i * PGSIZE); - } - uint64 top = MAXVA/PGSIZE; - for (uint64 i = top-10; i < top; i++) { - print_pte(i * PGSIZE); - } - printf("print_pgtbl: OK\n"); -} - -void -ugetpid_test() -{ - int i; - - printf("ugetpid_test starting\n"); - testname = "ugetpid_test"; - - for (i = 0; i < 64; i++) { - int ret = fork(); - if (ret != 0) { - wait(&ret); - if (ret != 0) - exit(1); - continue; - } - if (getpid() != ugetpid()) - err("missmatched PID"); - exit(0); - } - printf("ugetpid_test: OK\n"); -} - -void -print_kpgtbl() -{ - printf("print_kpgtbl starting\n"); - kpgtbl(); - printf("print_kpgtbl: OK\n"); -} - -void -pgaccess_test() -{ - char *buf; - unsigned int abits; - printf("pgaccess_test starting\n"); - testname = "pgaccess_test"; - buf = malloc(32 * PGSIZE); - if (pgaccess(buf, 32, &abits) < 0) - err("pgaccess failed"); - buf[PGSIZE * 1] += 1; - buf[PGSIZE * 2] += 1; - buf[PGSIZE * 30] += 1; - if (pgaccess(buf, 32, &abits) < 0) - err("pgaccess failed"); - if (abits != ((1 << 1) | (1 << 2) | (1 << 30))) - err("incorrect access bits set"); - free(buf); - printf("pgaccess_test: OK\n"); -} - -void -supercheck(uint64 s) -{ - pte_t last_pte = 0; - - for (uint64 p = s; p < s + 512 * PGSIZE; p += PGSIZE) { - pte_t pte = (pte_t) pgpte((void *) p); - if(pte == 0) - err("no pte"); - if ((uint64) last_pte != 0 && pte != last_pte) { - err("pte different"); - } - if((pte & PTE_V) == 0 || (pte & PTE_R) == 0 || (pte & PTE_W) == 0){ - err("pte wrong"); - } - last_pte = pte; - } - - for(int i = 0; i < 512; i += PGSIZE){ - *(int*)(s+i) = i; - } - - for(int i = 0; i < 512; i += PGSIZE){ - if(*(int*)(s+i) != i) - err("wrong value"); - } -} - -void -superpg_test() -{ - int pid; - - printf("superpg_test starting\n"); - testname = "superpg_test"; - - char *end = sbrk(N); - if (end == 0 || end == (char*)0xffffffffffffffff) - err("sbrk failed"); - - uint64 s = SUPERPGROUNDUP((uint64) end); - supercheck(s); - if((pid = fork()) < 0) { - err("fork"); - } else if(pid == 0) { - supercheck(s); - exit(0); - } else { - int status; - wait(&status); - if (status != 0) { - exit(0); - } - } - printf("superpg_test: OK\n"); -} diff --git a/user/pingpong.c b/user/pingpong.c deleted file mode 100644 index 4d7ea95..0000000 --- a/user/pingpong.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "kernel/types.h" -#include "user/user.h" - -int main(int argc, char *argv[]) { - int proc_f2s[2], proc_s2f[2]; - char buffer[8]; - pipe(proc_f2s); - pipe(proc_s2f); - - if (fork() == 0) { - read(proc_s2f[0], buffer, 4); - printf("%d: received %s\n", getpid(), buffer); - write(proc_f2s[1], "pong", strlen("pong")); - } else { - write(proc_s2f[1], "ping", strlen("ping")); - read(proc_f2s[0], buffer, 4); - printf("%d: received %s\n", getpid(), buffer); - } - - exit(0); -} \ No newline at end of file diff --git a/user/primes.c b/user/primes.c deleted file mode 100644 index d65494e..0000000 --- a/user/primes.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "kernel/types.h" -#include "user/user.h" - -void redirect(int n, int pd[]) { - close(n); - dup(pd[n]); - close(pd[0]); - close(pd[1]); -} - -void primes() { - int previous, next; - int fd[2]; - - while (read(0, &previous, sizeof(int))) { - printf("prime %d\n", previous); - - if (pipe(fd) < 0) { - fprintf(2, "pipe failed\n"); - exit(1); - } - - if (fork() == 0) { - redirect(1, fd); - while (read(0, &next, sizeof(int))) { - if (next % previous != 0) { - write(1, &next, sizeof(int)); - } - } - exit(0); - } else { - close(fd[1]); - redirect(0, fd); - } - } -} - -int main(int argc, char *argv[]) { - int fd[2]; - - if (pipe(fd) < 0) { - fprintf(2, "pipe failed\n"); - exit(1); - } - - if (fork() == 0) { - redirect(1, fd); - for (int i = 2; i < 36; i++) { - write(1, &i, sizeof(int)); - } - exit(0); - } else { - close(fd[1]); - redirect(0, fd); - primes(); - } - - exit(0); -} - - diff --git a/user/sleep.c b/user/sleep.c deleted file mode 100644 index 095bd66..0000000 --- a/user/sleep.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "kernel/types.h" -#include "user/user.h" - -int main(int argc, char *argv[]) { - if (argc != 2) { - fprintf(2, "Usage: sleep