├── .gitattributes ├── Lab2 ├── source │ ├── include │ │ ├── test.h │ │ └── put.h │ ├── lib │ │ ├── Makefile │ │ └── put.c │ ├── init │ │ ├── Makefile │ │ ├── test.c │ │ └── main.c │ ├── arch │ │ └── riscv │ │ │ ├── include │ │ │ └── put.h │ │ │ ├── kernel │ │ │ ├── strap.c │ │ │ ├── Makefile │ │ │ ├── vmlinux.lds │ │ │ ├── head.S │ │ │ └── entry.S │ │ │ └── Makefile │ ├── help.py │ ├── .gdbinit │ └── Makefile └── assets │ ├── image-20201018132153939.png │ ├── image-20201028100115880.png │ ├── image-20201029185054233.png │ ├── image-20201029185422528.png │ └── image-20201029194625281.png ├── Lab5 ├── lab5_3180103012 │ ├── misc │ │ ├── help.py │ │ ├── help.cpp │ │ └── syscall.c │ ├── include │ │ ├── test.h │ │ ├── rand.h │ │ └── put.h │ ├── .gdbinit │ ├── arch │ │ └── riscv │ │ │ ├── include │ │ │ ├── syscall.h │ │ │ ├── types.h │ │ │ ├── vm.h │ │ │ └── sched.h │ │ │ ├── kernel │ │ │ ├── Makefile │ │ │ ├── strap.c │ │ │ ├── vmlinux.lds │ │ │ ├── head.S │ │ │ └── sched.c │ │ │ └── Makefile │ ├── init │ │ ├── main.c │ │ ├── test.c │ │ └── Makefile │ ├── lib │ │ ├── Makefile │ │ ├── rand.c │ │ └── put.c │ └── Makefile ├── assets │ ├── image-20201229102909497.png │ ├── image-20201229154224282.png │ ├── image-20201229162534060.png │ ├── image-20201229165135015.png │ └── image-20201229165315730.png └── man.url ├── Lab6 ├── lab6_3180103012 │ ├── misc │ │ ├── help.py │ │ └── help.c │ ├── user │ │ ├── start.S │ │ ├── syscall.h │ │ ├── link.ld │ │ ├── stdio.h │ │ ├── types.h │ │ ├── stddef.h │ │ ├── getpid.c │ │ ├── Makefile │ │ └── printf.c │ ├── include │ │ ├── rand.h │ │ ├── stdlib.h │ │ ├── string.h │ │ ├── stdio.h │ │ └── device.h │ ├── .gdbinit │ ├── arch │ │ └── riscv │ │ │ ├── include │ │ │ ├── string.h │ │ │ ├── syscall.h │ │ │ ├── stddef.h │ │ │ ├── types.h │ │ │ ├── buddy.h │ │ │ ├── mm.h │ │ │ ├── vm.h │ │ │ ├── slub.h │ │ │ ├── sched.h │ │ │ └── vm_flag.h │ │ │ ├── kernel │ │ │ ├── Makefile │ │ │ ├── strap.c │ │ │ ├── vmlinux.lds │ │ │ ├── fault.c │ │ │ ├── head.S │ │ │ ├── buddy.c │ │ │ ├── mm.c │ │ │ ├── vm.c │ │ │ └── sched.c │ │ │ └── Makefile │ ├── lib │ │ ├── exit.c │ │ ├── Makefile │ │ ├── string.c │ │ ├── rand.c │ │ └── printf.c │ ├── driver │ │ ├── Makefile │ │ ├── sifive_test.c │ │ ├── device.c │ │ ├── rinux_driver.h │ │ └── ns16550a.c │ ├── init │ │ ├── Makefile │ │ └── main.c │ └── Makefile └── assets │ └── image-20210115102209094.png ├── Lab3 ├── Lab3_3180103012 │ ├── include │ │ ├── test.h │ │ ├── rand.h │ │ └── put.h │ ├── .gdbinit │ ├── arch │ │ └── riscv │ │ │ ├── kernel │ │ │ ├── strap.c │ │ │ ├── Makefile │ │ │ ├── vmlinux.lds │ │ │ ├── head.S │ │ │ ├── sched.c │ │ │ └── entry.S │ │ │ ├── Makefile │ │ │ └── include │ │ │ └── sched.h │ ├── lib │ │ ├── Makefile │ │ ├── put.c │ │ └── rand.c │ ├── init │ │ ├── test.c │ │ ├── main.c │ │ └── Makefile │ └── Makefile └── assets │ ├── image-20201109132633353.png │ └── image-20201109150554783.png ├── Lab4 ├── lab4_3180103012 │ ├── include │ │ ├── test.h │ │ ├── rand.h │ │ └── put.h │ ├── .gdbinit │ ├── lib │ │ ├── Makefile │ │ ├── rand.c │ │ └── put.c │ ├── init │ │ ├── test.c │ │ ├── main.c │ │ └── Makefile │ ├── arch │ │ └── riscv │ │ │ ├── kernel │ │ │ ├── Makefile │ │ │ ├── strap.c │ │ │ ├── vmlinux.lds │ │ │ ├── head.S │ │ │ ├── sched.c │ │ │ ├── vm.c │ │ │ └── entry.S │ │ │ ├── Makefile │ │ │ └── include │ │ │ ├── vm.h │ │ │ └── sched.h │ ├── misc │ │ └── helper.cpp │ └── Makefile ├── assets │ ├── image-20201212103404130.png │ └── image-20201212103932711.png └── man.url ├── Lab0 ├── assets │ ├── image-20201002112928471.png │ ├── image-20201002113529801.png │ ├── image-20201002114040325.png │ ├── image-20201002114515073.png │ ├── image-20201002120038147.png │ ├── image-20201002122339937.png │ ├── image-20201002164548716.png │ ├── image-20201002164647470.png │ ├── image-20201002164730507.png │ └── image-20201002174046029.png └── Lab0_陈希尧_3012.md ├── Lab1 ├── assets │ ├── image-20201010135532501.png │ ├── image-20201012205118311.png │ └── image-20201012205914472.png └── lab1 │ ├── include │ └── test.h │ ├── init │ ├── Makefile │ ├── main.c │ └── test.c │ ├── arch │ └── riscv │ │ ├── kernel │ │ ├── Makefile │ │ ├── vmlinux.lds │ │ └── head.S │ │ └── Makefile │ └── Makefile └── .gitignore /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Lab2/source/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H 2 | #define _TEST_H 3 | 4 | int os_test(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/misc/help.py: -------------------------------------------------------------------------------- 1 | for i in range(0, 32): 2 | print(" sd x{}, {}(sp)".format(i+1, 8*i)) -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/misc/help.py: -------------------------------------------------------------------------------- 1 | for i in range(0, 32): 2 | print(" sd x{}, {}(sp)".format(i+1, 8*i)) -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H 2 | #define _TEST_H 3 | 4 | int os_test(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H 2 | #define _TEST_H 3 | 4 | int os_test(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H 2 | #define _TEST_H 3 | 4 | int os_test(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/start.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | .global _start 3 | _start: 4 | j main 5 | 6 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/.gdbinit: -------------------------------------------------------------------------------- 1 | set breakpoint pending on 2 | set output-radix 10 3 | target remote localhost:1234 4 | layout reg 5 | -------------------------------------------------------------------------------- /Lab0/assets/image-20201002112928471.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002112928471.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002113529801.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002113529801.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002114040325.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002114040325.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002114515073.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002114515073.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002120038147.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002120038147.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002122339937.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002122339937.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002164548716.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002164548716.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002164647470.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002164647470.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002164730507.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002164730507.png -------------------------------------------------------------------------------- /Lab0/assets/image-20201002174046029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab0/assets/image-20201002174046029.png -------------------------------------------------------------------------------- /Lab1/assets/image-20201010135532501.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab1/assets/image-20201010135532501.png -------------------------------------------------------------------------------- /Lab1/assets/image-20201012205118311.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab1/assets/image-20201012205118311.png -------------------------------------------------------------------------------- /Lab1/assets/image-20201012205914472.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab1/assets/image-20201012205914472.png -------------------------------------------------------------------------------- /Lab2/assets/image-20201018132153939.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab2/assets/image-20201018132153939.png -------------------------------------------------------------------------------- /Lab2/assets/image-20201028100115880.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab2/assets/image-20201028100115880.png -------------------------------------------------------------------------------- /Lab2/assets/image-20201029185054233.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab2/assets/image-20201029185054233.png -------------------------------------------------------------------------------- /Lab2/assets/image-20201029185422528.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab2/assets/image-20201029185422528.png -------------------------------------------------------------------------------- /Lab2/assets/image-20201029194625281.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab2/assets/image-20201029194625281.png -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/include/rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H 2 | #define RAND_H 3 | 4 | #define SEED 13 5 | unsigned int rand(); 6 | 7 | #endif -------------------------------------------------------------------------------- /Lab3/assets/image-20201109132633353.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab3/assets/image-20201109132633353.png -------------------------------------------------------------------------------- /Lab3/assets/image-20201109150554783.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab3/assets/image-20201109150554783.png -------------------------------------------------------------------------------- /Lab4/assets/image-20201212103404130.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab4/assets/image-20201212103404130.png -------------------------------------------------------------------------------- /Lab4/assets/image-20201212103932711.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab4/assets/image-20201212103932711.png -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/include/rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H 2 | #define RAND_H 3 | 4 | #define SEED 13 5 | unsigned int rand(); 6 | 7 | #endif -------------------------------------------------------------------------------- /Lab5/assets/image-20201229102909497.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab5/assets/image-20201229102909497.png -------------------------------------------------------------------------------- /Lab5/assets/image-20201229154224282.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab5/assets/image-20201229154224282.png -------------------------------------------------------------------------------- /Lab5/assets/image-20201229162534060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab5/assets/image-20201229162534060.png -------------------------------------------------------------------------------- /Lab5/assets/image-20201229165135015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab5/assets/image-20201229165135015.png -------------------------------------------------------------------------------- /Lab5/assets/image-20201229165315730.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab5/assets/image-20201229165315730.png -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/include/rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H 2 | #define RAND_H 3 | 4 | #define SEED 13 5 | unsigned int rand(); 6 | 7 | #endif -------------------------------------------------------------------------------- /Lab6/assets/image-20210115102209094.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/futuretech6/RV-Kernel/HEAD/Lab6/assets/image-20210115102209094.png -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/include/rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H 2 | #define RAND_H 3 | 4 | #define SEED 13 5 | unsigned int rand(); 6 | 7 | #endif -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/syscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SYS_WRITE 64 4 | #define SYS_GETPID 172 5 | #define SYS_FORK 220 6 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/include/stdlib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stddef.h" 4 | 5 | __attribute__((noreturn)) void exit(int status); 6 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/.gdbinit: -------------------------------------------------------------------------------- 1 | source ~/lab6/misc/gef.py 2 | set breakpoint pending on 3 | set output-radix 16 4 | target remote localhost:1234 5 | 6 | 7 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/.gdbinit: -------------------------------------------------------------------------------- 1 | set breakpoint pending on 2 | set output-radix 10 3 | target remote localhost:1234 4 | layout asm 5 | b schedule 6 | b do_timer 7 | -------------------------------------------------------------------------------- /Lab4/man.url: -------------------------------------------------------------------------------- 1 | [{000214A0-0000-0000-C000-000000000046}] 2 | Prop3=19,11 3 | [InternetShortcut] 4 | IDList= 5 | URL=https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 6 | -------------------------------------------------------------------------------- /Lab1/lab1/include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H 2 | #define _TEST_H 3 | 4 | int os_test(); 5 | 6 | #define UART16550A_DR (volatile unsigned char *)0x10000000 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Lab5/man.url: -------------------------------------------------------------------------------- 1 | [{000214A0-0000-0000-C000-000000000046}] 2 | Prop3=19,11 3 | [InternetShortcut] 4 | IDList= 5 | URL=https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab%205 6 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/include/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSCALL_H 2 | #define _SYSCALL_H 3 | 4 | #define SYS_WRITE_ID 64 5 | #define SYS_GETPID_ID 172 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Lab2/source/include/put.h: -------------------------------------------------------------------------------- 1 | #ifndef PUT_H 2 | #define PUT_H 3 | #define UART16550A_DR (volatile unsigned char *)0x10000000 4 | void puti(int num); 5 | int puts(const char *s); 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab2/source/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lib 2 | .PHONY: all 3 | all: put.o 4 | 5 | %.o: %.c 6 | @${GCC} ${CFLAG} -c $< -o $@ 7 | 8 | .PHONY: clean 9 | clean: 10 | @rm *.o 11 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/include/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | void *memset(void *dst, int c, size_t n); 6 | void memcpy(void *dest, const void *src, size_t n); -------------------------------------------------------------------------------- /Lab1/lab1/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | .PHONY: all 3 | all: main.o test.o 4 | 5 | %.o: %.c 6 | @${GCC} ${CFLAG} -c $< -o $@ 7 | 8 | .PHONY: clean 9 | clean: 10 | @rm *.o 11 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/.gdbinit: -------------------------------------------------------------------------------- 1 | set breakpoint pending on 2 | set output-radix 10 3 | target remote localhost:1234 4 | layout asm 5 | 6 | 7 | b *0xffffffe000001004 8 | b *0xffffffe000000ff4 9 | -------------------------------------------------------------------------------- /Lab2/source/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | .PHONY: all 3 | all: main.o test.o 4 | 5 | %.o: %.c 6 | @${GCC} ${CFLAG} -c $< -o $@ 7 | 8 | .PHONY: clean 9 | clean: 10 | @rm *.o 11 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/include/put.h: -------------------------------------------------------------------------------- 1 | #ifndef PUT_H 2 | #define PUT_H 3 | #define UART16550A_DR (volatile unsigned char *)0x10000000 4 | void puti(int num); 5 | int puts(const char *s); 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | // void* memset(void *dst, int c, uint n); 6 | // void* memmove(void *dst, const void *src, uint n); -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/include/put.h: -------------------------------------------------------------------------------- 1 | #ifndef PUT_H 2 | #define PUT_H 3 | #define UART16550A_DR (volatile unsigned char *)0x10000000 4 | void puti(int num); 5 | int puts(const char *s); 6 | #endif 7 | -------------------------------------------------------------------------------- /Lab2/source/help.py: -------------------------------------------------------------------------------- 1 | 2 | for i in range(1, 32): 3 | print("sd x"+str(i)+", "+str(8*(33-i))+"(sp)") 4 | print() 5 | for i in range(31, 0, -1): 6 | print("ld x"+str(i)+", "+str(8*(33-i))+"(sp)") -------------------------------------------------------------------------------- /Lab1/lab1/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | .PHONY: all 3 | all: head.o 4 | 5 | head.o: head.S 6 | @${GCC} ${CFLAG} -c $< -o $@ 7 | 8 | .PHONY: clean 9 | clean: 10 | @rm -f *.o 11 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/lib/exit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void exit(int status) { 5 | poweroff_dev->poweroff(); 6 | asm volatile("1: j 1b"); 7 | __builtin_unreachable(); 8 | } -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/misc/help.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char const *argv[]) { 5 | void *a = (void *)0; 6 | printf("%p", a + 3); 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/include/put.h: -------------------------------------------------------------------------------- 1 | #ifndef PUT_H 2 | #define PUT_H 3 | 4 | #define UART_ADDR (volatile unsigned char *)0x10000000 5 | void putd(long num); 6 | void putx(unsigned long num); 7 | int puts(const char *s); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x0; 6 | _start = .; 7 | .text.init : { KEEP(*(.text.init)) } 8 | .text : { KEEP(*(.text)) } 9 | .data : { KEEP(*(.data)) } 10 | } 11 | -------------------------------------------------------------------------------- /Lab2/source/.gdbinit: -------------------------------------------------------------------------------- 1 | set breakpoint pending on 2 | set output-radix 10 3 | target remote localhost:1234 4 | layout reg 5 | b _start 6 | b trap_s 7 | b trap_m_timer 8 | b trap_m_ecallS 9 | display (long)*0x200bff8 10 | display (long)*0x2004000 11 | -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/kernel/strap.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | 3 | void put_trap_s(void) { 4 | static int counter = 0; 5 | puts("[S] Supervisor Mode Timer Interrupt "); 6 | puti(counter++); 7 | puts("\n"); 8 | return; 9 | } 10 | -------------------------------------------------------------------------------- /Lab2/source/init/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "put.h" 3 | 4 | int os_test() { 5 | const char *msg = "ZJU OS LAB 2 GROUP-17\n"; 6 | 7 | puts(msg); 8 | while (1) 9 | ; 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/strap.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | 3 | void put_trap_s(void) { 4 | static int counter = 0; 5 | puts("[S] Supervisor Mode Timer Interrupt "); 6 | puti(counter++); 7 | puts("\n"); 8 | return; 9 | } 10 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSCALL_H 2 | #define _SYSCALL_H 3 | 4 | #define SYS_WRITE_ID 64 5 | #define SYS_GETPID_ID 172 6 | #define MMAP_ID 222 7 | #define MUNMAP_ID 215 8 | #define MPROTECT_ID 226 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lib 2 | DEP = ${TOP}/include/put.h ${TOP}/include/rand.h 3 | 4 | .PHONY: all 5 | all: put.o rand.o 6 | 7 | %.o: %.c ${DEP} 8 | @${GCC} ${CFLAG} -c $< -o $@ 9 | 10 | .PHONY: clean 11 | clean: 12 | @rm *.o 13 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lib 2 | DEP = ./Makefile ${TOP}/include/put.h ${TOP}/include/rand.h 3 | 4 | .PHONY: all 5 | all: put.o rand.o 6 | 7 | %.o: %.c ${DEP} 8 | @${CC} ${CFLAG} -c $< -o $@ 9 | 10 | .PHONY: clean 11 | clean: 12 | @rm *.o 13 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/init/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "put.h" 3 | #include "sched.h" 4 | 5 | int os_test() { 6 | puts("ZJU OS LAB 3 GROUP-17\ntask init...\n"); 7 | 8 | task_init(); 9 | dead_loop(); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/init/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "put.h" 3 | #include "sched.h" 4 | 5 | int os_test() { 6 | puts("ZJU OS LAB 4 GROUP-17\ntask init...\n"); 7 | 8 | task_init(); 9 | dead_loop(); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPES_H 2 | #define _TYPES_H 3 | 4 | typedef unsigned long uint64; 5 | typedef unsigned char uint8; 6 | typedef unsigned long size_t; 7 | typedef unsigned int *uintprt_t; 8 | typedef long pid_t; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | .PHONY: all 3 | all: head.o entry.o strap.o 4 | 5 | %.o: %.S 6 | @${GCC} ${CFLAG} -c $< -o $@ 7 | 8 | strap.o: strap.c 9 | @${GCC} ${CFLAG} -c $< -o $@ 10 | 11 | .PHONY: clean 12 | clean: 13 | @rm -f *.o 14 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/init/main.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define SIFIVE_TEST 0x100000 3 | #define VIRT_TEST_FINISHER_PASS 0x5555 4 | 5 | int start_kernel() { 6 | os_test(); 7 | asm("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/init/main.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define SIFIVE_TEST 0x100000 3 | #define VIRT_TEST_FINISHER_PASS 0x5555 4 | 5 | int start_kernel() { 6 | os_test(); 7 | asm("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/init/main.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define SIFIVE_TEST 0x100000 3 | #define VIRT_TEST_FINISHER_PASS 0x5555 4 | 5 | int start_kernel() { 6 | os_test(); 7 | asm("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lib 2 | DEP = ./Makefile $(wildcard ${TOP}/include/*.h) 3 | SRC = $(wildcard *.c) 4 | 5 | .PHONY: all clean 6 | 7 | 8 | all: $(SRC:%.c=%.o) 9 | %.o: %.c ${DEP} 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | 13 | clean: 14 | @rm *.o 15 | -------------------------------------------------------------------------------- /Lab1/lab1/init/main.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define SIFIVE_TEST 0x100000 3 | #define VIRT_TEST_FINISHER_PASS 0x5555 4 | 5 | int start_kernel() 6 | { 7 | os_test(); 8 | 9 | asm volatile("sh %0, 0(%1)" : : "r" (VIRT_TEST_FINISHER_PASS), "r" (SIFIVE_TEST)); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | DEP = ${TOP}/include/put.h ${TOP}/include/test.h ${TOP}/arch/riscv/include/sched.h 3 | 4 | .PHONY: all 5 | all: main.o test.o 6 | 7 | %.o: %.c ${DEP} 8 | @${GCC} ${CFLAG} -c $< -o $@ 9 | 10 | .PHONY: clean 11 | clean: 12 | @rm *.o 13 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lib 2 | DEP = ./Makefile $(wildcard ${TOP}/include/*.h) 3 | SRC = $(wildcard *.c) 4 | 5 | .PHONY: all clean 6 | 7 | 8 | all: $(patsubst %c, %o, ${SRC}) 9 | %.o: %.c ${DEP} 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | 13 | clean: 14 | @rm -f *.o 15 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | DEP = ./Makefile ${TOP}/include/test.h ${TOP}/include/put.h ${TOP}/arch/riscv/include/sched.h 3 | 4 | .PHONY: all 5 | all: main.o test.o 6 | 7 | %.o: %.c ${DEP} 8 | @${CC} ${CFLAG} -c $< -o $@ 9 | 10 | .PHONY: clean 11 | clean: 12 | @rm *.o 13 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/init/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "put.h" 3 | #include "sched.h" 4 | 5 | int os_test() { 6 | puts("ZJU OS LAB 5 3180103012/GROUP-17\n"); 7 | puts("task init...\n"); 8 | 9 | task_init(); 10 | for (;;) 11 | ; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/stdio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stddef.h" 4 | 5 | #ifdef DEBUG_LOG 6 | #define Log(format, ...) \ 7 | printf("[%s:%d %s] " format "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); 8 | #else 9 | #define Log(format, ...) ; 10 | #endif 11 | 12 | int printf(const char *, ...); -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/types.h: -------------------------------------------------------------------------------- 1 | typedef unsigned int uint; 2 | typedef unsigned short ushort; 3 | typedef unsigned char uchar; 4 | typedef unsigned long uintptr_t; 5 | 6 | typedef unsigned char uint8; 7 | typedef unsigned short uint16; 8 | typedef unsigned int uint32; 9 | typedef unsigned long uint64; 10 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | DEP = ./Makefile $(wildcard ${TOP}/include/*.h) $(wildcard ${TOP}/arch/riscv/include/*.h) 3 | SRC = $(wildcard *.c) 4 | 5 | .PHONY: all clean 6 | 7 | 8 | all: $(SRC:%.c=%.o) 9 | %.o: %.c ${DEP} 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | 13 | clean: 14 | @rm *.o 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pdf 3 | bin 4 | *.exe 5 | *.out 6 | *.o 7 | .vscode 8 | *.zip 9 | Image 10 | vmlinux 11 | *.gz 12 | System.map 13 | debug.log 14 | *.mp4 15 | *dasm.S 16 | *section.txt 17 | Lab4/kos-riscv 18 | *.bin 19 | *.elf 20 | Lab5/lab5_3180103012/user 21 | *.swp 22 | **/mmap.c 23 | gef.py 24 | deprecated 25 | 26 | -------------------------------------------------------------------------------- /Lab1/lab1/init/test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | void putChar(const char* msg) 4 | { 5 | while (*msg != '\0') 6 | { 7 | *UART16550A_DR = (unsigned char)(*msg); 8 | msg++; 9 | } 10 | } 11 | 12 | int os_test() 13 | { 14 | const char *msg = "Hello RISC-V!\n"; 15 | 16 | putChar(msg); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/driver/Makefile: -------------------------------------------------------------------------------- 1 | ASM_SRC = $(sort $(wildcard *.S)) 2 | C_SRC = $(sort $(wildcard *.c)) 3 | OBJ = $(patsubst %.S,%.o,$(ASM_SRC)) $(patsubst %.c,%.o,$(C_SRC)) 4 | 5 | .PHONY: all clean 6 | 7 | 8 | all: $(OBJ) 9 | %.o:%.c 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | 13 | clean: 14 | @rm -f *.o 15 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/init/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_init 2 | DEP = ./Makefile $(wildcard ${TOP}/include/*.h) $(wildcard ${TOP}/arch/riscv/include/*.h) 3 | SRC = $(wildcard *.c) 4 | 5 | .PHONY: all clean 6 | 7 | 8 | all: $(patsubst %c, %o, ${SRC}) 9 | %.o: %.c ${DEP} 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | 13 | clean: 14 | @rm -f *.o 15 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | DEP = ../include/sched.h ${TOP}/Makefile 3 | 4 | .PHONY: all 5 | all: head.o entry.o strap.o sched.o# switch.o 6 | 7 | %.o: %.S ${DEP} 8 | @${GCC} ${CFLAG} -c $< -o $@ 9 | 10 | %.o: %.c ${DEP} 11 | @${GCC} ${CFLAG} -c $< -o $@ 12 | 13 | .PHONY: clean 14 | clean: 15 | @rm -f *.o 16 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/include/put.h: -------------------------------------------------------------------------------- 1 | #ifndef PUT_H 2 | #define PUT_H 3 | 4 | #define UART_PHY_ADDR ((volatile unsigned char *)0x10000000) 5 | #define UART_VIR_ADDR ((volatile unsigned char *)0xffffffdf90000000) 6 | 7 | void putd(long num); 8 | void putx(unsigned long num); 9 | int puts(const char *s); 10 | void putf(const char *s, ...); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Lab1/lab1/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | BASE_ADDR = 0x80000000; 4 | SECTIONS 5 | { 6 | . = BASE_ADDR; 7 | .text : { *(.text) } 8 | .rodata : { *(.rodata) } 9 | .data : { *(.data) } 10 | .bss : { *(.bss) } 11 | . += 0x8000; 12 | stack_top = .; 13 | _end = .; 14 | mtvec_base = 0x0; 15 | stvec_base = 0x0; 16 | } 17 | -------------------------------------------------------------------------------- /Lab2/source/init/main.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define SIFIVE_TEST 0x100000 3 | #define VIRT_TEST_FINISHER_PASS 0x5555 4 | 5 | int start_kernel() { 6 | os_test(); 7 | 8 | asm volatile("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 9 | asm volatile("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | DEP = ./Makefile ../include/sched.h ../include/vm.h ${TOP}/Makefile 3 | 4 | .PHONY: all 5 | all: head.o entry.o strap.o sched.o vm.o ${DEP} 6 | %.o: %.S ${DEP} 7 | @${CC} ${CFLAG} -c $< -o $@ 8 | 9 | %.o: %.c ${DEP} 10 | @${CC} ${CFLAG} -c $< -o $@ 11 | 12 | .PHONY: clean 13 | clean: 14 | @rm -f *.o 15 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/include/stdio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stddef.h" 4 | 5 | #ifdef DEBUG_LOG 6 | #define Log(format, ...) \ 7 | printf("[%s:%d %s] " format "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); 8 | #else 9 | #define Log(format, ...) ; 10 | #endif 11 | 12 | int printf(const char *, ...); 13 | int putchar(int); 14 | int puts(const char *); 15 | void panic(const char *s, ...); -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/stddef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | #define NULL 0L 6 | #define offsetof(type, member) __builtin_offsetof(type, member) 7 | 8 | typedef __builtin_va_list va_list; 9 | 10 | #define va_start(v, l) __builtin_va_start(v, l) 11 | #define va_end(v) __builtin_va_end(v) 12 | #define va_arg(v, l) __builtin_va_arg(v, l) 13 | #define va_copy(d, s) __builtin_va_copy(d, s) -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | DEP = ./Makefile ${TOP}/Makefile $(wildcard ${TOP}/include/*.h) $(wildcard ${TOP}/arch/riscv/include/*.h) 3 | SRC = $(wildcard *.c *.S) 4 | 5 | .PHONY: all clean c asm 6 | 7 | 8 | all: c asm 9 | c: $(SRC:%.c=%.o) ${DEP} 10 | %.o: %.S ${DEP} ${SRC} 11 | @${CC} $(CFLAG) -c $< -o $@ 12 | 13 | asm: $(patsubst %S, %o, ${SRC}) ${DEP} 14 | %.o: %.c ${DEP} 15 | @${CC} ${CFLAG} -c $< -o $@ 16 | 17 | 18 | clean: 19 | @rm -f *.o 20 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_kernel 2 | DEP = ./Makefile ${TOP}/Makefile $(wildcard ${TOP}/include/*.h) $(wildcard ${TOP}/arch/riscv/include/*.h) 3 | SRC = $(wildcard *.c *.S) 4 | 5 | .PHONY: all clean c asm 6 | 7 | 8 | all: c asm 9 | c: $(patsubst %c, %o, ${SRC}) ${DEP} 10 | %.o: %.S ${DEP} 11 | @${CC} $(CFLAG) -c $< -o $@ 12 | 13 | 14 | asm: $(patsubst %S, %o, ${SRC}) ${DEP} 15 | %.o: %.c ${DEP} 16 | @${CC} ${CFLAG} -c $< -o $@ 17 | 18 | 19 | clean: 20 | @rm -f *.o 21 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/stddef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 6 | typedef __SIZE_TYPE__ size_t; 7 | typedef __WCHAR_TYPE__ wchar_t; 8 | 9 | #define NULL 0L 10 | #define offsetof(type, member) __builtin_offsetof(type, member) 11 | 12 | typedef __builtin_va_list va_list; 13 | 14 | #define va_start(v, l) __builtin_va_start(v, l) 15 | #define va_end(v) __builtin_va_end(v) 16 | #define va_arg(v, l) __builtin_va_arg(v, l) 17 | #define va_copy(d, s) __builtin_va_copy(d, s) 18 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPES_H 2 | #define _TYPES_H 3 | 4 | typedef unsigned int uint; 5 | typedef unsigned short ushort; 6 | typedef unsigned char uchar; 7 | typedef unsigned int *uintptr_t; 8 | 9 | typedef unsigned char uint8; 10 | typedef unsigned short uint16; 11 | typedef unsigned int uint32; 12 | typedef unsigned long uint64; 13 | 14 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 15 | typedef __SIZE_TYPE__ size_t; 16 | typedef __WCHAR_TYPE__ wchar_t; 17 | typedef size_t __off_t; 18 | typedef uint64 vm_flags_t; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/buddy.h: -------------------------------------------------------------------------------- 1 | #ifndef _BUDDY_H 2 | #define _BUDDY_H 3 | 4 | #include "types.h" 5 | #include "vm.h" 6 | 7 | #define BUDDY_START_ADDR 0x80000000L 8 | #define BUDDY_SPACE_SIZE (16 * 1024 * 1024) 9 | 10 | struct buddy { 11 | unsigned long pgnum; // number of `pages` 12 | unsigned long bitmap[2 * (BUDDY_SPACE_SIZE / PAGE_SIZE) - 1]; // bit map 13 | }; 14 | 15 | void init_buddy_system(void); 16 | void *alloc_pages(int npages); 17 | void *alloc_pages_ret_pa(int npages); 18 | void free_pages(void *addr); 19 | 20 | #endif -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/driver/sifive_test.c: -------------------------------------------------------------------------------- 1 | #include "device.h" 2 | #include "rinux_driver.h" 3 | 4 | enum { 5 | SIFIVE_TEST_FAIL = 0x3333, 6 | SIFIVE_TEST_PASS = 0x5555, 7 | }; 8 | 9 | static volatile unsigned int *test; 10 | 11 | static void sifive_test_init() { 12 | test = (unsigned int *)(void *)PA2VA(get_device_addr(POWEROFF_MMIO)); 13 | } 14 | 15 | static void sifive_test_poweroff() { 16 | *test = SIFIVE_TEST_PASS; 17 | while (1) { 18 | asm volatile(""); 19 | } 20 | } 21 | 22 | poweroff_device_t poweroff_sifive_test = {sifive_test_init, sifive_test_poweroff}; 23 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/lib/string.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | /** 4 | * @brief Memory set 5 | * 6 | * @param s Source address 7 | * @param c Char for replacement, of size 1 byte here 8 | * @param n Number of bytes replaced 9 | */ 10 | void *memset(void *s, int c, size_t n) { 11 | for (size_t i = 0; i < n; i++) 12 | *((uint8 *)s + i) = c; 13 | return s; 14 | } 15 | 16 | /** 17 | * @brief 18 | * 19 | * @param dest 20 | * @param src 21 | * @param n 22 | */ 23 | void memcpy(void *dest, const void *src, size_t n) { 24 | for (size_t i = 0; i < n; i++) 25 | *((uint8 *)dest + i) = *((uint8 *)src + i); 26 | } -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/lib/put.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | 3 | int puts(const char *s) { 4 | while (*s != '\0') { 5 | *UART16550A_DR = (unsigned char)(*s); 6 | s++; 7 | } 8 | return 0; 9 | } 10 | static char itoch(int x) { 11 | if (x >= 0 && x <= 9) 12 | return (char)(x + 48); 13 | return 0; 14 | } 15 | void puti(int x) { 16 | int digit = 1, tmp = x; 17 | while (tmp >= 10) { 18 | digit *= 10; 19 | tmp /= 10; 20 | } 21 | while (digit >= 1) { 22 | *UART16550A_DR = (unsigned char)itoch(x / digit); 23 | x %= digit; 24 | digit /= 10; 25 | } 26 | return; 27 | } 28 | -------------------------------------------------------------------------------- /Lab2/source/lib/put.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | 3 | int puts(const char *s) { 4 | while (*s != '\0') { 5 | *UART16550A_DR = (unsigned char)(*s); 6 | s++; 7 | } 8 | return 0; 9 | } 10 | static char itoch(int x) { 11 | if (x >= 0 && x <= 9) { 12 | return (char)(x + 48); 13 | } 14 | return 0; 15 | } 16 | void puti(int x) { 17 | int digit = 1, tmp = x; 18 | while (tmp >= 10) { 19 | digit *= 10; 20 | tmp /= 10; 21 | } 22 | while (digit >= 1) { 23 | *UART16550A_DR = (unsigned char)itoch(x / digit); 24 | x %= digit; 25 | digit /= 10; 26 | } 27 | return; 28 | } 29 | -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | BASE_ADDR = 0x80000000; 4 | SECTIONS 5 | { 6 | . = BASE_ADDR; 7 | .text : { 8 | *(.text.init) 9 | *(.text.entry) 10 | *(.text) 11 | } 12 | .rodata : { *(.rodata) } 13 | .data : { *(.data) } 14 | .bss : { *(.bss) } 15 | . += 0x8000; 16 | stack_top = .; 17 | _end = .; 18 | 19 | bss_size = 0x100; 20 | mtime_addr = 0x200bff8; 21 | mtimecmp_addr = 0x2004000; 22 | time_sep_init = 1000000; 23 | time_sep = 100000; 24 | mcause_MTimer = 0x7; 25 | mcause_ecallS = 0x9; 26 | scause_STimer = 0x5; 27 | } 28 | -------------------------------------------------------------------------------- /Lab1/lab1/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | .PHONY: all 3 | all: ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 4 | 5 | ${TOP}/vmlinux: ${TOP}/init/main.o ${TOP}/init/test.o ./kernel/head.o ./kernel/vmlinux.lds 6 | @# link to get the vmlinux 7 | @${LD} ${TOP}/init/main.o ${TOP}/init/test.o ./kernel/head.o -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 8 | 9 | ./boot/Image: ${TOP}/vmlinux 10 | @# use vmlinux to gen Image 11 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 12 | 13 | ${TOP}/System.map: ${TOP}/vmlinux 14 | @# print kernel symbol table 15 | @nm ${TOP}/vmlinux > ${TOP}/System.map 16 | 17 | .PHONY: clean 18 | clean: 19 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | BASE_ADDR = 0x80000000; 4 | SECTIONS 5 | { 6 | . = BASE_ADDR; 7 | .text : { 8 | *(.text.init) 9 | *(.text.entry) 10 | *(.text) 11 | } 12 | .rodata : { *(.rodata) } 13 | .data : { *(.data) } 14 | .bss : { *(.bss) } 15 | . += 0x10fff; 16 | stack_top = 0x80010fff; 17 | _end = .; 18 | 19 | bss_size = 0x100; 20 | mtime_addr = 0x200bff8; 21 | mtimecmp_addr = 0x2004000; 22 | time_sep_init = 1000000; 23 | time_sep = 100000; 24 | mcause_MTimer = 0x7; 25 | mcause_ecallS = 0x9; 26 | scause_STimer = 0x5; 27 | } 28 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | OBJ = $(wildcard ${TOP}/init/*.o) $(wildcard ${TOP}/lib/*.o) $(wildcard ${TOP}/arch/riscv/kernel/*.o) 3 | 4 | .PHONY: all clean 5 | 6 | 7 | all: ./Makefile ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 8 | ${TOP}/vmlinux: ${OBJ} ./kernel/vmlinux.lds ./Makefile 9 | @# link to get the vmlinux 10 | @${LD} ${OBJ} -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 11 | 12 | ./boot/Image: ${TOP}/vmlinux 13 | @# use vmlinux to gen Image 14 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 15 | 16 | ${TOP}/System.map: ${TOP}/vmlinux 17 | @# print kernel symbol table 18 | @nm ${TOP}/vmlinux > ${TOP}/System.map 19 | 20 | 21 | clean: 22 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/lib/rand.c: -------------------------------------------------------------------------------- 1 | #include "rand.h" 2 | 3 | int initialize = 0; 4 | int r[1000]; 5 | int t = 0; 6 | 7 | unsigned int rand() { 8 | int i; 9 | 10 | if (!initialize) { 11 | r[0] = SEED; 12 | for (i = 1; i < 31; i++) { 13 | r[i] = (16807LL * r[i - 1]) % 2147483647; 14 | if (r[i] < 0) 15 | r[i] += 2147483647; 16 | } 17 | for (i = 31; i < 34; i++) 18 | r[i] = r[i - 31]; 19 | for (i = 34; i < 344; i++) 20 | r[i] = r[i - 31] + r[i - 3]; 21 | initialize = 1; 22 | } 23 | t = t % 656; 24 | r[t + 344] = r[t + 344 - 31] + r[t + 344 - 3]; 25 | t++; 26 | return (unsigned int)r[t - 1 + 344] % 5 + 1; 27 | } 28 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/lib/rand.c: -------------------------------------------------------------------------------- 1 | #include "rand.h" 2 | 3 | int initialize = 0; 4 | int r[1000]; 5 | int t = 0; 6 | 7 | unsigned int rand() { 8 | int i; 9 | 10 | if (!initialize) { 11 | r[0] = SEED; 12 | for (i = 1; i < 31; i++) { 13 | r[i] = (16807LL * r[i - 1]) % 2147483647; 14 | if (r[i] < 0) 15 | r[i] += 2147483647; 16 | } 17 | for (i = 31; i < 34; i++) 18 | r[i] = r[i - 31]; 19 | for (i = 34; i < 344; i++) 20 | r[i] = r[i - 31] + r[i - 3]; 21 | initialize = 1; 22 | } 23 | t = t % 656; 24 | r[t + 344] = r[t + 344 - 31] + r[t + 344 - 3]; 25 | t++; 26 | return (unsigned int)r[t - 1 + 344] % 5 + 1; 27 | } 28 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/lib/rand.c: -------------------------------------------------------------------------------- 1 | #include "rand.h" 2 | 3 | int initialize = 0; 4 | int r[1000]; 5 | int t = 0; 6 | 7 | unsigned int rand() { 8 | int i; 9 | 10 | if (!initialize) { 11 | r[0] = SEED; 12 | for (i = 1; i < 31; i++) { 13 | r[i] = (16807LL * r[i - 1]) % 2147483647; 14 | if (r[i] < 0) 15 | r[i] += 2147483647; 16 | } 17 | for (i = 31; i < 34; i++) 18 | r[i] = r[i - 31]; 19 | for (i = 34; i < 344; i++) 20 | r[i] = r[i - 31] + r[i - 3]; 21 | initialize = 1; 22 | } 23 | t = t % 656; 24 | r[t + 344] = r[t + 344 - 31] + r[t + 344 - 3]; 25 | t++; 26 | return (unsigned int)r[t - 1 + 344] % 5 + 1; 27 | } 28 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/lib/rand.c: -------------------------------------------------------------------------------- 1 | #include "rand.h" 2 | 3 | int initialize = 0; 4 | int r[1000]; 5 | int t = 0; 6 | 7 | unsigned int rand() { 8 | int i; 9 | 10 | if (!initialize) { 11 | r[0] = SEED; 12 | for (i = 1; i < 31; i++) { 13 | r[i] = (16807LL * r[i - 1]) % 2147483647; 14 | if (r[i] < 0) 15 | r[i] += 2147483647; 16 | } 17 | for (i = 31; i < 34; i++) 18 | r[i] = r[i - 31]; 19 | for (i = 34; i < 344; i++) 20 | r[i] = r[i - 31] + r[i - 3]; 21 | initialize = 1; 22 | } 23 | t = t % 656; 24 | r[t + 344] = r[t + 344 - 31] + r[t + 344 - 3]; 25 | t++; 26 | return (unsigned int)r[t - 1 + 344] % 5 + 1; 27 | } 28 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | OBJ = $(wildcard ${TOP}/init/*.o) $(wildcard ${TOP}/driver/*.o) $(wildcard ${TOP}/lib/*.o) $(wildcard ${TOP}/arch/riscv/kernel/*.o) 3 | 4 | .PHONY: all clean 5 | 6 | 7 | all: ./Makefile ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 8 | ${TOP}/vmlinux: ${OBJ} ./kernel/vmlinux.lds ./Makefile 9 | @# link to get the vmlinux 10 | @${LD} ${OBJ} -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 11 | 12 | ./boot/Image: ${TOP}/vmlinux 13 | @# use vmlinux to gen Image 14 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 15 | 16 | ${TOP}/System.map: ${TOP}/vmlinux 17 | @# print kernel symbol table 18 | @nm ${TOP}/vmlinux > ${TOP}/System.map 19 | 20 | 21 | clean: 22 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | .PHONY: all 3 | all: ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 4 | 5 | OBJS = ${TOP}/init/main.o ${TOP}/init/test.o ${TOP}/lib/put.o ${TOP}/lib/rand.o ./kernel/head.o ./kernel/entry.o ./kernel/strap.o ./kernel/sched.o# ./kernel/switch.o 6 | 7 | ${TOP}/vmlinux: ${OBJS} ./kernel/vmlinux.lds 8 | @# link to get the vmlinux 9 | @${LD} $^ -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 10 | 11 | ./boot/Image: ${TOP}/vmlinux 12 | @# use vmlinux to gen Image 13 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 14 | 15 | ${TOP}/System.map: ${TOP}/vmlinux 16 | @# print kernel symbol table 17 | @nm ${TOP}/vmlinux > ${TOP}/System.map 18 | 19 | .PHONY: clean 20 | clean: 21 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | .PHONY: all 3 | all: ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 4 | 5 | ${TOP}/vmlinux: ${TOP}/init/main.o ${TOP}/init/test.o ${TOP}/lib/put.o ./kernel/head.o ./kernel/entry.o ./kernel/strap.o ./kernel/vmlinux.lds 6 | @# link to get the vmlinux 7 | @${LD} ${TOP}/init/main.o ${TOP}/init/test.o ${TOP}/lib/put.o ./kernel/head.o ./kernel/entry.o ./kernel/strap.o -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 8 | 9 | ./boot/Image: ${TOP}/vmlinux 10 | @# use vmlinux to gen Image 11 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 12 | 13 | ${TOP}/System.map: ${TOP}/vmlinux 14 | @# print kernel symbol table 15 | @nm ${TOP}/vmlinux > ${TOP}/System.map 16 | 17 | .PHONY: clean 18 | clean: 19 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_riscv 2 | .PHONY: all 3 | all: ./Makefile ${TOP}/vmlinux ./boot/Image ${TOP}/System.map 4 | 5 | OBJS = ${TOP}/init/main.o ${TOP}/init/test.o ${TOP}/lib/put.o ${TOP}/lib/rand.o ./kernel/head.o ./kernel/entry.o ./kernel/strap.o ./kernel/sched.o ./kernel/vm.o 6 | 7 | ${TOP}/vmlinux: ${OBJS} ./kernel/vmlinux.lds ./Makefile 8 | @# link to get the vmlinux 9 | @${LD} ${OBJS} -T ./kernel/vmlinux.lds -o ${TOP}/vmlinux 10 | 11 | ./boot/Image: ${TOP}/vmlinux 12 | @# use vmlinux to gen Image 13 | @${OBJCOPY} ${TOP}/vmlinux ./boot/Image 14 | 15 | ${TOP}/System.map: ${TOP}/vmlinux 16 | @# print kernel symbol table 17 | @nm ${TOP}/vmlinux > ${TOP}/System.map 18 | 19 | .PHONY: clean 20 | clean: 21 | @rm -f ${TOP}/vmlinux ./boot/Image ${TOP}/System.map -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/misc/helper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "arch/riscv/include/vm.h" 6 | 7 | int main(int argc, char const *argv[]) { 8 | using namespace std; 9 | 10 | // L2 11 | uint64 VA = 0x80000ffc; 12 | printf("0x%lx 0x%lx\n", VAtoVPN2(VA), 0x80008000 + VAtoVPN2(VA) * 8); 13 | 14 | // L1 15 | uint64 pte2 = 0x20002c01; 16 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte2), (PTEtoPPN(pte2) << 12) + VAtoVPN1(VA) * 8); 17 | 18 | // L0 19 | uint64 pte1 = 0x20003001; 20 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte1), (PTEtoPPN(pte1) << 12) + VAtoVPN0(VA) * 8); 21 | 22 | // Phy 23 | uint64 pte0 = 0x2000000f; 24 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte0), (PTEtoPPN(pte0) << 12) + (VA & 0xfff)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/misc/help.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "arch/riscv/include/vm.h" 6 | 7 | int main(int argc, char const *argv[]) { 8 | using namespace std; 9 | 10 | // L2 11 | uint64 VA = 0x80000ffc; 12 | printf("0x%lx 0x%lx\n", VAtoVPN2(VA), 0x80008000 + VAtoVPN2(VA) * 8); 13 | 14 | // L1 15 | uint64 pte2 = 0x20002c01; 16 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte2), (PTEtoPPN(pte2) << 12) + VAtoVPN1(VA) * 8); 17 | 18 | // L0 19 | uint64 pte1 = 0x20003001; 20 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte1), (PTEtoPPN(pte1) << 12) + VAtoVPN0(VA) * 8); 21 | 22 | // Phy 23 | uint64 pte0 = 0x2000000f; 24 | printf("0x%lx 0x%lx\n", PTEtoPPN(pte0), (PTEtoPPN(pte0) << 12) + (VA & 0xfff)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Lab1/lab1/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | .global _start 4 | _start: 5 | # set mstatus, turn off mie and mipe 6 | li t1, 0x8 7 | csrrc x0, mstatus, t1 8 | 9 | # set mtvec(M mode异常处理地址) 10 | la t1, mtvec_base 11 | sll t1, t1, 2 12 | or t1, t1, 1 # mode = vectored 13 | csrrw x0, mtvec, t1 14 | 15 | # switch from M to S 16 | li t1, 0x1000 # MPP[1] = 0 17 | csrrc x0, mstatus, t1 18 | li t1, 0x800 # MPP[0] = 1 19 | csrrs x0, mstatus, t1 20 | la t1, S_Mode 21 | csrrw x0, mepc, t1 22 | mret 23 | 24 | S_Mode: 25 | # set stvec(S mode异常处理地址) 26 | la t1, stvec_base 27 | sll t1, t1, 2 28 | or t1, t1, 1 # mode = vectored 29 | csrrw x0, stvec, t1 30 | 31 | # set sp 32 | la sp, stack_top 33 | 34 | # jump to start_kernel in main.c 35 | call start_kernel 36 | 37 | .global _end 38 | _end: 39 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/strap.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file strap.c 3 | * @author Scott Chen 4 | * @brief the implementation S trap handling of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | */ 9 | #include "put.h" 10 | 11 | void strap_TimerInt(void) { 12 | static int counter = 0; 13 | puts("[S] Supervisor Mode Timer Interrupt "); 14 | putd(counter++); 15 | puts("\n"); 16 | return; 17 | } 18 | 19 | void strap_instPF(void) { 20 | puts("[S] Supervisor Mode Page Fault Exception While Reading Instructions\n"); 21 | return; 22 | } 23 | 24 | void strap_loadPF(void) { 25 | puts("[S] Supervisor Mode Page Fault Exception While Loading Data\n"); 26 | return; 27 | } 28 | 29 | void strap_storePF(void) { 30 | puts("[S] Supervisor Mode Page Fault Exception While Storing Data\n"); 31 | return; 32 | } -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/getpid.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "syscall.h" 3 | 4 | register void *current_sp __asm__("sp"); 5 | 6 | static inline long getpid() { 7 | long ret; 8 | asm volatile("li a7, %1\n" 9 | "ecall\n" 10 | "mv %0, a0\n" 11 | : "+r"(ret) 12 | : "i"(SYS_GETPID)); 13 | return ret; 14 | } 15 | 16 | static inline long fork() { 17 | long ret; 18 | asm volatile("li a7, %1\n" 19 | "ecall\n" 20 | "mv %0, a0\n" 21 | : "+r"(ret) 22 | : "i"(SYS_FORK)); 23 | return ret; 24 | } 25 | 26 | int main() { 27 | long ret; 28 | // ret = fork(); 29 | // ret = fork(); 30 | while (1) { 31 | printf("[User] pid: %ld, sp is %lx\n", getpid(), current_sp); 32 | for (unsigned int i = 0; i < 100000000; i++) 33 | ; 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/init/main.c: -------------------------------------------------------------------------------- 1 | #include "device.h" 2 | #include "sched.h" 3 | #include "stdio.h" 4 | 5 | #define SIFIVE_TEST 0x100000 6 | #define VIRT_TEST_FINISHER_PASS 0x5555 7 | 8 | memmap_t __mmio[] = {[UART_MMIO] = {0x10000000, 0x100}, 9 | [CLINT_MMIO] = {0x2000000, 0x10000}, 10 | [PLIC_MMIO] = {0xc000000, 0x4000000}, 11 | [POWEROFF_MMIO] = {0x100000, 0x1000}, 12 | [DRAM_MMIO] = {0x80000000, 0x0}, 13 | [NULL_MMIO] = {0x0, 0x0}}; 14 | 15 | void device_init() { 16 | register_console(&console_ns16550a); 17 | register_poweroff(&poweroff_sifive_test); 18 | } 19 | 20 | int os_test() { 21 | puts("ZJU OS LAB 5 3180103012/GROUP-17\n"); 22 | puts("task init...\n"); 23 | 24 | task_init(); 25 | for (;;) 26 | ; 27 | 28 | return 0; 29 | } 30 | 31 | int start_kernel() { 32 | os_test(); 33 | asm("sh %0, 0(%1)" : : "r"(VIRT_TEST_FINISHER_PASS), "r"(SIFIVE_TEST)); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/lib/put.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | 3 | int puts(const char *s) { 4 | while (*s != '\0') { 5 | *UART_ADDR = (unsigned char)(*s); 6 | s++; 7 | } 8 | return 0; 9 | } 10 | 11 | static unsigned char hex_map[16] = { 12 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 13 | 14 | void putd(long x) { 15 | long digit = 1, tmp = x; 16 | while (tmp >= 10) { 17 | digit *= 10; 18 | tmp /= 10; 19 | } 20 | while (digit >= 1) { 21 | *UART_ADDR = hex_map[x / digit]; 22 | x %= digit; 23 | digit /= 10; 24 | } 25 | return; 26 | } 27 | 28 | void putx(unsigned long x) { 29 | unsigned long digit = 1, tmp = x; 30 | 31 | puts("0x"); 32 | if (x == 0) { 33 | puts("0"); 34 | return; 35 | } 36 | while (tmp >= 16) { 37 | digit *= 16; 38 | tmp /= 16; 39 | } 40 | while (digit >= 1) { 41 | *UART_ADDR = hex_map[x / digit]; 42 | x %= digit; 43 | digit /= 16; 44 | } 45 | return; 46 | } 47 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of Zhejiang University Operating System Courses Project 2 | # This program is under MIT license, see http://phvntom.tech/LICENSE.txt 3 | 4 | CROSS_PREFIX = riscv64-unknown-elf- 5 | CC = $(CROSS_PREFIX)gcc 6 | LD = $(CROSS_PREFIX)ld 7 | AR = $(CROSS_PREFIX)ar 8 | OBJCOPY = $(CROSS_PREFIX)objcopy 9 | 10 | ISA = rv64ima 11 | ABI = lp64 12 | CFLAG = -march=$(ISA) -mabi=$(ABI) -mcmodel=medany \ 13 | -ffunction-sections -fdata-sections -nostartfiles \ 14 | -nostdlib -nostdinc -fno-builtin \ 15 | -g3 -static -lgcc -O1 -Wl,--gc-section -Wl,--print-gc-sections 16 | 17 | ASM_SRC = $(sort $(wildcard *.S)) 18 | C_SRC = $(sort $(wildcard *.c)) 19 | OBJ = $(patsubst %.S,%.o,$(ASM_SRC)) $(patsubst %.c,%.o,$(C_SRC)) 20 | 21 | all: hello.bin 22 | 23 | %.o:%.c Makefile 24 | @$(CC) $(CFLAG) -c $< 25 | 26 | %.o:%.S Makefile 27 | @$(CC) $(CFLAG) -c $< 28 | 29 | hello.bin: $(OBJ) 30 | @$(CC) $(CFLAG) -T link.ld -o hello.elf $(OBJ) 31 | @$(OBJCOPY) hello.elf -O binary hello.bin 32 | 33 | clean: 34 | @rm -rf *.o hello.* 35 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/include/device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stddef.h" 4 | 5 | // TODO: support other boards 6 | enum { UART_MMIO, CLINT_MMIO, PLIC_MMIO, POWEROFF_MMIO, DRAM_MMIO, NULL_MMIO }; 7 | 8 | typedef struct memmap { 9 | unsigned long base; 10 | unsigned long size; 11 | } memmap_t; 12 | 13 | extern memmap_t __mmio[]; 14 | 15 | unsigned long get_device_addr(unsigned long key); 16 | unsigned long get_device_size(unsigned long key); 17 | 18 | // UART 19 | typedef struct console_device { 20 | void (*init)(); 21 | char (*getchar)(); 22 | void (*putchar)(char); 23 | } console_device_t; 24 | 25 | void register_console(console_device_t *dev); 26 | extern console_device_t *console_dev; 27 | extern console_device_t console_none; 28 | extern console_device_t console_ns16550a; 29 | 30 | // POWEROFF 31 | typedef struct poweroff_device { 32 | void (*init)(); 33 | void (*poweroff)(); 34 | } poweroff_device_t; 35 | 36 | void register_poweroff(poweroff_device_t *dev); 37 | extern poweroff_device_t *poweroff_dev; 38 | extern poweroff_device_t poweroff_none; 39 | extern poweroff_device_t poweroff_sifive_test; -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/misc/syscall.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file syscall.c 3 | * @author Scott Chen 4 | * @brief My Implementation of the API of some syscalls, need no to be compiled in this lab 5 | * @version 0.1 6 | * @date 2020-12-14 7 | */ 8 | #include "syscall.h" 9 | #include "put.h" 10 | #include "sched.h" 11 | 12 | /** 13 | * @brief syscall_id=64 14 | * 15 | * @param fd file descriptor, 1 for stdout 16 | * @param buf address where print starts 17 | * @param count max length of string 18 | * @return size_t, number of chars that being printed 19 | */ 20 | size_t sys_write(unsigned int fd, const char *buf, size_t count) { 21 | size_t retVal; 22 | asm("li a7, %0" ::"n"(SYS_WRITE_ID)); 23 | asm("ld a0, %0" ::"m"(fd)); 24 | asm("ld a1, %0" ::"m"(buf)); 25 | asm("ld a2, %0" ::"m"(count)); 26 | asm("ecall"); 27 | asm("sd a0, %0" ::"m"(retVal)); 28 | return retVal; 29 | } 30 | 31 | /** 32 | * @brief syscall_id=172 33 | * 34 | * @return pid_t, current thread's pid 35 | */ 36 | pid_t sys_getpid(void) { 37 | pid_t retVal; 38 | asm("li a7, %0" ::"n"(SYS_GETPID_ID)); 39 | asm("ecall"); 40 | asm("sd a0, %0" ::"m"(retVal)); 41 | return retVal; 42 | } 43 | -------------------------------------------------------------------------------- /Lab1/lab1/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab1 2 | # export TOP=~/lab1/ 3 | # export RISCV=/opt/riscv 4 | # export PATH=$PATH:$RISCV/bin 5 | 6 | export 7 | CROSS_= riscv64-unknown-elf- 8 | AR=${CROSS_}ar 9 | GCC=${CROSS_}gcc 10 | LD=${CROSS_}ld 11 | OBJCOPY=${CROSS_}objcopy 12 | 13 | ISA ?= rv64imafd 14 | ABI ?= lp64 15 | 16 | INCLUDE = -I ../include 17 | CF = -O3 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections 18 | CFLAG = ${CF} ${INCLUDE} 19 | 20 | .PHONY: all 21 | all: 22 | @make -C ./init/ 23 | @make -C ./arch/riscv/kernel/ 24 | @make -C ./arch/riscv/ 25 | @echo "\e[35m==== Build Successfully ====\e[0m" 26 | 27 | .PHONY: run 28 | run: 29 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux 30 | @echo "\e[32m==== Run Successfully ====\e[0m" 31 | 32 | .PHONY: debug 33 | debug: 34 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -S -s 35 | # riscv64-unknown-linux-gnu-gdb vmlinux 36 | 37 | .PHONY: clean 38 | clean: 39 | @rm -f ./vmlinux ./System.map 40 | @make -C ./init/ clean 41 | @make -C ./arch/riscv/kernel/ clean 42 | @make -C ./arch/riscv/ clean 43 | @echo "\e[36m==== Clean Successfully ====\e[0m" 44 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/include/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_H 2 | #define _VM_H 3 | 4 | #include "types.h" 5 | 6 | #define NULL 0x0 7 | 8 | #define KERNEL_PHY_BASE 0x80000000 9 | #define KERNEL_VIR_BASE 0xffffffe000000000 10 | #define USER_PHY_ENTRY 0x84000000 11 | #define USER_STACK_TOP 0xffffffdf80000000 12 | 13 | #define USER_MAPPING_SIZE 0x100000 // 1MB 14 | #define KERNEL_MAPPING_SIZE 0x1000000 // 16MB 15 | 16 | #define PAGE_SIZE 0x1000 // 4096 bytes 17 | #define PAGE_ENTRY_NUM 0x200 // 512 18 | 19 | #define FREE_SPACE_SIZE 0x8000000 // [rt_pg_addr, rt_pg_addr + limit): 8MB 20 | 21 | #define KERNEL_TEXT_SIZE 0x3000 22 | #define KERNEL_RODATA_SIZE 0x1000 23 | 24 | #define PERM_R 0b10 25 | #define PERM_W 0b100 26 | #define PERM_X 0b1000 27 | #define PROT_U 0b10000 28 | 29 | struct free_list_node { 30 | void *base; 31 | size_t limit; 32 | struct free_list_node *next; 33 | }; 34 | 35 | /** 36 | * @brief Struct of PTE listed below: 37 | * PPN2 53:28; PPN1 27:19; PPN0 18:10; rsw 9:8; DAGUXWRV 8:0 38 | */ 39 | struct pageTable { 40 | uint64 PTE_list[512]; 41 | }; 42 | 43 | void create_mapping(uint64 *pgtbl, uint64 va, uint64 pa, uint64 sz, int prot); 44 | void kernel_paging_init(void); 45 | uint64 *user_paging_init(void); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/driver/device.c: -------------------------------------------------------------------------------- 1 | #include "device.h" 2 | 3 | console_device_t *console_dev = &console_none; 4 | poweroff_device_t *poweroff_dev = &poweroff_none; 5 | 6 | void register_console(console_device_t *dev) { 7 | console_dev = dev; 8 | if (dev->init) 9 | dev->init(); 10 | } 11 | 12 | void register_poweroff(poweroff_device_t *dev) { 13 | poweroff_dev = dev; 14 | if (dev->init) 15 | dev->init(); 16 | } 17 | 18 | static char default_getchar() { 19 | asm volatile("ebreak"); 20 | return 0; 21 | } 22 | 23 | static void default_putchar(char ch) { 24 | asm volatile("ebreak"); 25 | } 26 | 27 | static void default_poweroff(int status) { 28 | asm volatile("ebreak"); 29 | while (1) { 30 | asm volatile("" : : : "memory"); 31 | } 32 | } 33 | 34 | console_device_t console_none = {NULL, default_getchar, default_putchar}; 35 | 36 | poweroff_device_t poweroff_none = { 37 | NULL, 38 | default_poweroff, 39 | }; 40 | 41 | unsigned long get_device_addr(unsigned long key) { 42 | memmap_t *map = __mmio; 43 | if (key >= NULL_MMIO) 44 | return 0; 45 | else 46 | return __mmio[key].base; 47 | } 48 | 49 | unsigned long get_device_size(unsigned long key) { 50 | memmap_t *map = __mmio; 51 | if (key >= NULL_MMIO) 52 | return 0; 53 | else 54 | return __mmio[key].size; 55 | } -------------------------------------------------------------------------------- /Lab2/source/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab2 2 | # alias gdb=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb 3 | export TOP=$(shell pwd) 4 | export RISCV=/opt/riscv 5 | export PATH:=${PATH}:${RISCV}/bin 6 | 7 | export 8 | CROSS_=riscv64-unknown-elf- 9 | AR=${CROSS_}ar 10 | GCC=${CROSS_}gcc 11 | LD=${CROSS_}ld 12 | OBJCOPY=${CROSS_}objcopy 13 | 14 | ISA ?= rv64imafd 15 | ABI ?= lp64 16 | 17 | INCLUDE = -I ../include 18 | CF = -O0 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections 19 | CFLAG = ${CF} ${INCLUDE} -g 20 | 21 | .PHONY: all 22 | all: 23 | @make -C ./lib/ 24 | @make -C ./init/ 25 | @make -C ./arch/riscv/kernel/ 26 | @make -C ./arch/riscv/ 27 | @echo "\e[35m==== Build Successfully ====\e[0m" 28 | 29 | .PHONY: run 30 | run: 31 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux 32 | @echo "\e[32m==== Run Successfully ====\e[0m" 33 | 34 | .PHONY: debug 35 | debug: 36 | @echo "\e[32m==== Start Debugging ====\e[0m" 37 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -S -s 38 | @echo "\e[32m==== End Debugging ====\e[0m" 39 | 40 | .PHONY: clean 41 | clean: 42 | @rm -f ./vmlinux ./System.map 43 | @make -C ./init/ clean 44 | @make -C ./lib/ clean 45 | @make -C ./arch/riscv/kernel/ clean 46 | @make -C ./arch/riscv/ clean 47 | @echo "\e[36m==== Clean Successfully ====\e[0m" 48 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab3 2 | # sed -i '$aalias gdb=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb' ~/.bashrc 3 | export TOP=$(shell pwd) 4 | export RISCV=/opt/riscv 5 | export PATH:=${PATH}:${RISCV}/bin 6 | 7 | export 8 | CROSS_=riscv64-unknown-elf- 9 | AR=${CROSS_}ar 10 | GCC=${CROSS_}gcc 11 | LD=${CROSS_}ld 12 | OBJCOPY=${CROSS_}objcopy 13 | 14 | ISA ?= rv64imafd 15 | ABI ?= lp64 16 | 17 | INCLUDE = -I ${TOP}/include/ -I ${TOP}/arch/riscv/include/ 18 | CF = -O0 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections 19 | # CFLAG = ${CF} ${INCLUDE} -g -D SJF 20 | CFLAG = ${CF} ${INCLUDE} -g -D PRIORITY 21 | 22 | .PHONY: all 23 | all: 24 | @make -C ./lib/ 25 | @make -C ./init/ 26 | @make -C ./arch/riscv/kernel/ 27 | @make -C ./arch/riscv/ 28 | @echo "\e[35m==== Build Successfully ====\e[0m" 29 | 30 | .PHONY: run 31 | run: 32 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux 33 | @echo "\e[32m==== Run Successfully ====\e[0m" 34 | 35 | .PHONY: debug 36 | debug: 37 | @echo "\e[32m==== Start Debugging ====\e[0m" 38 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -S -s 39 | @echo "\e[32m==== End Debugging ====\e[0m" 40 | 41 | .PHONY: clean 42 | clean: 43 | @rm -f ./vmlinux ./System.map 44 | @make -C ./init/ clean 45 | @make -C ./lib/ clean 46 | @make -C ./arch/riscv/kernel/ clean 47 | @make -C ./arch/riscv/ clean 48 | @echo "\e[36m==== Clean Successfully ====\e[0m" 49 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/mm.h: -------------------------------------------------------------------------------- 1 | #ifndef _MM_H 2 | #define _MM_H 3 | 4 | #include "types.h" 5 | 6 | // #define PROT_NONE 0x0 // 页内容不可被访问 7 | // #define PROT_READ 0x1 // 页内容可以被读取 8 | // #define PROT_WRITE 0x2 // 页可以被写入内容 9 | // #define PROT_EXEC 0x4 // 页内容可以被执行 10 | #define PROT_SEM 0x8 // (可选) 页面可能用于原子操作(atomic operation) 11 | #define PROT_GROWSDOWN 0x01000000 12 | #define PROT_GROWSUP 0x02000000 13 | 14 | #define MAP_PRIVATE 0x2 15 | #define MAP_ANONYMOUS 0x20 16 | 17 | typedef struct { 18 | unsigned long pgprot; 19 | } pgprot_t; 20 | 21 | struct vm_area_struct { 22 | /* Our start address within vm_area. */ 23 | unsigned long vm_start; 24 | /* The first byte **after** our end address within vm_area. */ 25 | unsigned long vm_end; 26 | /* linked list of VM areas per task, sorted by address. */ 27 | struct vm_area_struct *vm_next, *vm_prev; 28 | /* The address space we belong to. */ 29 | struct mm_struct *vm_mm; 30 | /* Access permissions of this VMA. */ 31 | pgprot_t vm_page_prot; 32 | /* Flags*/ 33 | unsigned long vm_flags; 34 | }; 35 | 36 | struct mm_struct { 37 | uint64 *rtpg_addr; 38 | struct vm_area_struct *vm_area_list; 39 | }; 40 | 41 | void *do_mmap(struct mm_struct *mm, void *start, size_t length, int prot, unsigned long flags, 42 | unsigned long pgoff); 43 | void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset); 44 | int munmap(void *start, size_t length); 45 | int mprotect(void *__addr, size_t __len, int __prot); 46 | 47 | #endif -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | 3 | .global _start 4 | _start: 5 | # init .bss 6 | la t0, .bss # pointer 7 | la t1, bss_size # counter 8 | bss_init_loop: 9 | sb zero, 0(t0) 10 | addi t0, t0, 1 11 | addi t1, t1, -1 12 | bne t1, zero, bss_init_loop 13 | 14 | # set mtimecmp to mtime+time_sep 15 | la t0, mtime_addr # RV64, t0 is of 64 bit 16 | ld t1, 0(t0) # mtime->t1 17 | la t0, time_sep_init 18 | add t1, t1, t0 19 | la t0, mtimecmp_addr 20 | sd t1, 0(t0) 21 | 22 | # set time int delegation 23 | li t1, 0x20 # mi[e|p][5]=sti[e|p] 24 | csrs mideleg, t1 25 | 26 | # set mstatus.mpie 27 | li t1, 0x80 # mstatus[7] 28 | csrs mstatus, t1 29 | 30 | # set mstatus.mie, mie.mtie, sstatus.sie, sie.stie 31 | li t1, 0x8 # mstatus[3] 32 | csrs mstatus, t1 33 | li t1, 0x80 # mie[7] 34 | csrs mie, t1 35 | li t1, 0x2 # sstatus[1] 36 | csrs sstatus, t1 37 | li t1, 0x20 # sie[5] 38 | csrs sie, t1 39 | 40 | # set mtvec(M mode) 41 | la t1, trap_m # mode = directed 42 | csrw mtvec, t1 43 | 44 | # switch from M to S 45 | li t1, 0x1000 # MPP[1] = 0 46 | csrc mstatus, t1 47 | li t1, 0x800 # MPP[0] = 1 48 | csrs mstatus, t1 49 | 50 | la t1, S_Mode 51 | csrw mepc, t1 52 | mret 53 | 54 | S_Mode: 55 | # set stvec(S mode) 56 | la t1, trap_s # mode = directed 57 | csrw stvec, t1 58 | 59 | # set sp 60 | la sp, stack_top 61 | 62 | # jump to start_kernel in main.c 63 | call start_kernel 64 | 65 | .global _end 66 | _end: 67 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | 3 | .global _start 4 | _start: 5 | # init .bss 6 | la t0, .bss # pointer 7 | la t1, bss_size # counter 8 | bss_init_loop: 9 | sb zero, 0(t0) 10 | addi t0, t0, 1 11 | addi t1, t1, -1 12 | bne t1, zero, bss_init_loop 13 | 14 | # set mtimecmp to mtime+time_sep 15 | la t0, mtime_addr # RV64, t0 is of 64 bit 16 | ld t1, 0(t0) # mtime->t1 17 | la t0, time_sep_init 18 | add t1, t1, t0 19 | la t0, mtimecmp_addr 20 | sd t1, 0(t0) 21 | 22 | # set time int delegation 23 | li t1, 0x20 # mi[e|p][5]=sti[e|p] 24 | csrs mideleg, t1 25 | 26 | # set mstatus.mpie 27 | li t1, 0x80 # mstatus[7] 28 | csrs mstatus, t1 29 | 30 | # set mstatus.mie, mie.mtie, sstatus.sie, sie.stie 31 | li t1, 0x8 # mstatus[3] 32 | csrs mstatus, t1 33 | li t1, 0x80 # mie[7] 34 | csrs mie, t1 35 | li t1, 0x2 # sstatus[1] 36 | csrs sstatus, t1 37 | li t1, 0x20 # sie[5] 38 | csrs sie, t1 39 | 40 | # set mtvec(M mode) 41 | la t1, trap_m # mode = directed 42 | csrw mtvec, t1 43 | 44 | # switch from M to S 45 | li t1, 0x1000 # MPP[1] = 0 46 | csrc mstatus, t1 47 | li t1, 0x800 # MPP[0] = 1 48 | csrs mstatus, t1 49 | 50 | la t1, S_Mode 51 | csrw mepc, t1 52 | mret 53 | 54 | S_Mode: 55 | # set stvec(S mode) 56 | la t1, trap_s # mode = directed 57 | csrw stvec, t1 58 | 59 | # set sp 60 | la sp, stack_top 61 | 62 | # jump to start_kernel in main.c 63 | call start_kernel 64 | 65 | .global _end 66 | _end: 67 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/driver/rinux_driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pages 4 | #define PHY_START 0x80000000L 5 | #define PHY_END (PHY_START + 16 * 1024 * 1024) 6 | 7 | #define PAGE_SIZE 4096L 8 | #define PAGE_SHIFT 12 9 | 10 | #define PAGE_UP(addr) ((((uint64)addr) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) 11 | #define PAGE_DOWN(addr) ((((uint64)addr)) & ~(PAGE_SIZE - 1)) 12 | 13 | #define PTE_V (1L << 0) 14 | #define PTE_R (1L << 1) 15 | #define PTE_W (1L << 2) 16 | #define PTE_X (1L << 3) 17 | #define PTE_U (1L << 4) 18 | #define PTE_G (1L << 5) 19 | #define PTE_A (1L << 6) 20 | #define PTE_D (1L << 7) 21 | 22 | #define PA2PTE(pa) ((((uint64)pa) >> 12) << 10) 23 | #define PTE2PA(pte) (((pte) >> 10) << 12) 24 | #define PTE_FLAGS(pte) ((pte)&0x3FF) 25 | 26 | #define PAGE_OFFSET 0xffffffe000000000L 27 | #define VA_PA_OFFSET ((uint64)PAGE_OFFSET - (uint64)PHY_START) 28 | #define VA2PA(va) ((uint64)va - (uint64)VA_PA_OFFSET) 29 | #define PA2VA(pa) ((uint64)pa + (uint64)VA_PA_OFFSET) 30 | 31 | #define PXMASK 0x1FF 32 | #define PXSHIFT(level) (PAGE_SHIFT + (9 * (level))) 33 | #define PX(level, va) ((((uint64)(va)) >> PXSHIFT(level)) & PXMASK) 34 | 35 | #define SATP_SV39 (8L << 60) 36 | #define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64)pagetable) >> 12)) 37 | 38 | #define PAGE_ALLOC 1 39 | #define NO_PAGE_ALLOC 0 40 | 41 | #define write_csr(reg, val) ({ asm volatile("csrw " #reg ", %0" ::"rK"(val)); }) 42 | #define read_csr(reg) \ 43 | ({ \ 44 | unsigned long __tmp; \ 45 | asm volatile("csrr %0, " #reg : "=r"(__tmp)); \ 46 | __tmp; \ 47 | }) 48 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_H 2 | #define _VM_H 3 | 4 | #include "types.h" 5 | 6 | #define KERNEL_PHY_BASE 0x80000000 7 | #define KERNEL_VIR_BASE 0xffffffe000000000 8 | #define USER_PHY_ENTRY 0x84000000 9 | #define USER_STACK_TOP 0xffffffdf80000000 10 | 11 | #define USER_MAPPING_SIZE 0x1000 12 | #define KERNEL_MAPPING_SIZE 0x1000000 // 16MB 13 | 14 | #ifndef PAGE_SIZE 15 | #define PAGE_SIZE 0x1000 // 4096 bytes 16 | #endif 17 | #define PAGE_ENTRY_NUM 0x200 // 512 18 | 19 | #define FREE_SPACE_SIZE 0x8000000 // [rt_pg_addr, rt_pg_addr + limit): 8MB 20 | 21 | #define KERNEL_PROG_SIZE 0x1a000 22 | #define KERNEL_TEXT_SIZE 0x5000 23 | #define KERNEL_RODATA_SIZE 0x1000 24 | 25 | #define PERM_R 0b10 26 | #define PERM_W 0b100 27 | #define PERM_X 0b1000 28 | #define PROT_U 0b10000 29 | 30 | #define UART_PHY_ADDR ((volatile unsigned char *)0x10000000) 31 | #define UART_VIR_ADDR ((volatile unsigned char *)0xffffffdf90000000) 32 | 33 | #define VA2PA(__VA) ((void *)((uint64)(__VA)-0xffffffdf80000000)) 34 | #define PA2VA(__PA) ((void *)((uint64)(__PA) + 0xffffffdf80000000)) 35 | 36 | #define PAGE_CEIL(__A) (((uint64)(__A)-1) / PAGE_SIZE + 1) 37 | #define PAGE_FLOOR(__A) ((uint64)(__A) / PAGE_SIZE) 38 | 39 | struct free_list_node { 40 | void *base; 41 | size_t limit; 42 | struct free_list_node *next; 43 | }; 44 | 45 | /** 46 | * @brief Struct of PTE listed below: 47 | * PPN2 53:28; PPN1 27:19; PPN0 18:10; rsw 9:8; DAGUXWRV 8:0 48 | */ 49 | struct pageTable { 50 | uint64 PTE_list[512]; 51 | }; 52 | 53 | uint64 *page_walk(uint64 *pgtbl, uint64 va); 54 | void create_mapping(uint64 *pgtbl, uint64 va, uint64 pa, uint64 sz, int prot); 55 | void kernel_paging_init(void); 56 | uint64 *user_paging_init(void); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/kernel/strap.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file strap.c 3 | * @author Scott Chen 4 | * @brief the implementation S trap handling of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab5 8 | */ 9 | #include "put.h" 10 | #include "sched.h" 11 | #include "syscall.h" 12 | #include "types.h" 13 | 14 | void strap_TimerInt(void) { 15 | static int counter = 0; 16 | puts("[S] Supervisor Mode Timer Interrupt "); 17 | putd(counter++); 18 | puts("\n"); 19 | return; 20 | } 21 | 22 | void strap_instPF(void) { 23 | puts("[S] Supervisor Mode Page Fault Exception While Reading Instructions\n"); 24 | return; 25 | } 26 | 27 | void strap_loadPF(void) { 28 | puts("[S] Supervisor Mode Page Fault Exception While Loading Data\n"); 29 | return; 30 | } 31 | 32 | void strap_storePF(void) { 33 | puts("[S] Supervisor Mode Page Fault Exception While Storing Data\n"); 34 | return; 35 | } 36 | 37 | extern struct task_struct *current; 38 | 39 | size_t handler_sys_write(unsigned int fd, const char *buf, size_t count) { 40 | size_t cnt = 0; 41 | if (fd == 1) 42 | for (cnt = 0; buf[cnt] != 0 && cnt < count; cnt++) 43 | *UART_VIR_ADDR = (unsigned char)buf[cnt]; 44 | return cnt; 45 | } 46 | 47 | long handler_sys_getpid(void) { 48 | return current->pid; 49 | } 50 | 51 | void handler_s(uint64 scause, uint64 sepc, uint64 *regs) { 52 | uint64 syscall_id = regs[17]; // a7 53 | uint64 *syscall_argv = ®s[10]; // a0 ~ a6 54 | uint64 *syscall_ret = ®s[10]; // a0 ~ a1 55 | 56 | switch (syscall_id) { 57 | case SYS_WRITE_ID: 58 | syscall_ret[0] = handler_sys_write((unsigned int)syscall_argv[0], 59 | (char *)syscall_argv[1], (size_t)syscall_argv[2]); 60 | break; 61 | case SYS_GETPID_ID: syscall_ret[0] = handler_sys_getpid(); break; 62 | default: break; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab4 2 | # ln -s ~/lab4/.gdbinit ~/.gdbinit 3 | # sed -i '$aalias md=make\\ \\&\\&\\ make\\ debug' ~/.bashrc 4 | # sed -i '$aalias gdb=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb' ~/.bashrc 5 | # sed -i '$aalias gv=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb\\ vmlinux' ~/.bashrc 6 | export TOP=$(shell pwd) 7 | export RISCV=/opt/riscv 8 | export PATH:=${PATH}:${RISCV}/bin 9 | 10 | export 11 | CROSS_=riscv64-unknown-elf- 12 | AR=${CROSS_}ar 13 | CC=${CROSS_}gcc 14 | LD=${CROSS_}ld 15 | OBJCOPY=${CROSS_}objcopy 16 | OBJDUMP=${CROSS_}objdump 17 | READELF=${CROSS_}readelf 18 | 19 | ISA ?= rv64imafd 20 | ABI ?= lp64 21 | 22 | INCLUDE = -I ${TOP}/include/ -I ${TOP}/arch/riscv/include/ 23 | CF = -O0 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections -g 24 | CFLAG = ${CF} ${INCLUDE} -D SJF 25 | # CFLAG = ${CF} ${INCLUDE} -D PRIORITY 26 | 27 | .PHONY: all 28 | all: 29 | @make -C ${TOP}/lib/ 30 | @make -C ${TOP}/init/ 31 | @make -C ${TOP}/arch/riscv/kernel/ 32 | @make -C ${TOP}/arch/riscv/ 33 | @echo "\e[35m==== Build Successfully ====\e[0m" 34 | ${OBJDUMP} -S ${TOP}/vmlinux > ${TOP}/misc/dasm.S 35 | ${READELF} -S ${TOP}/vmlinux > ${TOP}/misc/section.txt 36 | @echo "\e[35m==== DeAsm Successfully ====\e[0m" 37 | 38 | .PHONY: run 39 | run: 40 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux 41 | @echo "\e[32m==== Run Successfully ====\e[0m" 42 | 43 | .PHONY: debug 44 | debug: 45 | @echo "\e[32m==== Start Debugging ====\e[0m" 46 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -S -s 47 | @echo "\e[32m==== End Debugging ====\e[0m" 48 | 49 | .PHONY: clean 50 | clean: 51 | @rm -f ${TOP}/vmlinux ${TOP}/System.map ${TOP}/a.out 52 | @make -C ${TOP}/init/ clean 53 | @make -C ${TOP}/lib/ clean 54 | @make -C ${TOP}/arch/riscv/kernel/ clean 55 | @make -C ${TOP}/arch/riscv/ clean 56 | @echo "\e[36m==== Clean Successfully ====\e[0m" 57 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/include/vm.h: -------------------------------------------------------------------------------- 1 | #define NULL 0x0 2 | 3 | #define PHY_BASE 0x80000000 4 | #define VIR_BASE 0xffffffe000000000 5 | #define MAPPING_SIZE 0x1000000 // 16MB 6 | 7 | #define PAGE_SIZE 0x1000 // 4096 bytes 8 | #define PAGE_ENTRY_NUM 0x200 // 512 9 | 10 | #define FREE_SPACE_SIZE 0x800000 // [rt_pg_addr, rt_pg_addr + limit): 8MB 11 | 12 | #define TEXT_SIZE 0x2000 13 | #define RODATA_SIZE 0x1000 14 | 15 | #define PERM_R 0b10 16 | #define PERM_W 0b100 17 | #define PERM_X 0b1000 18 | 19 | #define PAGING_DEBUG 0 20 | 21 | typedef unsigned long uint64; 22 | typedef unsigned char uint8; 23 | typedef unsigned long size_t; 24 | 25 | struct free_list_node { 26 | void *base; 27 | size_t limit; 28 | struct free_list_node *next; 29 | }; 30 | 31 | /** 32 | * @brief Struct of PTE listed below: 33 | * PPN2 53:28; PPN1 27:19; PPN0 18:10; rsw 9:8; DAGUXWRV 8:0 34 | */ 35 | struct pageTable { 36 | uint64 PTE_list[512]; 37 | }; 38 | 39 | #define Page_Floor(__addr) ((uint64)(__addr) & ~(uint64)(PAGE_SIZE - 1)) 40 | 41 | #define VAtoVPN2(__va) (((uint64)(__va) >> 30) & (PAGE_ENTRY_NUM - 1)) 42 | #define VAtoVPN1(__va) (((uint64)(__va) >> 21) & (PAGE_ENTRY_NUM - 1)) 43 | #define VAtoVPN0(__va) (((uint64)(__va) >> 12) & (PAGE_ENTRY_NUM - 1)) 44 | 45 | #define PAtoPPN(__pa) (((uint64)(__pa) >> 12) & 0xfffffffffff) // PPN need no division 46 | 47 | // PROT = {RSW, D, A, G, U, X, W, R, V} = {6'b0, PERM_X|W|R, V} 48 | #define LoadPTE(__pte_addr, __ppn, __perm, __v) \ 49 | { \ 50 | *__pte_addr = ((uint64)(*(__pte_addr)) & 0xffc0000000000000) | \ 51 | ((uint64)(__ppn) << 10) | ((uint64)(__perm) | (uint64)(__v)); \ 52 | } 53 | 54 | #define PTEtoPPN(__pte) (((uint64)(__pte) >> 10) & 0xfffffffffff) 55 | #define PTEtoV(__pte) ((_Bool)((uint64)(__pte)&0x1)) 56 | 57 | void create_mapping(uint64 *pgtbl, uint64 va, uint64 pa, uint64 sz, int perm); 58 | void paging_init(void); -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | MEMORY { 4 | ram (wxa!ri) : ORIGIN = 0x0000000080000000, LENGTH = 16M 5 | ramv (wxa!ri) : ORIGIN = 0xffffffe000000000, LENGTH = 4096M 6 | } 7 | PHDRS { 8 | text PT_LOAD; 9 | rodata PT_LOAD; 10 | data PT_LOAD; 11 | bss PT_LOAD; 12 | } 13 | SECTIONS { 14 | . = 0xffffffe000000000; 15 | .text : { 16 | PROVIDE(text_start = .); 17 | *(.text.init) 18 | *(.text.entry) 19 | *(.text .text.*) 20 | PROVIDE(text_end = .); 21 | } >ramv AT>ram :text 22 | .rodata : ALIGN(0x1000) { 23 | PROVIDE(rodata_start = .); 24 | . = ALIGN(16); 25 | *(.srodata .srodata.*) 26 | . = ALIGN(16); 27 | *(.rodata .rodata.*) 28 | PROVIDE(rodata_end = .); 29 | } >ramv AT>ram :rodata 30 | .data : ALIGN(0x1000) { 31 | PROVIDE(data_start = .); 32 | . = ALIGN(16); 33 | *(.sdata .sdata.*) 34 | . = ALIGN(16); 35 | *(.data .data.*) 36 | PROVIDE(data_end = .); 37 | } >ramv AT>ram :data 38 | .bss : ALIGN(0x1000) { 39 | PROVIDE(bss_start = .); 40 | . = ALIGN(16); 41 | *(.sbss .sbss.*) 42 | . = ALIGN(16); 43 | *(.bss .bss.*) 44 | PROVIDE(bss_end = .); 45 | } >ramv AT>ram :bss 46 | 47 | . = ALIGN(0x1000); 48 | . += 0x1000; 49 | init_stack_top = .; 50 | . += 0x1000; 51 | stack_top = .; 52 | _end = .; 53 | 54 | physical_base = 0x80000000; 55 | virtual_mask = 0xffffff8000000000; 56 | virtual_base = 0xffffffe000000000; 57 | phy2vir_diff = 0xffffffdf80000000; 58 | 59 | rt_pg_addr = _end; 60 | 61 | mtime_addr = 0x200bff8; 62 | mtimecmp_addr = 0x2004000; 63 | time_sep_init = 1000000; 64 | time_sep = 100000; 65 | 66 | mcause_i_MTimer = 7; 67 | 68 | mcasue_e_inst = 2; 69 | mcause_e_ldFault = 5; 70 | mcause_e_ecallS = 9; 71 | mcause_e_loadPF = 13; 72 | 73 | scause_i_STimer = 5; 74 | 75 | scause_e_instPF = 12; 76 | scause_e_loadPF = 13; 77 | scause_e_storePF = 15; 78 | 79 | medeleg_bit = 0xB000; 80 | } 81 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/driver/ns16550a.c: -------------------------------------------------------------------------------- 1 | #include "device.h" 2 | #include "rinux_driver.h" 3 | 4 | enum { 5 | UART_RBR = 0x00, /* Receive Buffer Register */ 6 | UART_THR = 0x00, /* Transmit Hold Register */ 7 | UART_IER = 0x01, /* Interrupt Enable Register */ 8 | UART_DLL = 0x00, /* Divisor LSB (LCR_DLAB) */ 9 | UART_DLM = 0x01, /* Divisor MSB (LCR_DLAB) */ 10 | UART_FCR = 0x02, /* FIFO Control Register */ 11 | UART_LCR = 0x03, /* Line Control Register */ 12 | UART_MCR = 0x04, /* Modem Control Register */ 13 | UART_LSR = 0x05, /* Line Status Register */ 14 | UART_MSR = 0x06, /* Modem Status Register */ 15 | UART_SCR = 0x07, /* Scratch Register */ 16 | 17 | UART_LCR_DLAB = 0x80, /* Divisor Latch Bit */ 18 | UART_LCR_8BIT = 0x03, /* 8-bit */ 19 | UART_LCR_PODD = 0x08, /* Parity Odd */ 20 | 21 | UART_LSR_DA = 0x01, /* Data Available */ 22 | UART_LSR_OE = 0x02, /* Overrun Error */ 23 | UART_LSR_PE = 0x04, /* Parity Error */ 24 | UART_LSR_FE = 0x08, /* Framing Error */ 25 | UART_LSR_BI = 0x10, /* Break indicator */ 26 | UART_LSR_RE = 0x20, /* THR is empty */ 27 | UART_LSR_RI = 0x40, /* THR is empty and line is idle */ 28 | UART_LSR_EF = 0x80, /* Erroneous data in FIFO */ 29 | }; 30 | 31 | static volatile unsigned char *uart; 32 | 33 | static void ns16550a_init() { 34 | uart = (unsigned char *)(void *)PA2VA(get_device_addr(UART_MMIO)); 35 | unsigned int uart_freq = 1843200; 36 | unsigned int baud_rate = 115200; 37 | unsigned int divisor = uart_freq / (16 * baud_rate); 38 | uart[UART_LCR] = UART_LCR_DLAB; 39 | uart[UART_DLL] = divisor & 0xff; 40 | uart[UART_DLM] = (divisor >> 8) & 0xff; 41 | uart[UART_LCR] = UART_LCR_PODD | UART_LCR_8BIT; 42 | } 43 | 44 | static char ns16550a_getchar() { 45 | if (uart[UART_LSR] & UART_LSR_DA) { 46 | return uart[UART_RBR]; 47 | } else { 48 | return -1; 49 | } 50 | } 51 | 52 | static void ns16550a_putchar(char ch) { 53 | while ((uart[UART_LSR] & UART_LSR_RE) == 0) 54 | ; 55 | uart[UART_THR] = ch; 56 | } 57 | 58 | console_device_t console_ns16550a = {ns16550a_init, ns16550a_getchar, ns16550a_putchar}; 59 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/slub.h: -------------------------------------------------------------------------------- 1 | #ifndef _SLUB_H 2 | #define _SLUB_H 3 | 4 | #include 5 | 6 | #define NR_PARTIAL 9 7 | #define PAGE_SHIFT 12 8 | #define PPN_SHIFT 10 9 | #ifndef PAGE_SIZE 10 | #define PAGE_SIZE (1UL << PAGE_SHIFT) 11 | #endif 12 | #define PAGE_MASK (~((1UL << PAGE_SHIFT) - 1)) 13 | #define MEM_SHIFT (24 - PAGE_SHIFT) 14 | #define STRUCTURE_SIZE 16UL 15 | 16 | struct page { 17 | unsigned long flags; 18 | int count; 19 | struct page *header; 20 | struct page *next; 21 | struct list_head slub_list; 22 | struct kmem_cache *slub; /* Pointer to slab */ 23 | void *freelist; 24 | }; 25 | 26 | struct cache_area { 27 | void *base; 28 | size_t size; 29 | void *freelist; 30 | }; 31 | 32 | struct kmem_cache { 33 | /* kmem_cache_cpu */ 34 | void **freelist; /* Pointer to next available object */ 35 | unsigned long tid; /* Globally unique transaction id */ 36 | struct page *page; /* The slab from which we are allocating */ 37 | 38 | /* Used for retrieving partial slabs, etc. */ 39 | int refcount; 40 | unsigned long min_partial; 41 | size_t size; /* The size of an object including metadata */ 42 | size_t object_size; /* The size of an object without metadata */ 43 | unsigned int offset; /* Free pointer offset */ 44 | unsigned long nr_page_per_slub; 45 | 46 | void (*init_func)(void *); 47 | unsigned int inuse; /* Offset to metadata */ 48 | unsigned int align; /* Alignment */ 49 | unsigned int red_left_pad; /* Left redzone padding size */ 50 | const char *name; /* Name (only for display!) */ 51 | struct list_head list; /* List of slab caches */ 52 | 53 | /* kmem_cache_node */ 54 | unsigned long nr_partial; 55 | struct list_head partial; 56 | #ifdef CONFIG_SLUB_DEBUG 57 | unsigned long nr_slabs; 58 | unsigned long total_objects; 59 | struct list_head full; 60 | #endif 61 | }; 62 | 63 | void slub_init(); 64 | struct kmem_cache *kmem_cache_create(const char *, size_t, unsigned int, int, void *(void *)); 65 | 66 | void *kmem_cache_alloc(struct kmem_cache *); 67 | void kmem_cache_free(void *); 68 | 69 | void *kmalloc(size_t); 70 | void kfree(const void *); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/strap.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file strap.c 3 | * @author Scott Chen 4 | * @brief the implementation S trap handling of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab5 8 | */ 9 | #include "mm.h" 10 | #include "sched.h" 11 | #include "stdio.h" 12 | #include "syscall.h" 13 | #include "types.h" 14 | 15 | void strap_TimerInt(void) { 16 | static int counter = 0; 17 | puts("[S] Supervisor Mode Timer Interrupt "); 18 | printf("%d", counter++); 19 | puts("\n"); 20 | return; 21 | } 22 | 23 | void strap_instPF(void) { 24 | puts("[S] Supervisor Mode Page Fault Exception While Reading Instructions\n"); 25 | return; 26 | } 27 | 28 | void strap_loadPF(void) { 29 | puts("[S] Supervisor Mode Page Fault Exception While Loading Data\n"); 30 | return; 31 | } 32 | 33 | void strap_storePF(void) { 34 | puts("[S] Supervisor Mode Page Fault Exception While Storing Data\n"); 35 | return; 36 | } 37 | 38 | size_t handler_sys_write(unsigned int fd, const char *buf, size_t count) { 39 | size_t cnt = 0; 40 | if (fd == 1) 41 | for (cnt = 0; buf[cnt] != 0 && cnt < count; cnt++) 42 | putchar(buf[cnt]); 43 | return cnt; 44 | } 45 | 46 | long handler_sys_getpid(void) { 47 | return current->pid; 48 | } 49 | 50 | void handler_s(uint64 scause, uint64 sepc, uint64 *regs) { 51 | uint64 id = regs[17]; // a7 52 | uint64 *argv = ®s[10]; // a0 ~ a6 53 | uint64 *ret = ®s[10]; // a0 ~ a1 54 | 55 | switch (id) { 56 | case SYS_WRITE_ID: 57 | ret[0] = 58 | handler_sys_write((unsigned int)argv[0], (char *)argv[1], (size_t)argv[2]); 59 | break; 60 | 61 | case SYS_GETPID_ID: ret[0] = handler_sys_getpid(); break; 62 | 63 | case MMAP_ID: 64 | ret[0] = mmap((void *)argv[0], (size_t)argv[1], (int)argv[2], (int)argv[3], 65 | (int)argv[4], (__off_t)argv[5]); 66 | break; 67 | 68 | case MUNMAP_ID: ret[0] = munmap((void *)argv[0], (size_t)argv[1]); break; 69 | 70 | case MPROTECT_ID: 71 | ret[0] = mprotect((void *)argv[0], (size_t)argv[1], (int)argv[2]); 72 | break; 73 | 74 | default: break; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | MEMORY { 4 | ram (wxa!ri) : ORIGIN = 0x0000000080000000, LENGTH = 16M 5 | ramv (wxa!ri) : ORIGIN = 0xffffffe000000000, LENGTH = 4096M 6 | } 7 | PHDRS { 8 | text PT_LOAD; 9 | rodata PT_LOAD; 10 | data PT_LOAD; 11 | bss PT_LOAD; 12 | } 13 | SECTIONS { 14 | . = 0xffffffe000000000; 15 | .text : { 16 | PROVIDE(text_start = .); 17 | *(.text.init) 18 | *(.text.entry) 19 | *(.text .text.*) 20 | PROVIDE(text_end = .); 21 | } >ramv AT>ram :text 22 | .rodata : ALIGN(0x1000) { 23 | PROVIDE(rodata_start = .); 24 | . = ALIGN(16); 25 | *(.srodata .srodata.*) 26 | . = ALIGN(16); 27 | *(.rodata .rodata.*) 28 | PROVIDE(rodata_end = .); 29 | } >ramv AT>ram :rodata 30 | .data : ALIGN(0x1000) { 31 | PROVIDE(data_start = .); 32 | . = ALIGN(16); 33 | *(.sdata .sdata.*) 34 | . = ALIGN(16); 35 | *(.data .data.*) 36 | PROVIDE(data_end = .); 37 | } >ramv AT>ram :data 38 | .bss : ALIGN(0x1000) { 39 | PROVIDE(bss_start = .); 40 | . = ALIGN(16); 41 | *(.sbss .sbss.*) 42 | . = ALIGN(16); 43 | *(.bss .bss.*) 44 | PROVIDE(bss_end = .); 45 | } >ramv AT>ram :bss 46 | 47 | . = ALIGN(0x1000); 48 | . += 0x1000; 49 | init_stack_top = .; 50 | . += 0x1000; 51 | stack_top = .; 52 | _end = .; 53 | 54 | physical_base = 0x80000000; 55 | virtual_mask = 0xffffff8000000000; 56 | virtual_base = 0xffffffe000000000; 57 | phy2vir_diff = 0xffffffdf80000000; 58 | 59 | kernel_rt_pg_addr = _end; 60 | 61 | mtime_addr = 0x200bff8; 62 | mtimecmp_addr = 0x2004000; 63 | time_sep_init = 5000000; 64 | time_sep = 5000000; 65 | 66 | mcause_i_MTimer = 7; 67 | 68 | mcasue_e_inst = 2; 69 | mcause_e_ldFault = 5; 70 | mcause_e_ecallS = 9; 71 | mcause_e_loadPF = 13; 72 | 73 | scause_i_STimer = 5; 74 | 75 | scause_e_ecallU = 8; 76 | scause_e_ecallS = 9; 77 | scause_e_instPF = 12; 78 | scause_e_loadPF = 13; 79 | scause_e_storePF = 15; 80 | 81 | medeleg_bit = 0xB100; 82 | 83 | USER_PHY_ENTRY = 0x84000000; 84 | } 85 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/vmlinux.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( _start ) 3 | MEMORY { 4 | ram (wxa!ri) : ORIGIN = 0x0000000080000000, LENGTH = 16M 5 | ramv (wxa!ri) : ORIGIN = 0xffffffe000000000, LENGTH = 4096M 6 | } 7 | PHDRS { 8 | text PT_LOAD; 9 | rodata PT_LOAD; 10 | data PT_LOAD; 11 | bss PT_LOAD; 12 | } 13 | SECTIONS { 14 | . = 0xffffffe000000000; 15 | .text : { 16 | PROVIDE(text_start = .); 17 | *(.text.init) 18 | *(.text.entry) 19 | *(.text .text.*) 20 | PROVIDE(text_end = .); 21 | } >ramv AT>ram :text 22 | .rodata : ALIGN(0x1000) { 23 | PROVIDE(rodata_start = .); 24 | . = ALIGN(16); 25 | *(.srodata .srodata.*) 26 | . = ALIGN(16); 27 | *(.rodata .rodata.*) 28 | PROVIDE(rodata_end = .); 29 | } >ramv AT>ram :rodata 30 | .data : ALIGN(0x1000) { 31 | PROVIDE(data_start = .); 32 | . = ALIGN(16); 33 | *(.sdata .sdata.*) 34 | . = ALIGN(16); 35 | *(.data .data.*) 36 | PROVIDE(data_end = .); 37 | } >ramv AT>ram :data 38 | .bss : ALIGN(0x1000) { 39 | PROVIDE(bss_start = .); 40 | . = ALIGN(16); 41 | *(.sbss .sbss.*) 42 | . = ALIGN(16); 43 | *(.bss .bss.*) 44 | PROVIDE(bss_end = .); 45 | } >ramv AT>ram :bss 46 | 47 | . = ALIGN(0x1000); 48 | . += 0x1000; 49 | init_stack_top = .; 50 | . += 0x1000; 51 | stack_top = .; 52 | _end = .; 53 | 54 | physical_base = 0x80000000; 55 | virtual_mask = 0xffffff8000000000; 56 | virtual_base = 0xffffffe000000000; 57 | phy2vir_diff = 0xffffffdf80000000; 58 | 59 | kernel_rt_pg_addr = _end; 60 | kernel_rt_pg_addr = ALIGN(0x20000); 61 | 62 | mtime_addr = 0x200bff8; 63 | mtimecmp_addr = 0x2004000; 64 | time_sep_init = 5000000; 65 | time_sep = 5000000; 66 | 67 | mcause_i_MTimer = 7; 68 | 69 | mcasue_e_inst = 2; 70 | mcause_e_ldFault = 5; 71 | mcause_e_ecallS = 9; 72 | mcause_e_loadPF = 13; 73 | 74 | scause_i_STimer = 5; 75 | 76 | scause_e_ecallU = 8; 77 | scause_e_ecallS = 9; 78 | scause_e_instPF = 12; 79 | scause_e_loadPF = 13; 80 | scause_e_storePF = 15; 81 | 82 | medeleg_bit = 0xB100; 83 | 84 | USER_PHY_ENTRY = 0x84000000; 85 | } 86 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/fault.c: -------------------------------------------------------------------------------- 1 | #include "mm.h" 2 | #include "sched.h" 3 | #include "slub.h" 4 | #include "stdio.h" 5 | #include "vm.h" 6 | 7 | #define CAUSE_FETCH_PAGE_FAULT 12 8 | #define CAUSE_LOAD_PAGE_FAULT 13 9 | #define CAUSE_STORE_PAGE_FAULT 15 10 | 11 | void do_page_fault(void) { 12 | uint64 bad_addr; 13 | asm("csrr t0, stval"); 14 | asm("sd t0, %0" : : "m"(bad_addr)); 15 | 16 | printf("[S] Bad Addr: 0x%lx\n", bad_addr); 17 | 18 | struct vm_area_struct *vm_area_ptr = current->mm->vm_area_list; 19 | for (; vm_area_ptr; vm_area_ptr = vm_area_ptr->vm_next) { 20 | if (vm_area_ptr->vm_start <= bad_addr && bad_addr < vm_area_ptr->vm_end) 21 | break; 22 | } 23 | if (!vm_area_ptr) { // Not Found 24 | panic( 25 | "Invalid vm area in page fault - no vm area found for bad_addr=0x%lx", bad_addr); 26 | return; 27 | } 28 | 29 | uint64 scause; 30 | asm("csrr t0, scause"); 31 | asm("sd t0, %0" : : "m"(scause)); 32 | 33 | _Bool prot_match; 34 | int prot = PROT_U; 35 | switch (scause) { 36 | case CAUSE_FETCH_PAGE_FAULT: 37 | prot_match = (vm_area_ptr->vm_page_prot.pgprot | PERM_X); 38 | break; 39 | case CAUSE_LOAD_PAGE_FAULT: 40 | prot_match = (vm_area_ptr->vm_page_prot.pgprot | PERM_R); 41 | break; 42 | case CAUSE_STORE_PAGE_FAULT: 43 | prot_match = (vm_area_ptr->vm_page_prot.pgprot | PERM_W); 44 | break; 45 | default: prot_match = 0; break; 46 | } 47 | if (!prot_match) { 48 | panic("Invalid vm area in page fault - prot unmatch."); 49 | return; 50 | } 51 | uint64 pa; 52 | 53 | if (bad_addr < USER_MAPPING_SIZE) { // User Prog 54 | pa = USER_PHY_ENTRY + PAGE_FLOOR(bad_addr) * PAGE_SIZE; 55 | prot |= PERM_R | PERM_W | PERM_X; 56 | } else if (bad_addr >= USER_STACK_TOP - USER_MAPPING_SIZE) { // User Stack 57 | // pa = USER_PHY_ENTRY + USER_MAPPING_SIZE + PAGE_FLOOR(bad_addr) * PAGE_SIZE - 58 | // (USER_STACK_TOP - USER_MAPPING_SIZE); 59 | pa = (uint64)VA2PA(kmalloc(PAGE_SIZE)); 60 | prot |= PERM_R | PERM_W; 61 | } else // Other 62 | pa = (uint64)VA2PA(kmalloc(PAGE_SIZE)); 63 | 64 | create_mapping( 65 | current->mm->rtpg_addr, PAGE_FLOOR(bad_addr) * PAGE_SIZE, pa, PAGE_SIZE, prot); 66 | 67 | printf("[S] mapped PA: 0x%x to VA: 0x%lx with size=%d, prot=0x%x\n", pa, 68 | PAGE_FLOOR(bad_addr) * PAGE_SIZE, PAGE_SIZE, prot); 69 | } -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab5 2 | # ln -s ~/lab5/.gdbinit ~/.gdbinit 3 | # sed -i '$aalias md=make\\ debug' ~/.bashrc 4 | # sed -i '$aalias gdb=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb' ~/.bashrc 5 | # sed -i '$aalias gv=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb\\ vmlinux' ~/.bashrc 6 | # sed -i '$aalias readelf=/opt/riscv/bin/riscv64-unknown-linux-gnu-readelf' ~/.bashrc 7 | # sed -i '$aalias objdump=/opt/riscv/bin/riscv64-unknown-linux-gnu-objdump' ~/.bashrc 8 | # /opt/riscv/bin/riscv64-unknown-linux-gnu-readelf 9 | export TOP=$(shell pwd) 10 | export RISCV=/opt/riscv 11 | export PATH:=${PATH}:${RISCV}/bin 12 | 13 | export 14 | CROSS_=riscv64-unknown-elf- 15 | AR=${CROSS_}ar 16 | CC=${CROSS_}gcc 17 | LD=${CROSS_}ld 18 | OBJCOPY=${CROSS_}objcopy 19 | OBJDUMP=${CROSS_}objdump 20 | READELF=${CROSS_}readelf 21 | 22 | ISA ?= rv64imafd 23 | ABI ?= lp64 24 | 25 | INCLUDE = -I ${TOP}/include/ -I ${TOP}/arch/riscv/include/ 26 | CF = -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections -g 27 | # CFLAG = ${CF} ${INCLUDE} -D SJF 28 | CFLAG = ${CF} ${INCLUDE} -D PRIORITY 29 | 30 | .PHONY: all user kernel dasm run debug clean 31 | 32 | 33 | all: user kernel dasm 34 | 35 | 36 | user: 37 | @make -C ${TOP}/user/ 38 | @echo "\e[35mBuild User Program Successfully\e[0m" 39 | 40 | 41 | kernel: 42 | @make -C ${TOP}/lib/ 43 | @make -C ${TOP}/init/ 44 | @make -C ${TOP}/arch/riscv/kernel/ 45 | @make -C ${TOP}/arch/riscv/ 46 | @echo "\e[35mBuild Kernel Successfully\e[0m" 47 | 48 | 49 | dasm: ${TOP}/misc/dasm.S ${TOP}/misc/vmlinux_section.txt ${TOP}/misc/hello_dasm.S ${TOP}/misc/hello_section.txt 50 | @echo "\e[35mDisassemble Successfully\e[0m" 51 | ${TOP}/misc/dasm.S: ${TOP}/vmlinux 52 | ${OBJDUMP} -S ${TOP}/vmlinux > ${TOP}/misc/dasm.S 53 | ${TOP}/misc/vmlinux_section.txt: ${TOP}/vmlinux 54 | ${READELF} -S ${TOP}/vmlinux > ${TOP}/misc/vmlinux_section.txt 55 | ${TOP}/misc/hello_dasm.S: ${TOP}/user/hello.elf 56 | ${OBJDUMP} -S ${TOP}/user/hello.elf > ${TOP}/misc/hello_dasm.S 57 | ${TOP}/misc/hello_section.txt: ${TOP}/user/hello.elf 58 | ${READELF} -S ${TOP}/user/hello.elf > ${TOP}/misc/hello_section.txt 59 | 60 | 61 | run: user kernel dasm 62 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -initrd ./user/hello.bin 63 | @echo "\e[32mRun Successfully\e[0m" 64 | 65 | 66 | debug: user kernel dasm 67 | @echo "\e[32mStart Debugging\e[0m" 68 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -initrd ./user/hello.bin -S -s 69 | @echo "\e[32mEnd Debugging\e[0m" 70 | 71 | 72 | clean: 73 | @rm -f ${TOP}/vmlinux ${TOP}/System.map ${TOP}/a.out 74 | @make -C ${TOP}/arch/riscv/ clean 75 | @make -C ${TOP}/arch/riscv/kernel/ clean 76 | @make -C ${TOP}/init/ clean 77 | @make -C ${TOP}/lib/ clean 78 | @make -C ${TOP}/user/ clean 79 | @echo "\e[36mClean Successfully\e[0m" 80 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | 3 | .global _start 4 | _start: 5 | # turn off MMU 6 | csrw satp, zero 7 | 8 | # init .bss 9 | la t0, .bss # pointer 10 | la t1, _end # end 11 | bss_init_loop: 12 | sb zero, 0(t0) 13 | addi t0, t0, 1 14 | bne t0, t1, bss_init_loop 15 | 16 | # set mtimecmp to mtime+time_sep 17 | la t0, mtime_addr # RV64, t0 is of 64 bit 18 | ld t1, 0(t0) # mtime->t1 19 | la t0, time_sep_init 20 | add t1, t1, t0 21 | la t0, mtimecmp_addr 22 | sd t1, 0(t0) 23 | 24 | # set time int delegation 25 | li t1, 0x20 # mi[e|p][5]=sti[e|p] 26 | csrs mideleg, t1 27 | 28 | # set delegation of instruction/load/store page fault 29 | la t1, medeleg_bit 30 | csrs medeleg, t1 # just set is ok 31 | 32 | # set mstatus.mpie 33 | li t1, 0x80 # mstatus[7] 34 | csrs mstatus, t1 35 | 36 | # set mstatus.mie, mie.mtie, sstatus.sie, sie.stie 37 | li t1, 0x8 # mstatus[3] 38 | csrs mstatus, t1 39 | li t1, 0x80 # mie[7] 40 | csrs mie, t1 41 | li t1, 0x2 # sstatus[1] 42 | csrs sstatus, t1 43 | li t1, 0x20 # sie[5] 44 | csrs sie, t1 45 | 46 | # set mtvec(M mode) 47 | la t1, trap_m # mode = directed 48 | csrw mtvec, t1 49 | 50 | # set mscratch to stack_top in physical space 51 | la t1, stack_top 52 | csrw mscratch, t1 53 | 54 | # switch from M to S 55 | li t1, 0x1000 # MPP[1] = 0 56 | csrc mstatus, t1 57 | li t1, 0x800 # MPP[0] = 1 58 | csrs mstatus, t1 59 | 60 | la t1, S_Mode 61 | csrw mepc, t1 62 | mret 63 | 64 | S_Mode: 65 | # set stvec(physical) 66 | la t1, trap_s # mode = directed 67 | csrw stvec, t1 68 | 69 | # set sp for `paging_init()` in Physical Space !!!!! 70 | la sp, init_stack_top 71 | 72 | # init page mapping **using physical address** 73 | call paging_init 74 | 75 | # set satp to turn on MMU 76 | ori t0, zero, 8 # mode=satp[63:60] = 8 77 | sll t0, t0, 16 78 | ori t0, t0, 0 # ASID=satp[59:44] = 0 79 | sll t0, t0, 44 80 | la t1, rt_pg_addr 81 | srl t1, t1, 12 82 | or t0, t0, t1 # PPN=satp[43:0] = 0x80000000 >> 12 = 0x80000, in unit 4KB(>>12) 83 | csrw satp, t0 84 | 85 | # refresh related cache 86 | sfence.vma 87 | 88 | # load phy2vir_diff to t2 89 | li t2, 0xffffffdf80000000 90 | 91 | # set stvec(virtual) 92 | la t1, trap_s # mode = directed 93 | add t1, t1, t2 # convert to virtual 94 | csrw stvec, t1 95 | 96 | # set sp to init_stack_top in virtual space 97 | la sp, init_stack_top 98 | add sp, sp, t2 # convert to virtual 99 | 100 | # jump to start_kernel in virtual space 101 | la t1, start_kernel 102 | add t1, t1, t2 # convert to virtual 103 | jr t1 104 | 105 | 106 | .global _end 107 | _end: 108 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile_lab6 2 | # ln -s ~/lab6/.gdbinit ~/.gdbinit 3 | # sed -i '$aalias md=make\\ debug' ~/.bashrc 4 | # sed -i '$aalias gdb=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb' ~/.bashrc 5 | # sed -i '$aalias gv=/opt/riscv/bin/riscv64-unknown-linux-gnu-gdb\\ vmlinux' ~/.bashrc 6 | # sed -i '$aalias readelf=/opt/riscv/bin/riscv64-unknown-linux-gnu-readelf' ~/.bashrc 7 | # sed -i '$aalias objdump=/opt/riscv/bin/riscv64-unknown-linux-gnu-objdump' ~/.bashrc 8 | # /opt/riscv/bin/riscv64-unknown-linux-gnu-readelf 9 | export TOP=$(shell pwd) 10 | export RISCV=/opt/riscv 11 | export PATH:=${PATH}:${RISCV}/bin 12 | 13 | export 14 | CROSS_=riscv64-unknown-elf- 15 | AR=${CROSS_}ar 16 | CC=${CROSS_}gcc 17 | LD=${CROSS_}ld 18 | OBJCOPY=${CROSS_}objcopy 19 | OBJDUMP=${CROSS_}objdump 20 | READELF=${CROSS_}readelf 21 | 22 | ISA ?= rv64imafd 23 | ABI ?= lp64 24 | 25 | INCLUDE = -I ${TOP}/include/ -I ${TOP}/arch/riscv/include/ 26 | CF = -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections -g -w 27 | # CFLAG = ${CF} ${INCLUDE} -D SJF 28 | CFLAG = ${CF} ${INCLUDE} -D PRIORITY 29 | 30 | .PHONY: all user kernel dasm run debug clean 31 | 32 | 33 | all: user kernel dasm 34 | 35 | 36 | user: 37 | @make -C ${TOP}/user/ 38 | @echo "\e[35mBuild User Program Successfully\e[0m" 39 | 40 | 41 | kernel: 42 | @make -C ${TOP}/init/ 43 | @make -C ${TOP}/driver/ 44 | @make -C ${TOP}/lib/ 45 | @make -C ${TOP}/arch/riscv/kernel/ 46 | @make -C ${TOP}/arch/riscv/ 47 | @echo "\e[35mBuild Kernel Successfully\e[0m" 48 | 49 | 50 | dasm: ${TOP}/misc/dasm.S ${TOP}/misc/vmlinux_section.txt ${TOP}/misc/hello_dasm.S ${TOP}/misc/hello_section.txt 51 | @echo "\e[35mDisassemble Successfully\e[0m" 52 | ${TOP}/misc/dasm.S: ${TOP}/vmlinux 53 | ${OBJDUMP} -S ${TOP}/vmlinux > ${TOP}/misc/vmlinux_dasm.S 54 | ${TOP}/misc/vmlinux_section.txt: ${TOP}/vmlinux 55 | ${READELF} -S ${TOP}/vmlinux > ${TOP}/misc/vmlinux_section.txt 56 | ${TOP}/misc/hello_dasm.S: ${TOP}/user/hello.elf 57 | ${OBJDUMP} -S ${TOP}/user/hello.elf > ${TOP}/misc/hello_dasm.S 58 | ${TOP}/misc/hello_section.txt: ${TOP}/user/hello.elf 59 | ${READELF} -S ${TOP}/user/hello.elf > ${TOP}/misc/hello_section.txt 60 | 61 | 62 | run: user kernel dasm 63 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -initrd ./user/hello.bin 64 | @echo "\e[32mRun Successfully\e[0m" 65 | 66 | 67 | debug: user kernel dasm 68 | @echo "\e[32mStart Debugging\e[0m" 69 | qemu-system-riscv64 -nographic -machine virt -kernel vmlinux -initrd ./user/hello.bin -S -s 70 | @echo "\e[32mEnd Debugging\e[0m" 71 | 72 | 73 | clean: 74 | @rm -f ${TOP}/vmlinux ${TOP}/System.map ${TOP}/a.out 75 | @make -C ${TOP}/arch/riscv/ clean 76 | @make -C ${TOP}/arch/riscv/kernel/ clean 77 | @make -C ${TOP}/init/ clean 78 | @make -C ${TOP}/lib/ clean 79 | @make -C ${TOP}/driver/ clean 80 | @make -C ${TOP}/user/ clean 81 | @echo "\e[36mClean Successfully\e[0m" 82 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | 3 | .global _start 4 | _start: 5 | # turn off MMU 6 | csrw satp, zero 7 | 8 | # init .bss 9 | la t0, .bss # pointer 10 | la t1, _end # end 11 | bss_init_loop: 12 | sb zero, 0(t0) 13 | addi t0, t0, 1 14 | bne t0, t1, bss_init_loop 15 | 16 | # set mtimecmp to mtime+time_sep 17 | la t0, mtime_addr # RV64, t0 is of 64 bit 18 | ld t1, 0(t0) # mtime->t1 19 | la t0, time_sep_init 20 | add t1, t1, t0 21 | la t0, mtimecmp_addr 22 | sd t1, 0(t0) 23 | 24 | # set time int delegation 25 | li t1, 0x20 # mi[e|p][5]=sti[e|p] 26 | csrs mideleg, t1 27 | 28 | # set delegation of instruction/load/store page fault 29 | la t1, medeleg_bit 30 | csrs medeleg, t1 # just set is ok 31 | 32 | # set mstatus.mpie 33 | li t1, 0x80 # mstatus[7] 34 | csrs mstatus, t1 35 | 36 | # set mstatus.mie, mie.mtie, sstatus.sie, sie.stie 37 | li t1, 0x8 # mstatus[3] 38 | csrs mstatus, t1 39 | li t1, 0x80 # mie[7] 40 | csrs mie, t1 41 | li t1, 0x2 # sstatus[1] 42 | csrs sstatus, t1 43 | li t1, 0x20 # sie[5] 44 | csrs sie, t1 45 | 46 | # set mtvec(M mode) 47 | la t1, trap_m # mode = directed 48 | csrw mtvec, t1 49 | 50 | # set mscratch to stack_top in physical space 51 | la t1, stack_top 52 | csrw mscratch, t1 53 | 54 | # switch from M to S 55 | li t1, 0x1000 # MPP[1] = 0 56 | csrc mstatus, t1 57 | li t1, 0x800 # MPP[0] = 1 58 | csrs mstatus, t1 59 | 60 | la t1, S_Mode 61 | csrw mepc, t1 62 | mret 63 | 64 | S_Mode: 65 | # set stvec(physical) 66 | la t1, trap_s # mode = directed 67 | csrw stvec, t1 68 | 69 | # set sp for `kernel_paging_init()` in Physical Space !!!!! 70 | la sp, init_stack_top 71 | 72 | # init page mapping **using physical address** 73 | call kernel_paging_init 74 | 75 | # set satp to turn on MMU 76 | ori t0, zero, 8 # mode=satp[63:60] = 8 77 | sll t0, t0, 16 78 | ori t0, t0, 0 # ASID=satp[59:44] = 0 79 | sll t0, t0, 44 80 | la t1, kernel_rt_pg_addr 81 | srl t1, t1, 12 82 | or t0, t0, t1 # PPN=satp[43:0] = 0x80000000 >> 12 = 0x80000, in unit 4KB(>>12) 83 | csrw satp, t0 84 | 85 | # refresh related cache 86 | sfence.vma 87 | 88 | # load phy2vir_diff to t2 89 | li t2, 0xffffffdf80000000 90 | 91 | # set stvec(virtual) 92 | la t1, trap_s # mode = directed 93 | add t1, t1, t2 # convert to virtual 94 | csrw stvec, t1 95 | 96 | # set sp to init_stack_top in virtual space 97 | la sp, init_stack_top 98 | add sp, sp, t2 # convert to virtual 99 | 100 | # enable sstatus.sum 101 | li t0, 0x40000 # sstatus[18]=SUM 102 | csrs sstatus, t0 103 | 104 | # jump to start_kernel in virtual space 105 | la t1, start_kernel 106 | add t1, t1, t2 # convert to virtual 107 | jr t1 108 | 109 | 110 | .global _end 111 | _end: 112 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/head.S: -------------------------------------------------------------------------------- 1 | .section .text.init 2 | 3 | .global _start 4 | _start: 5 | # turn off MMU 6 | csrw satp, zero 7 | 8 | # init .bss 9 | la t0, .bss # pointer 10 | la t1, _end # end 11 | bss_init_loop: 12 | sb zero, 0(t0) 13 | addi t0, t0, 1 14 | bne t0, t1, bss_init_loop 15 | 16 | # set mtimecmp to mtime+time_sep 17 | la t0, mtime_addr # RV64, t0 is of 64 bit 18 | ld t1, 0(t0) # mtime->t1 19 | la t0, time_sep_init 20 | add t1, t1, t0 21 | la t0, mtimecmp_addr 22 | sd t1, 0(t0) 23 | 24 | # set time int delegation 25 | li t1, 0x20 # mi[e|p][5]=sti[e|p] 26 | csrs mideleg, t1 27 | 28 | # set delegation of instruction/load/store page fault 29 | la t1, medeleg_bit 30 | csrs medeleg, t1 # just set is ok 31 | 32 | # set mstatus.mpie 33 | li t1, 0x80 # mstatus[7] 34 | csrs mstatus, t1 35 | 36 | # set mstatus.mie, mie.mtie, sstatus.sie, sie.stie 37 | li t1, 0x8 # mstatus[3] 38 | csrs mstatus, t1 39 | li t1, 0x80 # mie[7] 40 | csrs mie, t1 41 | li t1, 0x2 # sstatus[1] 42 | csrs sstatus, t1 43 | li t1, 0x20 # sie[5] 44 | csrs sie, t1 45 | 46 | # set mtvec(M mode) 47 | la t1, trap_m # mode = directed 48 | csrw mtvec, t1 49 | 50 | # set mscratch to stack_top in physical space 51 | la t1, stack_top 52 | csrw mscratch, t1 53 | 54 | # switch from M to S 55 | li t1, 0x1000 # MPP[1] = 0 56 | csrc mstatus, t1 57 | li t1, 0x800 # MPP[0] = 1 58 | csrs mstatus, t1 59 | 60 | la t1, S_Mode 61 | csrw mepc, t1 62 | mret 63 | 64 | S_Mode: 65 | # set stvec(physical) 66 | la t1, trap_s # mode = directed 67 | csrw stvec, t1 68 | 69 | # set sp for `kernel_paging_init()` in Physical Space !!!!! 70 | la sp, init_stack_top 71 | 72 | # init page mapping **using physical address** 73 | call kernel_paging_init 74 | 75 | # set satp to turn on MMU 76 | ori t0, zero, 8 # mode=satp[63:60] = 8 77 | sll t0, t0, 16 78 | ori t0, t0, 0 # ASID=satp[59:44] = 0 79 | sll t0, t0, 44 80 | la t1, kernel_rt_pg_addr 81 | srl t1, t1, 12 82 | or t0, t0, t1 # PPN=satp[43:0] = 0x80000000 >> 12 = 0x80000, in unit 4KB(>>12) 83 | csrw satp, t0 84 | 85 | # refresh related cache 86 | sfence.vma 87 | 88 | # load phy2vir_diff to t2 89 | li t2, 0xffffffdf80000000 90 | 91 | # set stvec(virtual) 92 | la t1, trap_s # mode = directed 93 | add t1, t1, t2 # convert to virtual 94 | csrw stvec, t1 95 | 96 | # set sp to init_stack_top in virtual space 97 | la sp, init_stack_top 98 | add sp, sp, t2 # convert to virtual 99 | 100 | # enable sstatus.sum 101 | li t0, 0x40000 # sstatus[18]=SUM 102 | csrs sstatus, t0 103 | 104 | # jump to start_kernel in virtual space 105 | la t1, start_kernel 106 | add t1, t1, t2 # convert to virtual 107 | jr t1 108 | 109 | 110 | .global _end 111 | _end: 112 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/buddy.c: -------------------------------------------------------------------------------- 1 | #include "buddy.h" 2 | #include "slub.h" 3 | #include "stdio.h" 4 | #include "vm.h" 5 | 6 | struct buddy buddy; 7 | 8 | /* 9 | 0 +---> 1 +---> 3 +---> 7 10 | | | | 11 | | | +---> 8 12 | | | 13 | | +---> 4 +---> 9 14 | | | 15 | | +---> 10 16 | | 17 | +---> 2 +---> 5 +---> 11 18 | | | 19 | | +---> 12 20 | | 21 | +---> 6 +---> 13 22 | | 23 | +---> 14 24 | */ 25 | 26 | #define BIN_TREE_UPCHILD(__X) ((__X)*2 + 1) 27 | #define BIN_TREE_DOWNCHILD(__X) ((__X)*2 + 2) 28 | #define BIN_TREE_PARENT(__X) (((__X)-1) / 2) 29 | 30 | /** 31 | * @brief initialize buddy system 32 | */ 33 | void init_buddy_system(void) { 34 | buddy.pgnum = PAGE_FLOOR(BUDDY_SPACE_SIZE); 35 | 36 | int i = 0; 37 | for (uint64 layer_size = buddy.pgnum; layer_size; layer_size /= 2) 38 | for (uint64 node_count = 0; node_count < buddy.pgnum / layer_size; node_count++) 39 | buddy.bitmap[i++] = layer_size; 40 | 41 | alloc_pages(PAGE_FLOOR(KERNEL_PROG_SIZE)); 42 | } 43 | 44 | /** 45 | * @brief allocate space of n pages from low to high 46 | * 47 | * @param npages allocated space size in page 48 | * @return void* VA of the space head (in byte) 49 | */ 50 | void *alloc_pages(int npages) { 51 | if (buddy.bitmap[0] < npages) { // No enough space 52 | panic("Insufficient space in buddy system."); 53 | return NULL; 54 | } 55 | 56 | int bm_loc = 0; 57 | uint64 alloc_size = buddy.pgnum; 58 | uint64 ret_addr_pg = 0; // Starting from 0x80000000, in unit page 59 | 60 | while (1) { 61 | // alloc_size check make sure BIN_TREE_CHILD will not overflow access 62 | if (alloc_size > 1 && buddy.bitmap[BIN_TREE_UPCHILD(bm_loc)] >= npages) 63 | bm_loc = BIN_TREE_UPCHILD(bm_loc); 64 | else if (alloc_size > 1 && buddy.bitmap[BIN_TREE_DOWNCHILD(bm_loc)] >= npages) { 65 | bm_loc = BIN_TREE_DOWNCHILD(bm_loc); 66 | ret_addr_pg += alloc_size / 2; 67 | } else 68 | break; 69 | alloc_size /= 2; 70 | } 71 | 72 | for (int i = bm_loc;; i = BIN_TREE_PARENT(i)) { // sub alloc size from the parent tree 73 | buddy.bitmap[i] -= alloc_size; 74 | if (!i) 75 | break; 76 | } 77 | return (void *)PA2VA(BUDDY_START_ADDR + ret_addr_pg * PAGE_SIZE); 78 | } 79 | 80 | /** 81 | * @brief release the space starting from addr 82 | * 83 | * @param addr sapce head of the space to be freed (in byte) 84 | */ 85 | void free_pages(void *addr) { 86 | addr = VA2PA(addr); 87 | 88 | if (addr < 0 || addr >= buddy.pgnum) { 89 | panic("Invalid free address."); 90 | return; 91 | } 92 | 93 | uint64 alloc_size = 1; 94 | _Bool size_not_found = 1; 95 | 96 | for (int bm_loc = buddy.pgnum - 1 + PAGE_FLOOR(addr - BUDDY_START_ADDR);; 97 | bm_loc = BIN_TREE_PARENT(bm_loc)) { 98 | if (buddy.bitmap[bm_loc] && size_not_found) { 99 | alloc_size <<= 1; 100 | } else { // Found alloc page 101 | size_not_found = 0; 102 | buddy.bitmap[bm_loc] += alloc_size; 103 | if (!bm_loc) // Stop at root 104 | return; 105 | } 106 | } 107 | } 108 | 109 | /* 110 | 6 +---> 4 +---> 2 +---> 1 111 | | | | 112 | | | +---> 1 113 | | | 114 | | +---> 2 +---> 1 115 | | | 116 | | +---> 1 117 | | 118 | +---> 2 +---> 0 +---> 1 119 | | | 120 | | +---> 1 121 | | 122 | +---> 2 +---> 1 123 | | 124 | +---> 1 125 | */ -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/include/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHED_H 2 | #define _SCHED_H 3 | 4 | #define TASK_BASE 0x80010000 5 | #define TASK_SIZE (4096) 6 | #define THREAD_OFFSET (5 * 0x08) 7 | 8 | #ifndef __ASSEMBLER__ 9 | 10 | /* task的最大数量 */ 11 | #define NR_TASKS 64 12 | 13 | #define FIRST_TASK (task[0]) 14 | #define LAST_TASK (task[NR_TASKS - 1]) 15 | 16 | /* 定义task的状态,Lab3中task只需要一种状态。*/ 17 | #define TASK_RUNNING 0 18 | #define TASK_INTERRUPTIBLE 1 19 | #define TASK_UNINTERRUPTIBLE 2 20 | #define TASK_ZOMBIE 3 21 | #define TASK_STOPPED 4 22 | 23 | // Ensure Mutual Exclusion 24 | #ifdef SJF 25 | #define PREEMPT_ENABLE 0 26 | #else 27 | #ifdef PRIORITY 28 | #define PREEMPT_ENABLE 1 29 | #endif 30 | #endif 31 | 32 | #define PREEMPT_DISABLE !PREEMPT_ENABLE 33 | 34 | /* Lab3中进程的数量以及每个进程初始的时间片 */ 35 | #define LAB_TEST_NUM 4 36 | #define LAB_TEST_COUNTER 5 37 | 38 | /* 当前进程 */ 39 | extern struct task_struct *current; 40 | 41 | /* 进程指针数组 */ 42 | extern struct task_struct *task[NR_TASKS]; 43 | 44 | /* 进程状态段数据结构 */ 45 | struct thread_struct { 46 | unsigned long long ra; 47 | unsigned long long sp; 48 | unsigned long long s0; 49 | unsigned long long s1; 50 | unsigned long long s2; 51 | unsigned long long s3; 52 | unsigned long long s4; 53 | unsigned long long s5; 54 | unsigned long long s6; 55 | unsigned long long s7; 56 | unsigned long long s8; 57 | unsigned long long s9; 58 | unsigned long long s10; 59 | unsigned long long s11; 60 | }; 61 | 62 | /* 进程数据结构 */ 63 | struct task_struct { 64 | long state; // 进程状态 Lab3中进程初始化时置为TASK_RUNNING 65 | long counter; // 运行剩余时间 66 | long priority; // 运行优先级 1最高 5最低 67 | long blocked; 68 | long pid; // 进程标识符 69 | // Above Size Cost: 40 bytes 70 | 71 | struct thread_struct thread; // 该进程状态段 72 | }; 73 | 74 | /* 进程初始化 创建四个dead_loop进程 */ 75 | void task_init(void); 76 | 77 | /* 在时钟中断处理中被调用 */ 78 | void do_timer(void); 79 | 80 | /* 调度程序 */ 81 | void schedule(void); 82 | 83 | /* 切换当前任务current到下一个任务next */ 84 | void switch_to(struct task_struct *next); 85 | void switch_to_asm(); 86 | 87 | /* 死循环 */ 88 | void dead_loop(void); 89 | 90 | #define CONTEXT_SAVE(pTask) \ 91 | { \ 92 | asm("sd ra, %0" : : "m"(pTask->thread.ra)); \ 93 | asm("sd sp, %0" : : "m"(pTask->thread.sp)); \ 94 | asm("sd s0, %0" : : "m"(pTask->thread.s0)); \ 95 | asm("sd s1, %0" : : "m"(pTask->thread.s1)); \ 96 | asm("sd s2, %0" : : "m"(pTask->thread.s2)); \ 97 | asm("sd s3, %0" : : "m"(pTask->thread.s3)); \ 98 | asm("sd s4, %0" : : "m"(pTask->thread.s4)); \ 99 | asm("sd s5, %0" : : "m"(pTask->thread.s5)); \ 100 | asm("sd s6, %0" : : "m"(pTask->thread.s6)); \ 101 | asm("sd s7, %0" : : "m"(pTask->thread.s7)); \ 102 | asm("sd s8, %0" : : "m"(pTask->thread.s8)); \ 103 | asm("sd s9, %0" : : "m"(pTask->thread.s9)); \ 104 | asm("sd s10, %0" : : "m"(pTask->thread.s10)); \ 105 | asm("sd s11, %0" : : "m"(pTask->thread.s11)); \ 106 | } 107 | 108 | #define CONTEXT_LOAD(pTask) \ 109 | { \ 110 | asm("ld ra, %0" : : "m"(pTask->thread.ra)); \ 111 | asm("ld sp, %0" : : "m"(pTask->thread.sp)); \ 112 | asm("ld s0, %0" : : "m"(pTask->thread.s0)); \ 113 | asm("ld s1, %0" : : "m"(pTask->thread.s1)); \ 114 | asm("ld s2, %0" : : "m"(pTask->thread.s2)); \ 115 | asm("ld s3, %0" : : "m"(pTask->thread.s3)); \ 116 | asm("ld s4, %0" : : "m"(pTask->thread.s4)); \ 117 | asm("ld s5, %0" : : "m"(pTask->thread.s5)); \ 118 | asm("ld s6, %0" : : "m"(pTask->thread.s6)); \ 119 | asm("ld s7, %0" : : "m"(pTask->thread.s7)); \ 120 | asm("ld s8, %0" : : "m"(pTask->thread.s8)); \ 121 | asm("ld s9, %0" : : "m"(pTask->thread.s9)); \ 122 | asm("ld s10, %0" : : "m"(pTask->thread.s10)); \ 123 | asm("ld s11, %0" : : "m"(pTask->thread.s11)); \ 124 | } 125 | 126 | #endif 127 | 128 | #endif -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHED_H 2 | #define _SCHED_H 3 | 4 | #include "mm.h" 5 | #include "types.h" 6 | 7 | #define TASK_BASE 0xffffffe000ff0000 8 | #define TASK_SIZE 0x1000 9 | // #define THREAD_OFFSET (5 * 0x08) 10 | 11 | #ifndef __ASSEMBLER__ 12 | 13 | /* task的最大数量 */ 14 | #define NR_TASKS 64 15 | 16 | #define FIRST_TASK (task[0]) 17 | #define LAST_TASK (task[NR_TASKS - 1]) 18 | 19 | /* 定义task的状态,Lab3中task只需要一种状态。*/ 20 | #define TASK_RUNNING 0 21 | #define TASK_INTERRUPTIBLE 1 22 | #define TASK_UNINTERRUPTIBLE 2 23 | #define TASK_ZOMBIE 3 24 | #define TASK_STOPPED 4 25 | 26 | // Ensure Mutual Exclusion 27 | #ifdef SJF 28 | #define PREEMPT_ENABLE 0 29 | #else 30 | #ifdef PRIORITY 31 | #define PREEMPT_ENABLE 1 32 | #else 33 | #define PREEMPT_ENABLE 1 // PRIORITY by default 34 | #endif 35 | 36 | #endif 37 | 38 | #define PREEMPT_DISABLE !PREEMPT_ENABLE 39 | 40 | /* Lab3中进程的数量以及每个进程初始的时间片 */ 41 | #define LAB_TEST_NUM 4 42 | #define LAB_TEST_COUNTER 5 43 | 44 | /* 当前进程 */ 45 | extern struct task_struct *current; 46 | 47 | /* 进程指针数组 */ 48 | extern struct task_struct *task[NR_TASKS]; 49 | 50 | /* 进程状态段数据结构 */ 51 | struct thread_struct { 52 | unsigned long long ra; 53 | unsigned long long sp; 54 | unsigned long long s0; 55 | unsigned long long s1; 56 | unsigned long long s2; 57 | unsigned long long s3; 58 | unsigned long long s4; 59 | unsigned long long s5; 60 | unsigned long long s6; 61 | unsigned long long s7; 62 | unsigned long long s8; 63 | unsigned long long s9; 64 | unsigned long long s10; 65 | unsigned long long s11; 66 | }; 67 | 68 | /* 进程数据结构 */ 69 | struct task_struct { 70 | long state; // 进程状态Lab3中进程初始化时置为TASK_RUNNING 71 | long counter; // 运行剩余时间 72 | long priority; // 运行优先级 1最高 5最低 73 | long blocked; 74 | long pid; // 进程标识符 75 | // Above Size Cost: 40 bytes 76 | 77 | // uint64 sepc; 78 | uint64 sscratch; 79 | 80 | struct mm_struct *mm; 81 | struct thread_struct thread; // 该进程状态段 82 | }; 83 | 84 | /* 进程初始化 创建四个dead_loop进程 */ 85 | void task_init(void); 86 | 87 | /* 在时钟中断处理中被调用 */ 88 | void do_timer(void); 89 | 90 | /* 调度程序 */ 91 | void schedule(void); 92 | 93 | /* 切换当前任务current到下一个任务next */ 94 | void switch_to(struct task_struct *next); 95 | extern void __switch_to(struct thread_struct *prev_thread, struct thread_struct *next_thread); 96 | 97 | #define CONTEXT_SAVE(pTask) \ 98 | { \ 99 | asm("sd ra, %0" : : "m"(pTask->thread.ra)); \ 100 | asm("sd sp, %0" : : "m"(pTask->thread.sp)); \ 101 | asm("sd s0, %0" : : "m"(pTask->thread.s0)); \ 102 | asm("sd s1, %0" : : "m"(pTask->thread.s1)); \ 103 | asm("sd s2, %0" : : "m"(pTask->thread.s2)); \ 104 | asm("sd s3, %0" : : "m"(pTask->thread.s3)); \ 105 | asm("sd s4, %0" : : "m"(pTask->thread.s4)); \ 106 | asm("sd s5, %0" : : "m"(pTask->thread.s5)); \ 107 | asm("sd s6, %0" : : "m"(pTask->thread.s6)); \ 108 | asm("sd s7, %0" : : "m"(pTask->thread.s7)); \ 109 | asm("sd s8, %0" : : "m"(pTask->thread.s8)); \ 110 | asm("sd s9, %0" : : "m"(pTask->thread.s9)); \ 111 | asm("sd s10, %0" : : "m"(pTask->thread.s10)); \ 112 | asm("sd s11, %0" : : "m"(pTask->thread.s11)); \ 113 | } 114 | 115 | #define CONTEXT_LOAD(pTask) \ 116 | { \ 117 | asm("ld ra, %0" : : "m"(pTask->thread.ra)); \ 118 | asm("ld sp, %0" : : "m"(pTask->thread.sp)); \ 119 | asm("ld s0, %0" : : "m"(pTask->thread.s0)); \ 120 | asm("ld s1, %0" : : "m"(pTask->thread.s1)); \ 121 | asm("ld s2, %0" : : "m"(pTask->thread.s2)); \ 122 | asm("ld s3, %0" : : "m"(pTask->thread.s3)); \ 123 | asm("ld s4, %0" : : "m"(pTask->thread.s4)); \ 124 | asm("ld s5, %0" : : "m"(pTask->thread.s5)); \ 125 | asm("ld s6, %0" : : "m"(pTask->thread.s6)); \ 126 | asm("ld s7, %0" : : "m"(pTask->thread.s7)); \ 127 | asm("ld s8, %0" : : "m"(pTask->thread.s8)); \ 128 | asm("ld s9, %0" : : "m"(pTask->thread.s9)); \ 129 | asm("ld s10, %0" : : "m"(pTask->thread.s10)); \ 130 | asm("ld s11, %0" : : "m"(pTask->thread.s11)); \ 131 | } 132 | 133 | #endif 134 | 135 | #endif -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/lib/printf.c: -------------------------------------------------------------------------------- 1 | #include "device.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | int putchar(int ch) { 6 | // console_dev->putchar(ch); 7 | *((char *)0xffffffdf90000000) = ch; 8 | return 1; 9 | } 10 | 11 | int puts(const char *s) { 12 | while (*s) 13 | putchar(*s++); 14 | } 15 | 16 | static int vprintfmt(int (*putch)(int), const char *fmt, va_list vl) { 17 | int in_format = 0, longarg = 0; 18 | size_t pos = 0; 19 | for (; *fmt; fmt++) { 20 | if (in_format) { 21 | switch (*fmt) { 22 | case 'l': { 23 | longarg = 1; 24 | break; 25 | } 26 | 27 | case 'x': { 28 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 29 | 30 | int hexdigits = 2 * (longarg ? sizeof(long) : sizeof(int)) - 1; 31 | for (int halfbyte = hexdigits; halfbyte >= 0; halfbyte--) { 32 | int hex = (num >> (4 * halfbyte)) & 0xF; 33 | char hexchar = (hex < 10 ? '0' + hex : 'a' + hex - 10); 34 | putch(hexchar); 35 | pos++; 36 | } 37 | longarg = 0; 38 | in_format = 0; 39 | break; 40 | } 41 | 42 | case 'd': { 43 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 44 | if (num < 0) { 45 | num = -num; 46 | putch('-'); 47 | pos++; 48 | } 49 | int bits = 0; 50 | char decchar[25] = {'0', 0}; 51 | for (long tmp = num; tmp; bits++) { 52 | decchar[bits] = (tmp % 10) + '0'; 53 | tmp /= 10; 54 | } 55 | 56 | for (int i = bits; i >= 0; i--) { 57 | putch(decchar[i]); 58 | } 59 | pos += bits + 1; 60 | longarg = 0; 61 | in_format = 0; 62 | break; 63 | } 64 | 65 | case 'u': { 66 | unsigned long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 67 | int bits = 0; 68 | char decchar[25] = {'0', 0}; 69 | for (long tmp = num; tmp; bits++) { 70 | decchar[bits] = (tmp % 10) + '0'; 71 | tmp /= 10; 72 | } 73 | 74 | for (int i = bits; i >= 0; i--) { 75 | putch(decchar[i]); 76 | } 77 | pos += bits + 1; 78 | longarg = 0; 79 | in_format = 0; 80 | break; 81 | } 82 | 83 | case 's': { 84 | const char *str = va_arg(vl, const char *); 85 | while (*str) { 86 | putch(*str); 87 | pos++; 88 | str++; 89 | } 90 | longarg = 0; 91 | in_format = 0; 92 | break; 93 | } 94 | 95 | case 'c': { 96 | char ch = (char)va_arg(vl, int); 97 | putch(ch); 98 | pos++; 99 | longarg = 0; 100 | in_format = 0; 101 | break; 102 | } 103 | default: break; 104 | } 105 | } else if (*fmt == '%') { 106 | in_format = 1; 107 | } else { 108 | putch(*fmt); 109 | pos++; 110 | } 111 | } 112 | return pos; 113 | } 114 | 115 | int printf(const char *s, ...) { 116 | int res = 0; 117 | va_list vl; 118 | va_start(vl, s); 119 | res = vprintfmt(putchar, s, vl); 120 | va_end(vl); 121 | return res; 122 | } 123 | 124 | void panic(const char *s, ...) { 125 | printf("panic: "); 126 | 127 | va_list vl; 128 | va_start(vl, s); 129 | vprintfmt(putchar, s, vl); 130 | va_end(vl); 131 | 132 | printf("\n"); 133 | exit(0); 134 | } -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/include/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHED_H 2 | #define _SCHED_H 3 | 4 | #include "types.h" 5 | 6 | #define TASK_BASE 0xffffffe000ff0000 7 | #define TASK_SIZE 0x1000 8 | // #define THREAD_OFFSET (5 * 0x08) 9 | 10 | #ifndef __ASSEMBLER__ 11 | 12 | /* task的最大数量 */ 13 | #define NR_TASKS 64 14 | 15 | #define FIRST_TASK (task[0]) 16 | #define LAST_TASK (task[NR_TASKS - 1]) 17 | 18 | /* 定义task的状态,Lab3中task只需要一种状态。*/ 19 | #define TASK_RUNNING 0 20 | #define TASK_INTERRUPTIBLE 1 21 | #define TASK_UNINTERRUPTIBLE 2 22 | #define TASK_ZOMBIE 3 23 | #define TASK_STOPPED 4 24 | 25 | // Ensure Mutual Exclusion 26 | #ifdef SJF 27 | #define PREEMPT_ENABLE 0 28 | #else 29 | #ifdef PRIORITY 30 | #define PREEMPT_ENABLE 1 31 | #else 32 | #define PREEMPT_ENABLE 1 // PRIORITY by default 33 | #endif 34 | 35 | #endif 36 | 37 | #define PREEMPT_DISABLE !PREEMPT_ENABLE 38 | 39 | /* Lab3中进程的数量以及每个进程初始的时间片 */ 40 | #define LAB_TEST_NUM 4 41 | #define LAB_TEST_COUNTER 5 42 | 43 | /* 当前进程 */ 44 | extern struct task_struct *current; 45 | 46 | /* 进程指针数组 */ 47 | extern struct task_struct *task[NR_TASKS]; 48 | 49 | /* 进程状态段数据结构 */ 50 | struct thread_struct { 51 | unsigned long long ra; 52 | unsigned long long sp; 53 | unsigned long long s0; 54 | unsigned long long s1; 55 | unsigned long long s2; 56 | unsigned long long s3; 57 | unsigned long long s4; 58 | unsigned long long s5; 59 | unsigned long long s6; 60 | unsigned long long s7; 61 | unsigned long long s8; 62 | unsigned long long s9; 63 | unsigned long long s10; 64 | unsigned long long s11; 65 | }; 66 | 67 | struct mm_struct { 68 | uint64 *rtpg_addr; 69 | }; 70 | 71 | /* 进程数据结构 */ 72 | struct task_struct { 73 | long state; // 进程状态 Lab3中进程初始化时置为TASK_RUNNING 74 | long counter; // 运行剩余时间 75 | long priority; // 运行优先级 1最高 5最低 76 | long blocked; 77 | long pid; // 进程标识符 78 | // Above Size Cost: 40 bytes 79 | 80 | // uint64 sepc; 81 | uint64 sscratch; 82 | 83 | struct mm_struct mm; 84 | struct thread_struct thread; // 该进程状态段 85 | }; 86 | 87 | /* 进程初始化 创建四个dead_loop进程 */ 88 | void task_init(void); 89 | 90 | /* 在时钟中断处理中被调用 */ 91 | void do_timer(void); 92 | 93 | /* 调度程序 */ 94 | void schedule(void); 95 | 96 | /* 切换当前任务current到下一个任务next */ 97 | void switch_to(struct task_struct *next); 98 | extern void __switch_to(struct thread_struct *prev_thread, struct thread_struct *next_thread); 99 | 100 | #define CONTEXT_SAVE(pTask) \ 101 | { \ 102 | asm("sd ra, %0" : : "m"(pTask->thread.ra)); \ 103 | asm("sd sp, %0" : : "m"(pTask->thread.sp)); \ 104 | asm("sd s0, %0" : : "m"(pTask->thread.s0)); \ 105 | asm("sd s1, %0" : : "m"(pTask->thread.s1)); \ 106 | asm("sd s2, %0" : : "m"(pTask->thread.s2)); \ 107 | asm("sd s3, %0" : : "m"(pTask->thread.s3)); \ 108 | asm("sd s4, %0" : : "m"(pTask->thread.s4)); \ 109 | asm("sd s5, %0" : : "m"(pTask->thread.s5)); \ 110 | asm("sd s6, %0" : : "m"(pTask->thread.s6)); \ 111 | asm("sd s7, %0" : : "m"(pTask->thread.s7)); \ 112 | asm("sd s8, %0" : : "m"(pTask->thread.s8)); \ 113 | asm("sd s9, %0" : : "m"(pTask->thread.s9)); \ 114 | asm("sd s10, %0" : : "m"(pTask->thread.s10)); \ 115 | asm("sd s11, %0" : : "m"(pTask->thread.s11)); \ 116 | } 117 | 118 | #define CONTEXT_LOAD(pTask) \ 119 | { \ 120 | asm("ld ra, %0" : : "m"(pTask->thread.ra)); \ 121 | asm("ld sp, %0" : : "m"(pTask->thread.sp)); \ 122 | asm("ld s0, %0" : : "m"(pTask->thread.s0)); \ 123 | asm("ld s1, %0" : : "m"(pTask->thread.s1)); \ 124 | asm("ld s2, %0" : : "m"(pTask->thread.s2)); \ 125 | asm("ld s3, %0" : : "m"(pTask->thread.s3)); \ 126 | asm("ld s4, %0" : : "m"(pTask->thread.s4)); \ 127 | asm("ld s5, %0" : : "m"(pTask->thread.s5)); \ 128 | asm("ld s6, %0" : : "m"(pTask->thread.s6)); \ 129 | asm("ld s7, %0" : : "m"(pTask->thread.s7)); \ 130 | asm("ld s8, %0" : : "m"(pTask->thread.s8)); \ 131 | asm("ld s9, %0" : : "m"(pTask->thread.s9)); \ 132 | asm("ld s10, %0" : : "m"(pTask->thread.s10)); \ 133 | asm("ld s11, %0" : : "m"(pTask->thread.s11)); \ 134 | } 135 | 136 | #endif 137 | 138 | #endif -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/user/printf.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "syscall.h" 3 | 4 | int tail = 0; 5 | char buffer[1000] = {[0 ... 999] = 0}; 6 | 7 | static inline int putchar(int c) { 8 | buffer[tail++] = (char)c; 9 | return 0; 10 | } 11 | 12 | static int vprintfmt(int (*putch)(int), const char *fmt, va_list vl) { 13 | int in_format = 0, longarg = 0; 14 | size_t pos = 0; 15 | 16 | for (; *fmt; fmt++) { 17 | if (in_format) { 18 | switch (*fmt) { 19 | case 'l': { 20 | longarg = 1; 21 | break; 22 | } 23 | 24 | case 'x': { 25 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 26 | 27 | int hexdigits = 2 * (longarg ? sizeof(long) : sizeof(int)) - 1; 28 | for (int halfbyte = hexdigits; halfbyte >= 0; halfbyte--) { 29 | int hex = (num >> (4 * halfbyte)) & 0xF; 30 | char hexchar = (hex < 10 ? '0' + hex : 'a' + hex - 10); 31 | putch(hexchar); 32 | pos++; 33 | } 34 | longarg = 0; 35 | in_format = 0; 36 | break; 37 | } 38 | 39 | case 'd': { 40 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 41 | if (num < 0) { 42 | num = -num; 43 | putch('-'); 44 | pos++; 45 | } 46 | int bits = 0; 47 | char decchar[25] = {'0', 0}; 48 | for (long tmp = num; tmp; bits++) { 49 | decchar[bits] = (tmp % 10) + '0'; 50 | tmp /= 10; 51 | } 52 | 53 | if (bits == 0) 54 | bits++; 55 | 56 | for (int i = bits - 1; i >= 0; i--) { 57 | putch(decchar[i]); 58 | } 59 | pos += bits + 1; 60 | longarg = 0; 61 | in_format = 0; 62 | break; 63 | } 64 | 65 | case 'u': { 66 | unsigned long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 67 | int bits = 0; 68 | char decchar[25] = {'0', 0}; 69 | for (long tmp = num; tmp; bits++) { 70 | decchar[bits] = (tmp % 10) + '0'; 71 | tmp /= 10; 72 | } 73 | 74 | if (bits == 0) 75 | bits++; 76 | 77 | for (int i = bits - 1; i >= 0; i--) { 78 | putch(decchar[i]); 79 | } 80 | pos += bits - 1; 81 | longarg = 0; 82 | in_format = 0; 83 | break; 84 | } 85 | 86 | case 's': { 87 | const char *str = va_arg(vl, const char *); 88 | while (*str) { 89 | putch(*str); 90 | pos++; 91 | str++; 92 | } 93 | longarg = 0; 94 | in_format = 0; 95 | break; 96 | } 97 | 98 | case 'c': { 99 | char ch = (char)va_arg(vl, int); 100 | putch(ch); 101 | pos++; 102 | longarg = 0; 103 | in_format = 0; 104 | break; 105 | } 106 | default: break; 107 | } 108 | } else if (*fmt == '%') { 109 | in_format = 1; 110 | } else { 111 | putch(*fmt); 112 | pos++; 113 | } 114 | } 115 | 116 | long syscall_ret, fd = 1; 117 | buffer[tail++] = '\0'; 118 | asm volatile("li a7, %1\n" 119 | "mv a0, %2\n" 120 | "mv a1, %3\n" 121 | "mv a2, %4\n" 122 | "ecall\n" 123 | "mv %0, a0\n" 124 | : "+r"(syscall_ret) 125 | : "i"(SYS_WRITE), "r"(fd), "r"(&buffer), "r"(tail)); 126 | 127 | return syscall_ret; 128 | } 129 | 130 | int printf(const char *s, ...) { 131 | int res = 0; 132 | va_list vl; 133 | va_start(vl, s); 134 | tail = 0; 135 | res = vprintfmt(putchar, s, vl); 136 | va_end(vl); 137 | return res; 138 | } -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/mm.c: -------------------------------------------------------------------------------- 1 | #include "mm.h" 2 | #include "sched.h" 3 | #include "slub.h" 4 | #include "stddef.h" 5 | #include "types.h" 6 | #include "vm.h" 7 | 8 | #define LoadPTE(__pte_addr, __prot, __v) \ 9 | { \ 10 | *__pte_addr = ((uint64)(*(__pte_addr)) & 0xfffffffffffffc00) | \ 11 | ((uint64)(__prot) | (uint64)(__v)); \ 12 | } 13 | 14 | unsigned long get_unmapped_area(size_t length) { 15 | if (!current->mm->vm_area_list) // Not allocated yet 16 | return 0x0L; 17 | 18 | for (unsigned long addr = 0;; addr += PAGE_SIZE) { 19 | struct vm_area_struct *p; 20 | for (p = current->mm->vm_area_list; p->vm_next; p = p->vm_next) { 21 | if (p->vm_start < addr && addr < p->vm_end || 22 | p->vm_start < addr + length && addr + length < p->vm_end) { 23 | break; 24 | } 25 | } 26 | if (p->vm_next == NULL) { // Traverse to the last in vm_area_list with no conflict 27 | return addr; 28 | } 29 | } 30 | // panic("No enough space"); 31 | } 32 | 33 | void *do_mmap(struct mm_struct *mm, void *start, size_t length, int prot, unsigned long flags, 34 | unsigned long pgoff) { 35 | 36 | _Bool isCollision = 0; 37 | if (mm->vm_area_list) // vm_area_list not empty 38 | for (struct vm_area_struct *p = mm->vm_area_list; p->vm_next; p = p->vm_next) 39 | if (p->vm_start <= start && start < p->vm_end || 40 | p->vm_start < start + length && start + length <= p->vm_end) { 41 | isCollision = 1; 42 | break; 43 | } 44 | 45 | if (isCollision) // Collision 46 | start = (void *)get_unmapped_area(length); 47 | 48 | struct vm_area_struct *vm_area_ptr = kmalloc(sizeof(struct vm_area_struct)); 49 | 50 | vm_area_ptr->vm_start = start; 51 | vm_area_ptr->vm_end = start + length; 52 | vm_area_ptr->vm_next = NULL; 53 | vm_area_ptr->vm_mm = mm; 54 | vm_area_ptr->vm_page_prot.pgprot = prot; 55 | vm_area_ptr->vm_flags = flags; 56 | 57 | if (!mm->vm_area_list) { // Empty vm area list 58 | vm_area_ptr->vm_prev = NULL; 59 | mm->vm_area_list = vm_area_ptr; 60 | } else { // Traverse existing vm area list 61 | struct vm_area_struct *p; 62 | for (p = mm->vm_area_list; p->vm_next; p = p->vm_next) 63 | ; 64 | p->vm_next = vm_area_ptr; 65 | vm_area_ptr->vm_prev = p; 66 | } 67 | 68 | return start; 69 | } 70 | 71 | /** 72 | * @param __addr 建议映射的虚拟首地址,需要按页对齐 73 | * @param __len 映射的长度,需要按页对齐 74 | * @param __prot 映射区的权限,在4.3.1节中已说明 75 | * @param __flags 由于本次实验不涉及mmap在Linux中的其他功能,该参数无意义,固定为 76 | * (MAP_PRIVATE | MAP_ANONYMOUS) 77 | * @param __fd 由于本次实验不涉及文件映射,该参数无意义,固定为-1 78 | * @param __offset 由于本次实验不涉及文件映射,该参数无意义,固定为0 79 | * @return void* 实际映射的虚拟首地址,若虚拟地址区域[__addr, __addr+__len)未与 80 | * 其它地址映射冲突,则返回值就是建议首地址__addr,若发生冲突,则需要更换到无冲突的虚拟地址区域,返回值为该区域的首地址 81 | */ 82 | void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset) { 83 | return do_mmap(current->mm, __addr, __len, __prot, MAP_PRIVATE | MAP_ANONYMOUS, 0); 84 | } 85 | 86 | void free_page_tables(uint64 pagetable, uint64 va, uint64 n, int free_frame) { 87 | for (uint64 addr_last_byte = va + n - 1; va <= addr_last_byte; va += PAGE_SIZE) { 88 | LoadPTE(page_walk(pagetable, va), 0, 1); 89 | } 90 | } 91 | 92 | /** 93 | * @brief 94 | * 95 | * @param start 96 | * @param length 97 | * @return int 98 | */ 99 | int munmap(void *start, size_t length) { 100 | _Bool found = 0; 101 | for (struct vm_area_struct *p = current->mm->vm_area_list; p; p = p->vm_next) { 102 | if (p->vm_start >= start && p->vm_end <= start + length) { 103 | free_page_tables(current->mm->rtpg_addr, start, PAGE_CEIL(length), 1); 104 | if (p->vm_prev) 105 | p->vm_prev->vm_next = p->vm_next; 106 | if (p->vm_next) 107 | p->vm_next->vm_prev = p->vm_prev; 108 | kfree(p); 109 | found = 1; 110 | } 111 | } 112 | return (found ? 0 : -1); 113 | } 114 | 115 | /** 116 | * @brief 117 | * 118 | * @param __addr 119 | * @param __len 120 | * @param __prot 121 | * @return int 122 | */ 123 | int mprotect(void *__addr, size_t __len, int __prot) { 124 | for (uint64 addr_last_byte = __addr + __len - 1; __addr <= addr_last_byte; 125 | __addr += PAGE_SIZE) { 126 | LoadPTE(page_walk(current->mm->rtpg_addr, __addr), __prot, 1); 127 | } 128 | } -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/include/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHED_H 2 | #define _SCHED_H 3 | 4 | #define TASK_BASE 0xffffffe000ff0000 5 | #define TASK_SIZE (4096) 6 | // #define THREAD_OFFSET (5 * 0x08) 7 | 8 | #ifndef __ASSEMBLER__ 9 | 10 | /* task的最大数量 */ 11 | #define NR_TASKS 64 12 | 13 | #define FIRST_TASK (task[0]) 14 | #define LAST_TASK (task[NR_TASKS - 1]) 15 | 16 | /* 定义task的状态,Lab3中task只需要一种状态。*/ 17 | #define TASK_RUNNING 0 18 | #define TASK_INTERRUPTIBLE 1 19 | #define TASK_UNINTERRUPTIBLE 2 20 | #define TASK_ZOMBIE 3 21 | #define TASK_STOPPED 4 22 | 23 | // #define PRIORITY 24 | // #define SJF 25 | 26 | // Ensure Mutual Exclusion 27 | #ifdef SJF 28 | #define PREEMPT_ENABLE 0 29 | #else 30 | #ifdef PRIORITY 31 | #define PREEMPT_ENABLE 1 32 | #endif 33 | #endif 34 | 35 | #define PREEMPT_DISABLE !PREEMPT_ENABLE 36 | 37 | /* Lab3中进程的数量以及每个进程初始的时间片 */ 38 | #define LAB_TEST_NUM 4 39 | #define LAB_TEST_COUNTER 5 40 | 41 | /* 当前进程 */ 42 | extern struct task_struct *current; 43 | 44 | /* 进程指针数组 */ 45 | extern struct task_struct *task[NR_TASKS]; 46 | 47 | /* 进程状态段数据结构 */ 48 | struct thread_struct { 49 | unsigned long long ra; 50 | unsigned long long sp; 51 | unsigned long long s0; 52 | unsigned long long s1; 53 | unsigned long long s2; 54 | unsigned long long s3; 55 | unsigned long long s4; 56 | unsigned long long s5; 57 | unsigned long long s6; 58 | unsigned long long s7; 59 | unsigned long long s8; 60 | unsigned long long s9; 61 | unsigned long long s10; 62 | unsigned long long s11; 63 | }; 64 | 65 | /* 进程数据结构 */ 66 | struct task_struct { 67 | long state; // 进程状态 Lab3中进程初始化时置为TASK_RUNNING 68 | long counter; // 运行剩余时间 69 | long priority; // 运行优先级 1最高 5最低 70 | long blocked; 71 | long pid; // 进程标识符 72 | // Above Size Cost: 40 bytes 73 | 74 | struct thread_struct thread; // 该进程状态段 75 | }; 76 | 77 | /* 进程初始化 创建四个dead_loop进程 */ 78 | void task_init(void); 79 | 80 | /* 在时钟中断处理中被调用 */ 81 | void do_timer(void); 82 | 83 | /* 调度程序 */ 84 | void schedule(void); 85 | 86 | /* 切换当前任务current到下一个任务next */ 87 | void switch_to(struct task_struct *next); 88 | void switch_to_asm(); 89 | 90 | /* 死循环 */ 91 | void dead_loop(void); 92 | 93 | #define CONTEXT_SAVE(pTask) \ 94 | { \ 95 | asm("sd ra, %0" : : "m"(pTask->thread.ra)); \ 96 | asm("sd sp, %0" : : "m"(pTask->thread.sp)); \ 97 | asm("sd s0, %0" : : "m"(pTask->thread.s0)); \ 98 | asm("sd s1, %0" : : "m"(pTask->thread.s1)); \ 99 | asm("sd s2, %0" : : "m"(pTask->thread.s2)); \ 100 | asm("sd s3, %0" : : "m"(pTask->thread.s3)); \ 101 | asm("sd s4, %0" : : "m"(pTask->thread.s4)); \ 102 | asm("sd s5, %0" : : "m"(pTask->thread.s5)); \ 103 | asm("sd s6, %0" : : "m"(pTask->thread.s6)); \ 104 | asm("sd s7, %0" : : "m"(pTask->thread.s7)); \ 105 | asm("sd s8, %0" : : "m"(pTask->thread.s8)); \ 106 | asm("sd s9, %0" : : "m"(pTask->thread.s9)); \ 107 | asm("sd s10, %0" : : "m"(pTask->thread.s10)); \ 108 | asm("sd s11, %0" : : "m"(pTask->thread.s11)); \ 109 | } 110 | 111 | #define CONTEXT_LOAD(pTask) \ 112 | { \ 113 | asm("ld ra, %0" : : "m"(pTask->thread.ra)); \ 114 | asm("ld sp, %0" : : "m"(pTask->thread.sp)); \ 115 | asm("ld s0, %0" : : "m"(pTask->thread.s0)); \ 116 | asm("ld s1, %0" : : "m"(pTask->thread.s1)); \ 117 | asm("ld s2, %0" : : "m"(pTask->thread.s2)); \ 118 | asm("ld s3, %0" : : "m"(pTask->thread.s3)); \ 119 | asm("ld s4, %0" : : "m"(pTask->thread.s4)); \ 120 | asm("ld s5, %0" : : "m"(pTask->thread.s5)); \ 121 | asm("ld s6, %0" : : "m"(pTask->thread.s6)); \ 122 | asm("ld s7, %0" : : "m"(pTask->thread.s7)); \ 123 | asm("ld s8, %0" : : "m"(pTask->thread.s8)); \ 124 | asm("ld s9, %0" : : "m"(pTask->thread.s9)); \ 125 | asm("ld s10, %0" : : "m"(pTask->thread.s10)); \ 126 | asm("ld s11, %0" : : "m"(pTask->thread.s11)); \ 127 | } 128 | 129 | #define PRINT_SWITCH_INFO() \ 130 | { \ 131 | puts("[!] Switch from task "); \ 132 | putd(current->pid); \ 133 | puts(" [task struct: "); \ 134 | putx((unsigned long)current); \ 135 | puts(", sp: "); \ 136 | putx(current->thread.sp); \ 137 | puts("] to task "); \ 138 | putd(task[i_min_cnt]->pid); \ 139 | puts(" [task struct: "); \ 140 | putx((unsigned long)task[i_min_cnt]); \ 141 | puts(", sp: "); \ 142 | putx(task[i_min_cnt]->thread.sp); \ 143 | puts("], prio: "); \ 144 | putd(task[i_min_cnt]->priority); \ 145 | puts(", counter: "); \ 146 | putd(task[i_min_cnt]->counter); \ 147 | puts("\n"); \ 148 | } 149 | 150 | #endif 151 | 152 | #endif -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/sched.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sched.c 3 | * @author Scott Chen 4 | * @brief the scheduler implementation of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | */ 9 | #include "sched.h" 10 | #include "put.h" 11 | #include "rand.h" 12 | 13 | struct task_struct *current; 14 | struct task_struct *task[NR_TASKS]; 15 | 16 | /** 17 | * @brief init tasks, create 4 threads running dead-loop 18 | */ 19 | void task_init(void) { 20 | current = (struct task_struct *)TASK_BASE; 21 | for (int i = 0; i <= LAB_TEST_NUM; i++) { 22 | task[i] = (struct task_struct *)(long)(TASK_BASE + TASK_SIZE * i); 23 | task[i]->state = TASK_RUNNING; 24 | task[i]->counter = i == 0 ? 0 : (PREEMPT_ENABLE ? 8 - i : rand()); 25 | task[i]->priority = 5; 26 | task[i]->blocked = 0; 27 | task[i]->pid = i; 28 | 29 | task[i]->thread.sp = TASK_BASE + TASK_SIZE * (i + 1) - 0x1; 30 | asm("la t0, thread_init"); 31 | asm("sd t0, %0" ::"m"(task[i]->thread.ra)); 32 | 33 | if (i != 0) { 34 | puts("[PID = "); 35 | putd(task[i]->pid); 36 | puts("] Process Create Successfully! counter = "); 37 | putd(task[i]->counter); 38 | #if PREEMPT_ENABLE == 1 // PRIORITY 39 | puts(" priority = "); 40 | putd(task[i]->priority); 41 | #endif 42 | puts("\n"); 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * @brief called by timer int 49 | */ 50 | void do_timer(void) { 51 | #if PREEMPT_ENABLE == 0 // SJF 52 | // Print thread info for SJF 53 | puts("[PID = "); 54 | putd(current->pid); 55 | puts("] "); 56 | puts("Context Calculation: "); 57 | puts("counter = "); 58 | putd(current->counter); 59 | puts("\n"); 60 | 61 | // Decrease counter and schedule 62 | current->counter--; 63 | if (current->counter <= 0) 64 | schedule(); 65 | 66 | #else // PRIORITY 67 | current->counter--; 68 | if (current->counter <= 0) 69 | current->counter = (current->pid == 0) ? 5 : 8 - current->pid; 70 | schedule(); 71 | #endif 72 | } 73 | 74 | /** 75 | * @brief context switch from current to next 76 | * 77 | * @param next 78 | */ 79 | void switch_to(struct task_struct *next) { 80 | if (current == next) 81 | return; 82 | 83 | asm("addi sp, sp, 32"); // Restore the stack of switch_to 84 | CONTEXT_SAVE(current); // Do context save 85 | current = next; // `next` in $s0(-O0), will be overwrite soon 86 | CONTEXT_LOAD(current); // This `current` is the argv `next` 87 | asm("ret"); 88 | } 89 | 90 | /** 91 | * @brief dead loop 92 | */ 93 | void dead_loop(void) { 94 | for (;;) 95 | ; 96 | } 97 | 98 | /** 99 | * @brief schedule implementation 100 | */ 101 | void schedule(void) { 102 | #if PREEMPT_ENABLE == 0 // SJF 103 | int i_min_cnt = LAB_TEST_NUM; // index of min but not zero counter 104 | _Bool all_zeroes = 1; 105 | for (int i = LAB_TEST_NUM; i > 0; i--) 106 | if (task[i]->state == TASK_RUNNING) { 107 | if (task[i]->counter > 0 && task[i]->counter < task[i_min_cnt]->counter || 108 | task[i_min_cnt]->counter == 0) 109 | i_min_cnt = i; 110 | if (task[i]->counter > 0) // In case of negative cnt 111 | all_zeroes = 0; 112 | } 113 | if (all_zeroes) { 114 | for (int i = 1; i <= LAB_TEST_NUM; i++) 115 | if (task[i]->state == TASK_RUNNING) { 116 | task[i]->counter = rand(); 117 | 118 | puts("[PID = "); 119 | putd(task[i]->pid); 120 | puts("] Reset counter = "); 121 | putd(task[i]->counter); 122 | puts("\n"); 123 | } 124 | schedule(); 125 | } else { 126 | PRINT_SWITCH_INFO(); 127 | 128 | switch_to(task[i_min_cnt]); 129 | } 130 | 131 | #else // PRIORITY 132 | int max_pri = __INT_MAX__, i_min_cnt = 1; 133 | for (int i = 1; i <= LAB_TEST_NUM; i++) 134 | if (task[i]->state == TASK_RUNNING) 135 | if (task[i]->priority < max_pri) { 136 | i_min_cnt = i; 137 | max_pri = task[i]->priority; 138 | } else if (task[i]->priority == max_pri && 139 | task[i]->counter < task[i_min_cnt]->counter && task[i]->counter > 0) 140 | i_min_cnt = i; 141 | 142 | // Must be printed here to meet demands, else the printed info is out-dated 143 | PRINT_SWITCH_INFO(); 144 | 145 | // Use another loop to update prio 146 | for (int i = 1; i <= LAB_TEST_NUM; i++) 147 | if (task[i]->state == TASK_RUNNING) 148 | task[i]->priority = rand(); 149 | 150 | // Print all threads' info for PRIORITY 151 | puts("tasks' priority changed\n"); 152 | for (int i = 1; i <= LAB_TEST_NUM; i++) 153 | if (task[i]->state == TASK_RUNNING) { 154 | puts("[PID = "); 155 | putd(task[i]->pid); 156 | puts("] "); 157 | puts("counter = "); 158 | putd(task[i]->counter); 159 | puts(" priority = "); 160 | putd(task[i]->priority); 161 | puts("\n"); 162 | } 163 | switch_to(task[i_min_cnt]); 164 | #endif 165 | } 166 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/lib/put.c: -------------------------------------------------------------------------------- 1 | #include "put.h" 2 | #include "types.h" 3 | 4 | typedef __builtin_va_list va_list; 5 | #define va_start(v, l) __builtin_va_start(v, l) 6 | #define va_end(v) __builtin_va_end(v) 7 | #define va_arg(v, l) __builtin_va_arg(v, l) 8 | #define va_copy(d, s) __builtin_va_copy(d, s) 9 | 10 | int puts(const char *s) { 11 | while (*s != '\0') { 12 | *UART_VIR_ADDR = (unsigned char)(*s); 13 | s++; 14 | } 15 | return 0; 16 | } 17 | 18 | static unsigned char hex_map[16] = { 19 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 20 | 21 | void putd(long x) { 22 | long digit = 1, tmp = x; 23 | while (tmp >= 10) { 24 | digit *= 10; 25 | tmp /= 10; 26 | } 27 | while (digit >= 1) { 28 | *UART_VIR_ADDR = hex_map[x / digit]; 29 | x %= digit; 30 | digit /= 10; 31 | } 32 | return; 33 | } 34 | 35 | void putx(unsigned long x) { 36 | unsigned long digit = 1, tmp = x; 37 | 38 | puts("0x"); 39 | if (x == 0) { 40 | puts("0"); 41 | return; 42 | } 43 | while (tmp >= 16) { 44 | digit *= 16; 45 | tmp /= 16; 46 | } 47 | while (digit >= 1) { 48 | *UART_VIR_ADDR = hex_map[x / digit]; 49 | x %= digit; 50 | digit /= 16; 51 | } 52 | return; 53 | } 54 | 55 | int tail = 0; 56 | static char buffer[1000] = {[0 ... 999] = 0}; 57 | 58 | static inline int putchar(int c) { 59 | buffer[tail++] = (char)c; 60 | return 0; 61 | } 62 | 63 | static void vprintfmt(int (*putch)(int), const char *fmt, va_list vl) { 64 | _Bool in_format = 0, longarg = 0; 65 | size_t pos = 0; 66 | for (; *fmt; fmt++) { 67 | if (in_format) { 68 | switch (*fmt) { 69 | case 'l': { 70 | longarg = 1; 71 | break; 72 | } 73 | case 'x': { 74 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 75 | int hexdigits = 2 * (longarg ? sizeof(long) : sizeof(int)) - 1; 76 | for (int halfbyte = hexdigits; halfbyte >= 0; halfbyte--) { 77 | int hex = (num >> (4 * halfbyte)) & 0xF; 78 | char hexchar = (hex < 10 ? '0' + hex : 'a' + hex - 10); 79 | putch(hexchar); 80 | pos++; 81 | } 82 | longarg = 0; 83 | in_format = 0; 84 | break; 85 | } 86 | case 'd': { 87 | long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 88 | if (num < 0) { 89 | num = -num; 90 | putch('-'); 91 | pos++; 92 | } 93 | int bits = 0; 94 | char decchar[25] = {'0', 0}; 95 | for (long tmp = num; tmp; bits++) { 96 | decchar[bits] = (tmp % 10) + '0'; 97 | tmp /= 10; 98 | } 99 | if (bits == 0) 100 | bits++; 101 | for (int i = bits - 1; i >= 0; i--) 102 | putch(decchar[i]); 103 | pos += bits + 1; 104 | longarg = 0; 105 | in_format = 0; 106 | break; 107 | } 108 | 109 | case 'u': { 110 | unsigned long num = longarg ? va_arg(vl, long) : va_arg(vl, int); 111 | int bits = 0; 112 | char decchar[25] = {'0', 0}; 113 | for (long tmp = num; tmp; bits++) { 114 | decchar[bits] = (tmp % 10) + '0'; 115 | tmp /= 10; 116 | } 117 | if (bits == 0) 118 | bits++; 119 | for (int i = bits - 1; i >= 0; i--) 120 | putch(decchar[i]); 121 | pos += bits - 1; 122 | longarg = 0; 123 | in_format = 0; 124 | break; 125 | } 126 | 127 | case 's': { 128 | const char *str = va_arg(vl, const char *); 129 | while (*str) { 130 | putch(*str); 131 | pos++; 132 | str++; 133 | } 134 | longarg = 0; 135 | in_format = 0; 136 | break; 137 | } 138 | 139 | case 'c': { 140 | char ch = (char)va_arg(vl, int); 141 | putch(ch); 142 | pos++; 143 | longarg = 0; 144 | in_format = 0; 145 | break; 146 | } 147 | default: break; 148 | } 149 | } else if (*fmt == '%') { 150 | in_format = 1; 151 | } else { 152 | putch(*fmt); 153 | pos++; 154 | } 155 | } 156 | 157 | long syscall_ret, fd = 1; 158 | buffer[tail++] = '\0'; 159 | puts(buffer); 160 | } 161 | 162 | void putf(const char *s, ...) { 163 | va_list vl; 164 | va_start(vl, s); 165 | tail = 0; 166 | vprintfmt(putchar, s, vl); 167 | va_end(vl); 168 | } -------------------------------------------------------------------------------- /Lab0/Lab0_陈希尧_3012.md: -------------------------------------------------------------------------------- 1 |
《操作系统》Lab0

陈希尧 3180103012
2 | 3 | [TOC] 4 | 5 | # Lab Basis 6 | 7 | ## Purpose 8 | 9 | * 编译内核并用 gdb + QEMU 调试,在内核初始化过程中(用户登录之前)设置断点,对内核的启 动过程进行跟踪,并尝试使用gdb的各项命令(如backtrace、nish、frame、info、break、 display、next等)。 10 | * 在学在浙大中提交pdf格式的实验报告,记录实验过程并截图(4.1 - 4.4),对每一步的命令以及结 果进行必要的解释,记录遇到的问题和心得体会。 11 | 12 | ## Environment 13 | 14 | OS: Ubuntu 18.04.5 LTS on Windows 10 x86_64 (WSL2) 15 | 16 | Kernel: 4.19.128-microsoft-standard 17 | 18 | Docker version 19.03.13 19 | 20 | # Lab Steps 21 | 22 | ## Docker Installation 23 | 24 | > Reference: https://docs.docker.com/engine/install/ubuntu/#install-from-a-package 25 | 26 | 1. Get link address of docker-ce, docker-ce-cli and container.io using `wget` 27 | 28 | ``` 29 | https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/containerd.io_1.3.7-1_amd64.deb 30 | https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce-cli_19.03.13~3-0~ubuntu-bionic_amd64.deb 31 | https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce_19.03.13~3-0~ubuntu-bionic_amd64.de 32 | ``` 33 | 34 | 2. `sudo dpkg -i ${pathToPkg}` to install 35 | 36 | 3. `sudo service docker start` (important, seems the daemon won't start automatically) 37 | 38 | 4. add user to docker group, which is sudoers 39 | 40 | ```zsh 41 | sudo usermod -aGdocker ulysses 42 | sudo chmod a+rw ~/.docker/config.json 43 | sudo chmod a+rw /var/run/docker.sock 44 | ``` 45 | 46 | 5. Try running hello-world 47 | 48 | ## Create Container 49 | 50 | 1. Use `cat` and pipline to import image 51 | 2. `docker image ls` to check if image is imported correctly 52 | 3. Start container from image using `docker run -it osab:2020 /bin/bash` 53 | * No zsh installed 54 | * `-i`: interactivate 55 | * `-t`: terminal 56 | 4. `^D` to exit the container 57 | 5. `docker ps` can show all the container on the run 58 | * Same usage as `ps` 59 | * `-a` to show all container that has been started 60 | 6. `docker start 1737` can restart stopped container 61 | 7. Now the status can be seen using `docker ps` 62 | 8. `docker exec -it -u oslab -w /home/oslab 17 /bin/bash` to enter the container 63 | 64 | Screenshots: 65 | 66 | 67 | 68 | 69 | 70 | ## Compile kernel 71 | 72 | First set the system variables(I add them to "~/.bashrc" for convenience), then just `make` following the instructions. 73 | 74 | 75 | 76 | ```bash 77 | oslab@173798be1912:~$ ls 78 | lab0 79 | oslab@173798be1912:~$ cd lab0 80 | oslab@173798be1912:~/lab0$ export TOP=`pwd` 81 | oslab@173798be1912:~/lab0$ export RISCV=/opt/riscv 82 | oslab@173798be1912:~/lab0$ export PATH=$PATH:$RISCV/bin 83 | oslab@173798be1912:~/lab0$ mkdir -p build/linux 84 | oslab@173798be1912:~/lab0$ make -C linux O=$TOP/build/linux \ 85 | > CROSS_COMPILE=riscv64-unknown-linux-gnu- \ 86 | > ARCH=riscv CONFIG_DEBUG_INFO=y \ 87 | > defconfig all -j$(nproc) 88 | ``` 89 | 90 | Screenshot: 91 | 92 | 93 | 94 | Compile done: 95 | 96 | 97 | 98 | ## Run kernel 99 | 100 | ```bash 101 | oslab@173798be1912:~/lab0$ qemu-system-riscv64 -nographic -machine virt -kernel build/linux/arch/riscv/boot/Image \ 102 | > -device virtio-blk-device,drive=hd0 -append "root=/dev/vda ro console=ttyS0" \ 103 | > -bios default -drive file=rootfs.ext4,format=raw,id=hd0 \ 104 | > -netdev user,id=net0 -device virtio-net-device,netdev=net0 105 | ``` 106 | 107 | Screenshot: 108 | 109 | 110 | 111 | ## Debug kernel 112 | 113 | Use tmux to split the screen 114 | 115 | First start the `qemu-system-riscv64` program, here 116 | 117 | * `-s`: shorthand for -gdb tcp::1234 118 | * `-S`: freeze CPU at startup (use 'c' to start execution) 119 | 120 | Before `continue`, since stop-on-entry(`-S`) is set, the program will stop at enrty will no output: 121 | 122 | 123 | 124 | After `continue`, the program will continue to run to the breakpoint, which is at flag `start_kernel`: 125 | 126 | 127 | 128 | After `quit` gdb, the `qemu-system-riscv64` will continue to execute normally, so it will skip to the login interface: 129 | 130 | 131 | 132 | Then Try more gdb command: 133 | 134 | ```bash 135 | (gdb) target remote localhost:1234 136 | (gdb) b start_kernel # break 137 | (gdb) c # continue 138 | (gdb) f # frame, Select and print a stack frame. 139 | (gdb) bt # backtrace, Print backtrace of all stack frames, or innermost COUNT frames. 140 | (gdb) i args 141 | (gdb) i b 142 | (gdb) display /i $pc 143 | (gdb) n # next, step over 144 | (gdb) finish # Upon return, the value returned is printed and put in the value history. 145 | ``` 146 | 147 | 148 | 149 | # Problems & Thoughts 150 | 151 | ## Problems 152 | 153 | 1. 网络问题,本来打算通过apt安装docker的,后来发现换源这步挂了梯子都无法连接到[download.docker.com](https://download.docker.com),遂放弃,改用包安装 154 | 2. 根据官方手册,下载.deb包并安装完后守护进程会自动启动,因此提示说"docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?."的时候我以为是socket连接的问题,后来才发现是daemon根本没开始,`sudo service docker start`后解决 155 | 3. `qemu-system-riscv64`开始后,"^c"只能退出到qemu的登陆界面,不知道怎么退出,一直通过`ps`+`kill`解决 156 | 157 | ## Thoughts 158 | 159 | 本次实验主要完成了docker环境的配置与qemu平台的初步试验,难度较低,我的主要收获是掌握了gdb中一些基础的命令,由于之前一直是用ide的工具链或是vscode的插件进行调试,对gdb的指令接触较少,相信学习这些对我以后的实验很有帮助。 160 | 161 | -------------------------------------------------------------------------------- /Lab2/source/arch/riscv/kernel/entry.S: -------------------------------------------------------------------------------- 1 | .section .text.entry 2 | 3 | .global trap_m 4 | trap_m: 5 | # Save regs 6 | addi sp, sp, -264 7 | sd x1, 256(sp) 8 | sd x2, 248(sp) 9 | sd x3, 240(sp) 10 | sd x4, 232(sp) 11 | sd x5, 224(sp) 12 | sd x6, 216(sp) 13 | sd x7, 208(sp) 14 | sd x8, 200(sp) 15 | sd x9, 192(sp) 16 | sd x10, 184(sp) 17 | sd x11, 176(sp) 18 | sd x12, 168(sp) 19 | sd x13, 160(sp) 20 | sd x14, 152(sp) 21 | sd x15, 144(sp) 22 | sd x16, 136(sp) 23 | sd x17, 128(sp) 24 | sd x18, 120(sp) 25 | sd x19, 112(sp) 26 | sd x20, 104(sp) 27 | sd x21, 96(sp) 28 | sd x22, 88(sp) 29 | sd x23, 80(sp) 30 | sd x24, 72(sp) 31 | sd x25, 64(sp) 32 | sd x26, 56(sp) 33 | sd x27, 48(sp) 34 | sd x28, 40(sp) 35 | sd x29, 32(sp) 36 | sd x30, 24(sp) 37 | sd x31, 16(sp) 38 | csrr t0, mcause 39 | sd t0, 8(sp) 40 | csrr t0, mepc 41 | sd t0, 0(sp) 42 | 43 | csrr t0, mcause 44 | srli t1, t0, 63 # t1 = MSB 45 | andi t0, t0, 0xff # t0 = code 46 | beq t1, zero, trap_m_except 47 | 48 | trap_m_int: 49 | la t1, mcause_MTimer 50 | beq t0, t1, trap_m_timer 51 | j trap_m_end 52 | 53 | trap_m_timer: 54 | # enable mip.stip 55 | li t0, 0x20 # mip[5] 56 | csrs mip, t0 # For trap_s 57 | 58 | # clear mie.mtie 59 | li t0, 0x80 60 | csrc mie, t0 61 | 62 | j trap_m_end 63 | 64 | trap_m_except: 65 | la t1, mcause_ecallS 66 | beq t0, t1, trap_m_ecallS 67 | j trap_m_except_end 68 | 69 | trap_m_ecallS: 70 | # !!!!!! clear mip.stip !!!!!! 71 | li t0, 0x20 # sip[5] 72 | csrc mip, t0 # Stop from calling trap_s 73 | 74 | # set mtimecmp += time_sep, hardware will clear mip.mtip 75 | la t0, mtime_addr 76 | ld t0, 0(t0) # t0 = mtimecmp 77 | la t1, time_sep 78 | add t1, t0, t1 # t1 = mtimecmp+sep 79 | la t0, mtimecmp_addr 80 | sd t1, 0(t0) 81 | 82 | # enable mie.mtie 83 | li t0, 0x80 84 | csrs mie, t0 85 | 86 | j trap_m_except_end 87 | 88 | trap_m_except_end: 89 | ld t0, 0(sp) 90 | addi t0, t0, 4 # mepc += 4 91 | sd t0, 0(sp) 92 | 93 | trap_m_end: 94 | # Get regs back 95 | ld t0, 0(sp) 96 | csrw mepc, t0 97 | ld t0, 8(sp) 98 | csrw mcause, t0 99 | ld x31, 16(sp) 100 | ld x30, 24(sp) 101 | ld x29, 32(sp) 102 | ld x28, 40(sp) 103 | ld x27, 48(sp) 104 | ld x26, 56(sp) 105 | ld x25, 64(sp) 106 | ld x24, 72(sp) 107 | ld x23, 80(sp) 108 | ld x22, 88(sp) 109 | ld x21, 96(sp) 110 | ld x20, 104(sp) 111 | ld x19, 112(sp) 112 | ld x18, 120(sp) 113 | ld x17, 128(sp) 114 | ld x16, 136(sp) 115 | ld x15, 144(sp) 116 | ld x14, 152(sp) 117 | ld x13, 160(sp) 118 | ld x12, 168(sp) 119 | ld x11, 176(sp) 120 | ld x10, 184(sp) 121 | ld x9, 192(sp) 122 | ld x8, 200(sp) 123 | ld x7, 208(sp) 124 | ld x6, 216(sp) 125 | ld x5, 224(sp) 126 | ld x4, 232(sp) 127 | ld x3, 240(sp) 128 | ld x2, 248(sp) 129 | ld x1, 256(sp) 130 | addi sp, sp, 264 131 | 132 | mret 133 | 134 | 135 | .global trap_s 136 | trap_s: 137 | # Save regs 138 | addi sp, sp, -264 139 | sd x1, 256(sp) 140 | sd x2, 248(sp) 141 | sd x3, 240(sp) 142 | sd x4, 232(sp) 143 | sd x5, 224(sp) 144 | sd x6, 216(sp) 145 | sd x7, 208(sp) 146 | sd x8, 200(sp) 147 | sd x9, 192(sp) 148 | sd x10, 184(sp) 149 | sd x11, 176(sp) 150 | sd x12, 168(sp) 151 | sd x13, 160(sp) 152 | sd x14, 152(sp) 153 | sd x15, 144(sp) 154 | sd x16, 136(sp) 155 | sd x17, 128(sp) 156 | sd x18, 120(sp) 157 | sd x19, 112(sp) 158 | sd x20, 104(sp) 159 | sd x21, 96(sp) 160 | sd x22, 88(sp) 161 | sd x23, 80(sp) 162 | sd x24, 72(sp) 163 | sd x25, 64(sp) 164 | sd x26, 56(sp) 165 | sd x27, 48(sp) 166 | sd x28, 40(sp) 167 | sd x29, 32(sp) 168 | sd x30, 24(sp) 169 | sd x31, 16(sp) 170 | csrr t0, scause 171 | sd t0, 8(sp) 172 | csrr t0, sepc 173 | sd t0, 0(sp) 174 | 175 | csrr t0, scause 176 | srli t1, t0, 63 # t1 = MSB 177 | andi t0, t0, 0xff # t0 = code 178 | beq t1, zero, trap_s_except 179 | 180 | trap_s_int: 181 | la t1, scause_STimer 182 | beq t0, t1, trap_s_timer 183 | j trap_s_end 184 | 185 | trap_s_timer: 186 | call put_trap_s 187 | ecall 188 | 189 | j trap_s_end 190 | 191 | trap_s_except: 192 | 193 | j trap_s_except_end # No implementation yet 194 | 195 | trap_s_except_end: 196 | ld t0, 0(sp) 197 | addi t0, t0, 4 # sepc += 4 198 | sd t0, 0(sp) 199 | 200 | trap_s_end: 201 | # Get regs back 202 | ld t0, 0(sp) 203 | csrw mepc, t0 204 | ld t0, 8(sp) 205 | csrw mcause, t0 206 | ld x31, 16(sp) 207 | ld x30, 24(sp) 208 | ld x29, 32(sp) 209 | ld x28, 40(sp) 210 | ld x27, 48(sp) 211 | ld x26, 56(sp) 212 | ld x25, 64(sp) 213 | ld x24, 72(sp) 214 | ld x23, 80(sp) 215 | ld x22, 88(sp) 216 | ld x21, 96(sp) 217 | ld x20, 104(sp) 218 | ld x19, 112(sp) 219 | ld x18, 120(sp) 220 | ld x17, 128(sp) 221 | ld x16, 136(sp) 222 | ld x15, 144(sp) 223 | ld x14, 152(sp) 224 | ld x13, 160(sp) 225 | ld x12, 168(sp) 226 | ld x11, 176(sp) 227 | ld x10, 184(sp) 228 | ld x9, 192(sp) 229 | ld x8, 200(sp) 230 | ld x7, 208(sp) 231 | ld x6, 216(sp) 232 | ld x5, 224(sp) 233 | ld x4, 232(sp) 234 | ld x3, 240(sp) 235 | ld x2, 248(sp) 236 | ld x1, 256(sp) 237 | addi sp, sp, 264 238 | 239 | sret 240 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/sched.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sched.c 3 | * @author Scott Chen 4 | * @brief the scheduler implementation of oslab3 5 | * @version 0.1 6 | * @date 2020-11-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab3 8 | */ 9 | #include "sched.h" 10 | #include "put.h" 11 | #include "rand.h" 12 | 13 | struct task_struct *current; 14 | struct task_struct *task[NR_TASKS]; 15 | 16 | /** 17 | * @brief init tasks, create 4 threads running dead-loop 18 | */ 19 | void task_init(void) { 20 | current = (struct task_struct *)TASK_BASE; 21 | for (int i = 0; i <= LAB_TEST_NUM; i++) { 22 | task[i] = (struct task_struct *)(long)(TASK_BASE + TASK_SIZE * i); 23 | task[i]->state = TASK_RUNNING; 24 | task[i]->counter = i == 0 ? 0 : (PREEMPT_ENABLE ? 8 - i : rand()); 25 | task[i]->priority = 5; 26 | task[i]->blocked = 0; 27 | task[i]->pid = i; 28 | 29 | task[i]->thread.sp = TASK_BASE + TASK_SIZE * (i + 1) - 0x1; 30 | asm("la t0, thread_init"); 31 | asm("sd t0, %0" ::"m"(task[i]->thread.ra)); 32 | 33 | if (i != 0) { 34 | puts("[PID = "); 35 | puti(task[i]->pid); 36 | puts("] Process Create Successfully! counter = "); 37 | puti(task[i]->counter); 38 | #if PREEMPT_ENABLE == 1 // PRIORITY 39 | puts(" priority = "); 40 | puti(task[i]->priority); 41 | #endif 42 | puts("\n"); 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * @brief called by timer int 49 | */ 50 | void do_timer(void) { 51 | #if PREEMPT_ENABLE == 0 // SJF 52 | // Print thread info for SJF 53 | puts("[PID = "); 54 | puti(current->pid); 55 | puts("] "); 56 | puts("Context Calculation: "); 57 | puts("counter = "); 58 | puti(current->counter); 59 | puts("\n"); 60 | 61 | // Decrease counter and schedule 62 | current->counter--; 63 | if (current->counter <= 0) 64 | schedule(); 65 | 66 | #else // PRIORITY 67 | current->counter--; 68 | if (current->counter <= 0) 69 | current->counter = (current->pid == 0) ? 5 : 8 - current->pid; 70 | schedule(); 71 | #endif 72 | } 73 | 74 | /** 75 | * @brief context switch from current to next 76 | */ 77 | void switch_to(struct task_struct *next) { 78 | if (current == next) 79 | return; 80 | 81 | asm("addi sp, sp, 32"); // Restore the stack of switch_to 82 | CONTEXT_SAVE(current); // Do context save 83 | current = next; // `next` in $s0(-O0), will be overwrite soon 84 | CONTEXT_LOAD(current); // This `current` is the argv `next` 85 | asm("ret"); 86 | } 87 | 88 | /** 89 | * @brief dead loop 90 | */ 91 | void dead_loop(void) { 92 | for (;;) 93 | ; 94 | } 95 | 96 | /** 97 | * @brief schedule implementation 98 | */ 99 | void schedule(void) { 100 | #if PREEMPT_ENABLE == 0 // SJF 101 | int i_min_cnt = LAB_TEST_NUM; // index of min but not zero counter 102 | _Bool all_zeroes = 1; 103 | for (int i = LAB_TEST_NUM; i > 0; i--) 104 | if (task[i]->state == TASK_RUNNING) { 105 | if (task[i]->counter > 0 && task[i]->counter < task[i_min_cnt]->counter || 106 | task[i_min_cnt]->counter == 0) 107 | i_min_cnt = i; 108 | if (task[i]->counter > 0) // In case of negative cnt 109 | all_zeroes = 0; 110 | } 111 | if (all_zeroes) { 112 | for (int i = 1; i <= LAB_TEST_NUM; i++) 113 | if (task[i]->state == TASK_RUNNING) { 114 | task[i]->counter = rand(); 115 | 116 | puts("[PID = "); 117 | puti(task[i]->pid); 118 | puts("] Reset counter = "); 119 | puti(task[i]->counter); 120 | puts("\n"); 121 | } 122 | schedule(); 123 | } else { 124 | puts("[!] Switch from task "); 125 | puti(current->pid); 126 | puts(" to task "); 127 | puti(task[i_min_cnt]->pid); 128 | puts(", prio: "); 129 | puti(task[i_min_cnt]->priority); 130 | puts(", counter: "); 131 | puti(task[i_min_cnt]->counter); 132 | puts("\n"); 133 | 134 | switch_to(task[i_min_cnt]); 135 | } 136 | 137 | #else // PRIORITY 138 | int max_pri = __INT_MAX__, i_min_cnt = 1; 139 | for (int i = 1; i <= LAB_TEST_NUM; i++) 140 | if (task[i]->state == TASK_RUNNING) 141 | if (task[i]->priority < max_pri) { 142 | i_min_cnt = i; 143 | max_pri = task[i]->priority; 144 | } else if (task[i]->priority == max_pri && 145 | task[i]->counter < task[i_min_cnt]->counter && task[i]->counter > 0) 146 | i_min_cnt = i; 147 | 148 | // Must be printed here to meet demands, else the printed info is out-dated 149 | puts("[!] Switch from task "); 150 | puti(current->pid); 151 | puts(" to task "); 152 | puti(task[i_min_cnt]->pid); 153 | puts(", prio: "); 154 | puti(task[i_min_cnt]->priority); 155 | puts(", counter: "); 156 | puti(task[i_min_cnt]->counter); 157 | puts("\n"); 158 | 159 | // Use another loop to update prio 160 | for (int i = 1; i <= LAB_TEST_NUM; i++) 161 | if (task[i]->state == TASK_RUNNING) 162 | task[i]->priority = rand(); 163 | 164 | // Print all threads' info for PRIORITY 165 | puts("tasks' priority changed\n"); 166 | for (int i = 1; i <= LAB_TEST_NUM; i++) 167 | if (task[i]->state == TASK_RUNNING) { 168 | puts("[PID = "); 169 | puti(task[i]->pid); 170 | puts("] "); 171 | puts("counter = "); 172 | puti(task[i]->counter); 173 | puts(" priority = "); 174 | puti(task[i]->priority); 175 | puts("\n"); 176 | } 177 | switch_to(task[i_min_cnt]); 178 | #endif 179 | } 180 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/vm.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file vm.c 3 | * @author Scott Chen 4 | * @brief the implementation vm management of oslab4 5 | * @version 0.1 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | * @ref http://www.five-embeddev.com/riscv-isa-manual/latest/supervisor.html#sv32algorithm 9 | */ 10 | #include "vm.h" 11 | #include "buddy.h" 12 | #include "mm.h" 13 | #include "slub.h" 14 | #include "stdio.h" 15 | #include "string.h" 16 | 17 | #define Page_Floor(__addr) ((uint64)(__addr) & ~(uint64)(PAGE_SIZE - 1)) 18 | 19 | #define VAtoVPN2(__va) (((uint64)(__va) >> 30) & (PAGE_ENTRY_NUM - 1)) 20 | #define VAtoVPN1(__va) (((uint64)(__va) >> 21) & (PAGE_ENTRY_NUM - 1)) 21 | #define VAtoVPN0(__va) (((uint64)(__va) >> 12) & (PAGE_ENTRY_NUM - 1)) 22 | 23 | #define PAtoPPN(__pa) (((uint64)(__pa) >> 12) & 0xfffffffffff) // PPN need no division 24 | 25 | // PROT = {RSW, D, A, G, U, X, W, R, V} = {6'b0, PERM_X|W|R, V} 26 | #define LoadPTE(__pte_addr, __ppn, __prot, __v) \ 27 | { \ 28 | *__pte_addr = ((uint64)(*(__pte_addr)) & 0xffc00000000003fe) | \ 29 | ((uint64)(__ppn) << 10) | ((uint64)(__prot) | (uint64)(__v)); \ 30 | } 31 | 32 | #define PTEtoPPN(__pte) (((uint64)(__pte) >> 10) & 0xfffffffffff) 33 | #define PTEtoV(__pte) ((_Bool)((uint64)(__pte)&0x1)) 34 | 35 | /** 36 | * @brief Alloc physical memory space for kernel 37 | * 38 | * @param size Memory space, in unit byte 39 | * @return void* Allocated space, NULL for insufficient space 40 | */ 41 | void *kalloc_byte(size_t size) { 42 | static struct free_list_node first_node; 43 | static struct free_list_node *free_list = NULL; 44 | if (free_list == NULL) { // Init 45 | free_list = &first_node; 46 | asm("la t0, kernel_rt_pg_addr"); 47 | asm("sd t0, %0" ::"m"(free_list->base)); 48 | free_list->limit = FREE_SPACE_SIZE; 49 | free_list->next = NULL; 50 | } 51 | for (struct free_list_node *p = free_list; p; p = free_list->next) 52 | if (p->limit >= size) { 53 | p->limit -= size; 54 | return (void *)((uint8 *)(p->base = (uint8 *)p->base + size) - size); 55 | } else 56 | return NULL; 57 | } 58 | 59 | void kfree_byte(void *addr) {} 60 | 61 | /** 62 | * @brief Page walk from level-2 PT to level-1 PT, and return addr of level-0 PTE 63 | * 64 | * @param pgtbl Addr of 1st(level-2) page table 65 | * @param va VA 66 | * @return uint64* Address of pte of the 3rd(level-0) PTE 67 | */ 68 | uint64 *page_walk(uint64 *pgtbl, uint64 va) { 69 | for (int level = 2; level > 0; level--) { 70 | uint64 *pte_addr; 71 | switch (level) { 72 | case 2: pte_addr = &pgtbl[VAtoVPN2(va)]; break; 73 | case 1: pte_addr = &pgtbl[VAtoVPN1(va)]; break; 74 | } 75 | // Update `pgtbl` to be next level's pg tbl's base 76 | if (PTEtoV(*pte_addr)) { // Valid PTE, next level PT has been constructed 77 | pgtbl = (uint64 *)(PTEtoPPN(*pte_addr) << 12); 78 | } else { // Invalid PTE, need to construct next level PT 79 | if ((pgtbl = (uint64 *)VA2PA(alloc_pages(1))) == NULL) { 80 | // if ((pgtbl = (uint64 *)kmalloc(PAGE_SIZE)) == NULL) { 81 | puts("\n[!] Insufficient Free Space.\n"); 82 | return NULL; // Insufficient free space for pg tbls 83 | } 84 | memset(pgtbl, 0, PAGE_SIZE); 85 | LoadPTE(pte_addr, PAtoPPN((uint64)pgtbl), 0, 1); // PTE <- next level pg's PPN 86 | } 87 | } 88 | return &pgtbl[VAtoVPN0(va)]; 89 | } 90 | 91 | /** 92 | * @brief Create a mapping object 93 | * 94 | * @param pgtbl Base addr of level-2 page table 95 | * @param va Mapping from 96 | * @param pa Mapping to 97 | * @param sz Mapping size, ceil to PAGE_SIZE 98 | * @param prot Mapping protetion & permission(XWR) 99 | */ 100 | void create_mapping(uint64 *pgtbl, uint64 va, uint64 pa, uint64 sz, int prot) { 101 | for (uint64 addr_last_byte = va + sz - 1; va <= addr_last_byte; 102 | va += PAGE_SIZE, pa += PAGE_SIZE) { 103 | LoadPTE(page_walk(pgtbl, va), PAtoPPN(pa), prot, 1); 104 | } 105 | } 106 | 107 | /** 108 | * @brief Map kernel space to equal addr and higer addr, and map hardware address 109 | */ 110 | void kernel_paging_init(void) { 111 | init_buddy_system(); 112 | 113 | uint64 *rtpg_addr = (uint64 *)VA2PA(alloc_pages(1)); 114 | 115 | // Map UART 116 | create_mapping( 117 | rtpg_addr, (uint64)UART_VIR_ADDR, (uint64)UART_PHY_ADDR, PAGE_SIZE, PERM_R | PERM_W); 118 | 119 | // Map Kernel: High 120 | create_mapping(rtpg_addr, KERNEL_VIR_BASE, KERNEL_PHY_BASE, KERNEL_TEXT_SIZE, 121 | PERM_R | PERM_X); // text 122 | create_mapping(rtpg_addr, KERNEL_VIR_BASE + KERNEL_TEXT_SIZE, 123 | KERNEL_PHY_BASE + KERNEL_TEXT_SIZE, KERNEL_RODATA_SIZE, 124 | PERM_R); // rodata 125 | create_mapping(rtpg_addr, KERNEL_VIR_BASE + KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE, 126 | KERNEL_PHY_BASE + KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE, 127 | KERNEL_MAPPING_SIZE - (KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE), 128 | PERM_R | PERM_W); // Other Sections 129 | 130 | // Map Kernel: Equal 131 | create_mapping(rtpg_addr, KERNEL_PHY_BASE, KERNEL_PHY_BASE, KERNEL_TEXT_SIZE, 132 | PERM_R | PERM_X); // text 133 | create_mapping(rtpg_addr, KERNEL_PHY_BASE + KERNEL_TEXT_SIZE, 134 | KERNEL_PHY_BASE + KERNEL_TEXT_SIZE, KERNEL_RODATA_SIZE, 135 | PERM_R); // rodata 136 | create_mapping(rtpg_addr, KERNEL_PHY_BASE + KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE, 137 | KERNEL_PHY_BASE + KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE, 138 | KERNEL_MAPPING_SIZE - (KERNEL_TEXT_SIZE + KERNEL_RODATA_SIZE), 139 | PERM_R | PERM_W); // Other Sections 140 | } 141 | -------------------------------------------------------------------------------- /Lab3/Lab3_3180103012/arch/riscv/kernel/entry.S: -------------------------------------------------------------------------------- 1 | .section .text.entry 2 | 3 | .global thread_init 4 | thread_init: 5 | la t0, dead_loop 6 | csrw sepc, t0 7 | sret 8 | 9 | .global trap_m 10 | trap_m: 11 | # Save regs 12 | addi sp, sp, -264 13 | sd x1, 256(sp) 14 | sd x2, 248(sp) 15 | sd x3, 240(sp) 16 | sd x4, 232(sp) 17 | sd x5, 224(sp) 18 | sd x6, 216(sp) 19 | sd x7, 208(sp) 20 | sd x8, 200(sp) 21 | sd x9, 192(sp) 22 | sd x10, 184(sp) 23 | sd x11, 176(sp) 24 | sd x12, 168(sp) 25 | sd x13, 160(sp) 26 | sd x14, 152(sp) 27 | sd x15, 144(sp) 28 | sd x16, 136(sp) 29 | sd x17, 128(sp) 30 | sd x18, 120(sp) 31 | sd x19, 112(sp) 32 | sd x20, 104(sp) 33 | sd x21, 96(sp) 34 | sd x22, 88(sp) 35 | sd x23, 80(sp) 36 | sd x24, 72(sp) 37 | sd x25, 64(sp) 38 | sd x26, 56(sp) 39 | sd x27, 48(sp) 40 | sd x28, 40(sp) 41 | sd x29, 32(sp) 42 | sd x30, 24(sp) 43 | sd x31, 16(sp) 44 | csrr t0, mcause 45 | sd t0, 8(sp) 46 | csrr t0, mepc 47 | sd t0, 0(sp) 48 | 49 | csrr t0, mcause 50 | srli t1, t0, 63 # t1 = MSB 51 | andi t0, t0, 0xff # t0 = code 52 | beq t1, zero, trap_m_except 53 | 54 | trap_m_int: 55 | la t1, mcause_MTimer 56 | beq t0, t1, trap_m_timer 57 | j trap_m_end 58 | 59 | trap_m_timer: 60 | # enable mip.stip 61 | li t0, 0x20 # mip[5] 62 | csrs mip, t0 # For trap_s 63 | 64 | # clear mie.mtie 65 | li t0, 0x80 66 | csrc mie, t0 67 | 68 | j trap_m_end 69 | 70 | trap_m_except: 71 | la t1, mcause_ecallS 72 | beq t0, t1, trap_m_ecallS 73 | j trap_m_except_end 74 | 75 | trap_m_ecallS: 76 | # !!!!!! clear mip.stip !!!!!! 77 | li t0, 0x20 # sip[5] 78 | csrc mip, t0 # Stop from calling trap_s 79 | 80 | # set mtimecmp += time_sep, hardware will clear mip.mtip 81 | la t0, mtime_addr 82 | ld t0, 0(t0) # t0 = mtimecmp 83 | la t1, time_sep 84 | add t1, t0, t1 # t1 = mtimecmp+sep 85 | la t0, mtimecmp_addr 86 | sd t1, 0(t0) 87 | 88 | # enable mie.mtie 89 | li t0, 0x80 90 | csrs mie, t0 91 | 92 | j trap_m_except_end 93 | 94 | trap_m_except_end: 95 | ld t0, 0(sp) 96 | addi t0, t0, 4 # mepc += 4 97 | sd t0, 0(sp) 98 | 99 | trap_m_end: 100 | # Get regs back 101 | ld t0, 0(sp) 102 | csrw mepc, t0 103 | ld t0, 8(sp) 104 | csrw mcause, t0 105 | ld x31, 16(sp) 106 | ld x30, 24(sp) 107 | ld x29, 32(sp) 108 | ld x28, 40(sp) 109 | ld x27, 48(sp) 110 | ld x26, 56(sp) 111 | ld x25, 64(sp) 112 | ld x24, 72(sp) 113 | ld x23, 80(sp) 114 | ld x22, 88(sp) 115 | ld x21, 96(sp) 116 | ld x20, 104(sp) 117 | ld x19, 112(sp) 118 | ld x18, 120(sp) 119 | ld x17, 128(sp) 120 | ld x16, 136(sp) 121 | ld x15, 144(sp) 122 | ld x14, 152(sp) 123 | ld x13, 160(sp) 124 | ld x12, 168(sp) 125 | ld x11, 176(sp) 126 | ld x10, 184(sp) 127 | ld x9, 192(sp) 128 | ld x8, 200(sp) 129 | ld x7, 208(sp) 130 | ld x6, 216(sp) 131 | ld x5, 224(sp) 132 | ld x4, 232(sp) 133 | ld x3, 240(sp) 134 | ld x2, 248(sp) 135 | ld x1, 256(sp) 136 | addi sp, sp, 264 137 | 138 | mret 139 | 140 | 141 | .global trap_s 142 | trap_s: 143 | # Save regs 144 | addi sp, sp, -264 145 | sd x1, 256(sp) 146 | sd x2, 248(sp) 147 | sd x3, 240(sp) 148 | sd x4, 232(sp) 149 | sd x5, 224(sp) 150 | sd x6, 216(sp) 151 | sd x7, 208(sp) 152 | sd x8, 200(sp) 153 | sd x9, 192(sp) 154 | sd x10, 184(sp) 155 | sd x11, 176(sp) 156 | sd x12, 168(sp) 157 | sd x13, 160(sp) 158 | sd x14, 152(sp) 159 | sd x15, 144(sp) 160 | sd x16, 136(sp) 161 | sd x17, 128(sp) 162 | sd x18, 120(sp) 163 | sd x19, 112(sp) 164 | sd x20, 104(sp) 165 | sd x21, 96(sp) 166 | sd x22, 88(sp) 167 | sd x23, 80(sp) 168 | sd x24, 72(sp) 169 | sd x25, 64(sp) 170 | sd x26, 56(sp) 171 | sd x27, 48(sp) 172 | sd x28, 40(sp) 173 | sd x29, 32(sp) 174 | sd x30, 24(sp) 175 | sd x31, 16(sp) 176 | csrr t0, scause 177 | sd t0, 8(sp) 178 | csrr t0, sepc 179 | sd t0, 0(sp) 180 | 181 | csrr t0, scause 182 | srli t1, t0, 63 # t1 = MSB 183 | andi t0, t0, 0xff # t0 = code 184 | beq t1, zero, trap_s_except 185 | 186 | trap_s_int: 187 | la t1, scause_STimer 188 | beq t0, t1, trap_s_timer 189 | j trap_s_end 190 | 191 | trap_s_timer: 192 | ecall 193 | call do_timer 194 | 195 | j trap_s_end 196 | 197 | trap_s_except: 198 | 199 | # No implementation yet 200 | j trap_s_except_end 201 | 202 | trap_s_except_end: 203 | ld t0, 0(sp) 204 | addi t0, t0, 4 # sepc += 4 205 | sd t0, 0(sp) 206 | 207 | trap_s_end: 208 | # Get regs back 209 | ld t0, 0(sp) 210 | csrw mepc, t0 211 | ld t0, 8(sp) 212 | csrw mcause, t0 213 | ld x31, 16(sp) 214 | ld x30, 24(sp) 215 | ld x29, 32(sp) 216 | ld x28, 40(sp) 217 | ld x27, 48(sp) 218 | ld x26, 56(sp) 219 | ld x25, 64(sp) 220 | ld x24, 72(sp) 221 | ld x23, 80(sp) 222 | ld x22, 88(sp) 223 | ld x21, 96(sp) 224 | ld x20, 104(sp) 225 | ld x19, 112(sp) 226 | ld x18, 120(sp) 227 | ld x17, 128(sp) 228 | ld x16, 136(sp) 229 | ld x15, 144(sp) 230 | ld x14, 152(sp) 231 | ld x13, 160(sp) 232 | ld x12, 168(sp) 233 | ld x11, 176(sp) 234 | ld x10, 184(sp) 235 | ld x9, 192(sp) 236 | ld x8, 200(sp) 237 | ld x7, 208(sp) 238 | ld x6, 216(sp) 239 | ld x5, 224(sp) 240 | ld x4, 232(sp) 241 | ld x3, 240(sp) 242 | ld x2, 248(sp) 243 | ld x1, 256(sp) 244 | addi sp, sp, 264 245 | 246 | sret 247 | -------------------------------------------------------------------------------- /Lab5/lab5_3180103012/arch/riscv/kernel/sched.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sched.c 3 | * @author Scott Chen 4 | * @brief the scheduler implementation of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | */ 9 | #include "sched.h" 10 | #include "put.h" 11 | #include "rand.h" 12 | #include "syscall.h" 13 | #include "vm.h" 14 | 15 | #define write_csr(reg, val) ({ asm volatile("csrw " #reg ", %0" ::"rK"(val)); }) 16 | #define read_csr(__reg) \ 17 | ({ \ 18 | uint64 __tmp; \ 19 | asm volatile("csrr t0, " #__reg); \ 20 | asm("sd t0, %0" : : "m"(__tmp)); \ 21 | __tmp; \ 22 | }) 23 | 24 | struct task_struct *current; 25 | struct task_struct *task[NR_TASKS]; 26 | 27 | /** 28 | * @brief init tasks, create 4 threads running dead-loop 29 | */ 30 | void task_init(void) { 31 | current = (struct task_struct *)TASK_BASE; 32 | for (int i = 0; i <= LAB_TEST_NUM; i++) { 33 | task[i] = (struct task_struct *)(long)(TASK_BASE + TASK_SIZE * i); 34 | task[i]->state = TASK_RUNNING; 35 | task[i]->counter = i == 0 ? 0 : (PREEMPT_ENABLE ? 8 - i : rand()); 36 | task[i]->priority = 5; 37 | task[i]->blocked = 0; 38 | task[i]->pid = i; 39 | 40 | task[i]->thread.sp = TASK_BASE + TASK_SIZE * (i + 1); 41 | asm("la t0, thread_init"); 42 | asm("sd t0, %0" : : "m"(task[i]->thread.ra)); 43 | 44 | task[i]->sscratch = (size_t)task[i]->thread.sp; 45 | 46 | task[i]->mm.rtpg_addr = user_paging_init(); 47 | 48 | if (i != 0) 49 | #if PREEMPT_ENABLE == 0 // SJF 50 | putf("[PID = %d] Process Create Successfully! counter = %d\n", task[i]->pid, 51 | task[i]->counter); 52 | #else // PRIORITY 53 | putf("[PID = %d] Process Create Successfully! counter = %d priority = %d\n", 54 | task[i]->pid, task[i]->counter, task[i]->priority); 55 | #endif 56 | } 57 | asm("ld t0, %0" : : "m"(task[0]->sscratch)); 58 | asm("csrw sscratch, t0"); 59 | // write_csr(sscratch, task[0]->sscratch); 60 | } 61 | 62 | /** 63 | * @brief called by timer int 64 | */ 65 | void do_timer(void) { 66 | #if PREEMPT_ENABLE == 0 // SJF 67 | // Print thread info for SJF 68 | // putf("[PID = %d] Context Calculation: counter = %d\n", current->pid, current->counter); 69 | 70 | // Decrease counter and schedule 71 | current->counter--; 72 | if (current->counter <= 0) 73 | schedule(); 74 | 75 | #else // PRIORITY 76 | current->counter--; 77 | if (current->counter <= 0) 78 | current->counter = (current->pid == 0) ? 5 : 8 - current->pid; 79 | schedule(); 80 | #endif 81 | } 82 | 83 | /** 84 | * @brief context switch from current to next 85 | * 86 | * @param next 87 | */ 88 | void switch_to(struct task_struct *next) { 89 | if (current == next) 90 | return; 91 | 92 | asm("addi sp, sp, 32"); // Restore the stack of switch_to 93 | CONTEXT_SAVE(current); // Do context save 94 | 95 | asm("csrr t0, sscratch"); 96 | asm("sd t0, %0" : : "m"(current->sscratch)); 97 | // current->sscratch = read_csr(sscratch); 98 | 99 | current = next; // `next` in $s0(-O0), will be overwrite soon 100 | 101 | asm("ld t0, %0" : : "m"(current->sscratch)); 102 | asm("csrw sscratch, t0"); 103 | // write_csr(sscratch, current->sscratch); 104 | 105 | asm("ori t0, zero, 8"); 106 | asm("sll t0, t0, 16"); 107 | asm("ori t0, t0, 0"); 108 | asm("sll t0, t0, 44"); 109 | asm("ld t1, %0" : : "m"(current->mm.rtpg_addr)); 110 | asm("srl t1, t1, 12"); 111 | asm("or t0, t0, t1"); 112 | asm("csrw satp, t0"); 113 | asm("sfence.vma"); 114 | 115 | CONTEXT_LOAD(current); // This `current` is the argv `next` 116 | 117 | asm("ret"); 118 | } 119 | 120 | /** 121 | * @brief schedule implementation 122 | */ 123 | void schedule(void) { 124 | #if PREEMPT_ENABLE == 0 // SJF 125 | int i_min_cnt = LAB_TEST_NUM; // index of min but not zero counter 126 | _Bool all_zeroes = 1; 127 | for (int i = LAB_TEST_NUM; i > 0; i--) 128 | if (task[i]->state == TASK_RUNNING) { 129 | if (task[i]->counter > 0 && task[i]->counter < task[i_min_cnt]->counter || 130 | task[i_min_cnt]->counter == 0) 131 | i_min_cnt = i; 132 | if (task[i]->counter > 0) // In case of negative cnt 133 | all_zeroes = 0; 134 | } 135 | if (all_zeroes) { 136 | for (int i = 1; i <= LAB_TEST_NUM; i++) 137 | if (task[i]->state == TASK_RUNNING) { 138 | task[i]->counter = rand(); 139 | // putf("[PID = %d] Reset counter = %d\n", task[i]->pid, task[i]->counter); 140 | } 141 | schedule(); 142 | } else { 143 | putf("[!] Switch from task %d[%lx] to task %d[%lx], prio: %d, counter: %d\n", 144 | current->pid, (unsigned long)current, task[i_min_cnt]->pid, 145 | (unsigned long)task[i_min_cnt], task[i_min_cnt]->priority, 146 | task[i_min_cnt]->counter); 147 | switch_to(task[i_min_cnt]); 148 | } 149 | 150 | #else // PRIORITY 151 | int max_pri = __INT_MAX__, i_min_cnt = 1; 152 | for (int i = 1; i <= LAB_TEST_NUM; i++) 153 | if (task[i]->state == TASK_RUNNING) 154 | if (task[i]->priority < max_pri) { 155 | i_min_cnt = i; 156 | max_pri = task[i]->priority; 157 | } else if (task[i]->priority == max_pri && 158 | task[i]->counter < task[i_min_cnt]->counter && task[i]->counter > 0) 159 | i_min_cnt = i; 160 | 161 | // Must be printed here to meet demands, else the printed info is out-dated 162 | putf("[!] Switch from task %d[%lx] to task %d[%lx], prio: %d, counter: %d\n", 163 | current->pid, (unsigned long)current, task[i_min_cnt]->pid, 164 | (unsigned long)task[i_min_cnt], task[i_min_cnt]->priority, task[i_min_cnt]->counter); 165 | 166 | // Use another loop to update prio 167 | for (int i = 1; i <= LAB_TEST_NUM; i++) 168 | if (task[i]->state == TASK_RUNNING) 169 | task[i]->priority = rand(); 170 | 171 | // Print all threads' info for PRIORITY 172 | // puts("tasks' priority changed\n"); 173 | for (int i = 1; i <= LAB_TEST_NUM; i++) 174 | if (task[i]->state == TASK_RUNNING) { 175 | // putf("[PID = %d] counter = %d priority = %d\n", task[i]->pid, task[i]->counter, 176 | // task[i]->priority); 177 | } 178 | switch_to(task[i_min_cnt]); 179 | #endif 180 | } 181 | -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/vm.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file vm.c 3 | * @author Scott Chen 4 | * @brief the implementation vm management of oslab4 5 | * @version 0.1 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | * @ref http://www.five-embeddev.com/riscv-isa-manual/latest/supervisor.html#sv32algorithm 9 | */ 10 | #include "vm.h" 11 | #include "put.h" 12 | 13 | #if PAGING_DEBUG 14 | struct free_list_node *free_list_debug; 15 | void print_debug(void) { 16 | puts("\nPrint debug: whatever\n"); 17 | } 18 | #endif 19 | 20 | /** 21 | * @brief Alloc physical memory space for kernel 22 | * 23 | * @param size Memory space, in unit byte 24 | * @return void* Allocated space, NULL for insufficient space 25 | */ 26 | void *kalloc_byte(size_t size) { 27 | static struct free_list_node first_node; 28 | static struct free_list_node *free_list = NULL; 29 | if (free_list == NULL) { // Init 30 | free_list = &first_node; 31 | #if PAGING_DEBUG 32 | free_list_debug = &first_node; 33 | #endif 34 | asm("la t0, rt_pg_addr"); 35 | asm("sd t0, %0" ::"m"(free_list->base)); 36 | free_list->limit = FREE_SPACE_SIZE; 37 | free_list->next = NULL; 38 | } 39 | for (struct free_list_node *p = free_list; p; p = free_list->next) 40 | if (p->limit >= size) { 41 | p->limit -= size; 42 | return (void *)((uint8 *)(p->base = (uint8 *)p->base + size) - size); 43 | } else 44 | return NULL; 45 | } 46 | 47 | /** 48 | * @brief Memory set 49 | * 50 | * @param s Source address 51 | * @param c Char for replacement, of size 1 byte here 52 | * @param n Number of bytes replaced 53 | */ 54 | void memset_byte(void *s, uint8 c, size_t n) { 55 | for (int i = 0; i < n; i++) 56 | *((uint8 *)s + i) = c; 57 | } 58 | 59 | /** 60 | * @brief Page walk from level-2 PT to level-1 PT, and return addr of level-0 PTE 61 | * 62 | * @param pgtbl Addr of 1st(level-2) page table 63 | * @param va VA 64 | * @return uint64* Address of pte of the 3rd(level-0) PTE 65 | */ 66 | uint64 *page_walk(uint64 *pgtbl, uint64 va) { 67 | for (int level = 2; level > 0; level--) { 68 | uint64 *pte_addr; 69 | switch (level) { 70 | case 2: pte_addr = &pgtbl[VAtoVPN2(va)]; break; 71 | case 1: pte_addr = &pgtbl[VAtoVPN1(va)]; break; 72 | } 73 | #if PAGING_DEBUG 74 | puts("\n> in `page_walk`"); 75 | puts("\nlevel: "); 76 | putd(level); 77 | puts("\npgtbl: "); 78 | putx(pgtbl); 79 | puts("\nVPN: "); 80 | putx(VAtoVPN2(va)); 81 | putx(VAtoVPN1(va)); 82 | puts("\npte_addr: "); 83 | putx(pte_addr); 84 | puts("\n*pte_addr: "); 85 | putx(*pte_addr); 86 | puts("\n"); 87 | #endif 88 | // Update `pgtbl` to be next level's pg tbl's base 89 | if (PTEtoV(*pte_addr)) { // Valid PTE, next level PT has been constructed 90 | #if PAGING_DEBUG 91 | puts("Valid PTE\n"); 92 | #endif 93 | pgtbl = (uint64 *)(PTEtoPPN(*pte_addr) << 12); 94 | } else { // Invalid PTE, need to construct next level PT 95 | if ((pgtbl = (uint64 *)kalloc_byte(PAGE_SIZE)) == NULL) { 96 | puts("\n[!] Insufficient Free Space.\n"); 97 | return NULL; // Insufficient free space for pg tbls 98 | } 99 | memset_byte(pgtbl, 0, PAGE_SIZE); 100 | #if PAGING_DEBUG 101 | puts("Invalid PTE"); 102 | puts("\nLeft Space:"); 103 | putx(free_list_debug->limit); 104 | puts("\n"); 105 | #endif 106 | LoadPTE(pte_addr, PAtoPPN((uint64)pgtbl), 0, 1); // PTE <- next level pg's PPN 107 | } 108 | } 109 | #if PAGING_DEBUG 110 | puts("\nPTE addr of level0: "); 111 | putx(&pgtbl[VAtoVPN0(va)]); 112 | #endif 113 | return &pgtbl[VAtoVPN0(va)]; 114 | } 115 | 116 | /** 117 | * @brief Create a mapping object 118 | * 119 | * @param pgtbl Base addr of level-2 page table 120 | * @param va Mapping from 121 | * @param pa Mapping to 122 | * @param sz Mapping size, ceil to PAGE_SIZE 123 | * @param perm Mapping permission: XWR 124 | */ 125 | void create_mapping(uint64 *pgtbl, uint64 va, uint64 pa, uint64 sz, int perm) { 126 | #if PAGING_DEBUG 127 | static int cnt = 0; 128 | puts("\n> In `create_mapping`"); 129 | puts("\ncnt: "); 130 | putd(cnt++); 131 | puts("\n"); 132 | #endif 133 | for (uint64 addr_last_byte = va + sz - 1; va <= addr_last_byte; 134 | va += PAGE_SIZE, pa += PAGE_SIZE) { 135 | #if PAGING_DEBUG 136 | puts("\n> In `create_mapping (Before page walk)`"); 137 | puts("\npgtbl: "); 138 | putx(pgtbl); 139 | puts("\nva: "); 140 | putx(va); 141 | puts("\nVPN2: "); 142 | putx(VAtoVPN2(va)); 143 | puts(", VPN1: "); 144 | putx(VAtoVPN1(va)); 145 | puts(", VPN0: "); 146 | putx(VAtoVPN0(va)); 147 | puts("\npa: "); 148 | putx(pa); 149 | puts("\n"); 150 | #endif 151 | LoadPTE(page_walk(pgtbl, va), PAtoPPN(pa), perm, 1); 152 | #if PAGING_DEBUG 153 | puts("\n> In `create_mapping (After page walk)`"); 154 | puts("\npte_addr: "); 155 | putx(pte_addr); 156 | puts("\nPAtoPPN(pa): "); 157 | putx(PAtoPPN(pa)); 158 | puts("\n*pte_addr: "); 159 | putx(*pte_addr); 160 | puts("\n\n============\n"); 161 | #endif 162 | } 163 | } 164 | 165 | /** 166 | * @brief 将内核起始的0x80000000的16MB映射到0xffffffe000000000,同时也进行等值映射。 167 | * 将必要的硬件地址(如UART)进行等值映射,无偏移。 168 | */ 169 | void paging_init(void) { 170 | uint64 *rtpg_addr = (uint64 *)kalloc_byte(PAGE_SIZE); 171 | // Map UART 172 | create_mapping( 173 | rtpg_addr, (uint64)UART_ADDR, (uint64)UART_ADDR, PAGE_SIZE, PERM_R | PERM_W); 174 | // V Space --> P Space 175 | create_mapping(rtpg_addr, VIR_BASE, PHY_BASE, TEXT_SIZE, PERM_R | PERM_X); // text 176 | create_mapping(rtpg_addr, VIR_BASE + TEXT_SIZE, PHY_BASE + TEXT_SIZE, RODATA_SIZE, 177 | PERM_R); // rodata 178 | create_mapping(rtpg_addr, VIR_BASE + TEXT_SIZE + RODATA_SIZE, 179 | PHY_BASE + TEXT_SIZE + RODATA_SIZE, MAPPING_SIZE - (TEXT_SIZE + RODATA_SIZE), 180 | PERM_R | PERM_W); // Other Sections 181 | // P Space --> P Space 182 | create_mapping(rtpg_addr, PHY_BASE, PHY_BASE, TEXT_SIZE, PERM_R | PERM_X); // text 183 | create_mapping(rtpg_addr, PHY_BASE + TEXT_SIZE, PHY_BASE + TEXT_SIZE, RODATA_SIZE, 184 | PERM_R); // rodata 185 | create_mapping(rtpg_addr, PHY_BASE + TEXT_SIZE + RODATA_SIZE, 186 | PHY_BASE + TEXT_SIZE + RODATA_SIZE, MAPPING_SIZE - (TEXT_SIZE + RODATA_SIZE), 187 | PERM_R | PERM_W); // Other Sections 188 | #if PAGING_DEBUG 189 | puts("\n>> Paging Init Done.\n"); 190 | #endif 191 | } -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/include/vm_flag.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_FLAG_H 2 | #define _VM_FLAG_H 3 | /* 4 | * vm_flags in vm_area_struct, see mm_types.h. 5 | * When changing, update also include/trace/events/mmflags.h 6 | */ 7 | #define VM_NONE 0x00000000 8 | 9 | #define VM_READ 0x00000001 /* currently active flags */ 10 | #define VM_WRITE 0x00000002 11 | #define VM_EXEC 0x00000004 12 | #define VM_SHARED 0x00000008 13 | 14 | /* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */ 15 | #define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */ 16 | #define VM_MAYWRITE 0x00000020 17 | #define VM_MAYEXEC 0x00000040 18 | #define VM_MAYSHARE 0x00000080 19 | 20 | #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ 21 | #define VM_UFFD_MISSING 0x00000200 /* missing pages tracking */ 22 | #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ 23 | #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ 24 | #define VM_UFFD_WP 0x00001000 /* wrprotect pages tracking */ 25 | 26 | #define VM_LOCKED 0x00002000 27 | #define VM_IO 0x00004000 /* Memory mapped I/O or similar */ 28 | 29 | /* Used by sys_madvise() */ 30 | #define VM_SEQ_READ 0x00008000 /* App will access data sequentially */ 31 | #define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */ 32 | 33 | #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ 34 | #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ 35 | #define VM_LOCKONFAULT 0x00080000 /* Lock the pages covered when they are faulted in */ 36 | #define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */ 37 | #define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */ 38 | #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ 39 | #define VM_SYNC 0x00800000 /* Synchronous page faults */ 40 | #define VM_ARCH_1 0x01000000 /* Architecture-specific flag */ 41 | #define VM_WIPEONFORK 0x02000000 /* Wipe VMA contents in child. */ 42 | #define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */ 43 | 44 | #ifdef CONFIG_MEM_SOFT_DIRTY 45 | #define VM_SOFTDIRTY 0x08000000 /* Not soft dirty clean area */ 46 | #else 47 | #define VM_SOFTDIRTY 0 48 | #endif 49 | 50 | #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */ 51 | #define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */ 52 | #define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */ 53 | #define VM_MERGEABLE 0x80000000 /* KSM may merge identical pages */ 54 | 55 | #ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS 56 | #define VM_HIGH_ARCH_BIT_0 32 /* bit only usable on 64-bit architectures */ 57 | #define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */ 58 | #define VM_HIGH_ARCH_BIT_2 34 /* bit only usable on 64-bit architectures */ 59 | #define VM_HIGH_ARCH_BIT_3 35 /* bit only usable on 64-bit architectures */ 60 | #define VM_HIGH_ARCH_BIT_4 36 /* bit only usable on 64-bit architectures */ 61 | #define VM_HIGH_ARCH_0 BIT(VM_HIGH_ARCH_BIT_0) 62 | #define VM_HIGH_ARCH_1 BIT(VM_HIGH_ARCH_BIT_1) 63 | #define VM_HIGH_ARCH_2 BIT(VM_HIGH_ARCH_BIT_2) 64 | #define VM_HIGH_ARCH_3 BIT(VM_HIGH_ARCH_BIT_3) 65 | #define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4) 66 | #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */ 67 | 68 | #ifdef CONFIG_ARCH_HAS_PKEYS 69 | #define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 70 | #define VM_PKEY_BIT0 VM_HIGH_ARCH_0 /* A protection key is a 4-bit value */ 71 | #define VM_PKEY_BIT1 VM_HIGH_ARCH_1 /* on x86 and 5-bit value on ppc64 */ 72 | #define VM_PKEY_BIT2 VM_HIGH_ARCH_2 73 | #define VM_PKEY_BIT3 VM_HIGH_ARCH_3 74 | #ifdef CONFIG_PPC 75 | #define VM_PKEY_BIT4 VM_HIGH_ARCH_4 76 | #else 77 | #define VM_PKEY_BIT4 0 78 | #endif 79 | #endif /* CONFIG_ARCH_HAS_PKEYS */ 80 | 81 | #if defined(CONFIG_X86) 82 | #define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ 83 | #elif defined(CONFIG_PPC) 84 | #define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */ 85 | #elif defined(CONFIG_PARISC) 86 | #define VM_GROWSUP VM_ARCH_1 87 | #elif defined(CONFIG_IA64) 88 | #define VM_GROWSUP VM_ARCH_1 89 | #elif defined(CONFIG_SPARC64) 90 | #define VM_SPARC_ADI VM_ARCH_1 /* Uses ADI tag for access control */ 91 | #define VM_ARCH_CLEAR VM_SPARC_ADI 92 | #elif defined(CONFIG_ARM64) 93 | #define VM_ARM64_BTI VM_ARCH_1 /* BTI guarded page, a.k.a. GP bit */ 94 | #define VM_ARCH_CLEAR VM_ARM64_BTI 95 | #elif !defined(CONFIG_MMU) 96 | #define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */ 97 | #endif 98 | 99 | #if defined(CONFIG_ARM64_MTE) 100 | #define VM_MTE VM_HIGH_ARCH_0 /* Use Tagged memory for access control */ 101 | #define VM_MTE_ALLOWED VM_HIGH_ARCH_1 /* Tagged memory permitted */ 102 | #else 103 | #define VM_MTE VM_NONE 104 | #define VM_MTE_ALLOWED VM_NONE 105 | #endif 106 | 107 | #ifndef VM_GROWSUP 108 | #define VM_GROWSUP VM_NONE 109 | #endif 110 | 111 | /* Bits set in the VMA until the stack is in its final location */ 112 | #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ) 113 | 114 | #define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) 115 | 116 | /* Common data flag combinations */ 117 | #define VM_DATA_FLAGS_TSK_EXEC \ 118 | (VM_READ | VM_WRITE | TASK_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 119 | #define VM_DATA_FLAGS_NON_EXEC (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 120 | #define VM_DATA_FLAGS_EXEC \ 121 | (VM_READ | VM_WRITE | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 122 | 123 | #ifndef VM_DATA_DEFAULT_FLAGS /* arch can override this */ 124 | #define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_EXEC 125 | #endif 126 | 127 | #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ 128 | #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS 129 | #endif 130 | 131 | #ifdef CONFIG_STACK_GROWSUP 132 | #define VM_STACK VM_GROWSUP 133 | #else 134 | #define VM_STACK VM_GROWSDOWN 135 | #endif 136 | 137 | #define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT) 138 | 139 | /* VMA basic access permission flags */ 140 | #define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC) 141 | 142 | /* 143 | * Special vmas that are non-mergable, non-mlock()able. 144 | */ 145 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) 146 | 147 | /* This mask prevents VMA from being scanned with khugepaged */ 148 | #define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB) 149 | 150 | /* This mask defines which mm->def_flags a process can inherit its parent */ 151 | #define VM_INIT_DEF_MASK VM_NOHUGEPAGE 152 | 153 | /* This mask is used to clear all the VMA flags used by mlock */ 154 | #define VM_LOCKED_CLEAR_MASK (~(VM_LOCKED | VM_LOCKONFAULT)) 155 | 156 | /* Arch-specific flags to clear when updating VM flags on protection change */ 157 | #ifndef VM_ARCH_CLEAR 158 | #define VM_ARCH_CLEAR VM_NONE 159 | #endif 160 | #define VM_FLAGS_CLEAR (ARCH_VM_PKEY_FLAGS | VM_ARCH_CLEAR) 161 | 162 | #endif -------------------------------------------------------------------------------- /Lab4/lab4_3180103012/arch/riscv/kernel/entry.S: -------------------------------------------------------------------------------- 1 | .section .text.entry 2 | 3 | .global thread_init 4 | thread_init: 5 | la t0, dead_loop 6 | csrw sepc, t0 7 | sret 8 | 9 | .global trap_m 10 | trap_m: 11 | # Exchange sp and mscratch to use physical stack 12 | csrrw sp, mscratch, sp 13 | 14 | # Save regs 15 | addi sp, sp, -264 16 | sd x1, 256(sp) 17 | sd x2, 248(sp) 18 | sd x3, 240(sp) 19 | sd x4, 232(sp) 20 | sd x5, 224(sp) 21 | sd x6, 216(sp) 22 | sd x7, 208(sp) 23 | sd x8, 200(sp) 24 | sd x9, 192(sp) 25 | sd x10, 184(sp) 26 | sd x11, 176(sp) 27 | sd x12, 168(sp) 28 | sd x13, 160(sp) 29 | sd x14, 152(sp) 30 | sd x15, 144(sp) 31 | sd x16, 136(sp) 32 | sd x17, 128(sp) 33 | sd x18, 120(sp) 34 | sd x19, 112(sp) 35 | sd x20, 104(sp) 36 | sd x21, 96(sp) 37 | sd x22, 88(sp) 38 | sd x23, 80(sp) 39 | sd x24, 72(sp) 40 | sd x25, 64(sp) 41 | sd x26, 56(sp) 42 | sd x27, 48(sp) 43 | sd x28, 40(sp) 44 | sd x29, 32(sp) 45 | sd x30, 24(sp) 46 | sd x31, 16(sp) 47 | csrr s0, mcause 48 | sd s0, 8(sp) 49 | csrr s0, mepc 50 | sd s0, 0(sp) 51 | 52 | # ================================ trap_m starts here ================================ 53 | 54 | csrr s0, mcause 55 | srli s1, s0, 63 # s1 = MSB 56 | andi s0, s0, 0xff # s0 = code 57 | beq s1, zero, trap_m_except 58 | 59 | trap_m_int: 60 | la s1, mcause_i_MTimer 61 | beq s0, s1, trap_m_timer 62 | j trap_m_end 63 | 64 | trap_m_timer: 65 | # enable mip.stip 66 | li s0, 0x20 # mip[5] 67 | csrs mip, s0 # For trap_s 68 | 69 | # clear mie.mtie 70 | li s0, 0x80 71 | csrc mie, s0 72 | 73 | j trap_m_end 74 | 75 | trap_m_except: 76 | la s1, mcause_e_ecallS 77 | beq s0, s1, trap_m_ecallS 78 | j trap_m_except_end 79 | 80 | trap_m_ecallS: 81 | # !!!!!! clear mip.stip !!!!!! 82 | li s0, 0x20 # sip[5] 83 | csrc mip, s0 # Stop from calling trap_s 84 | 85 | # set mtimecmp = mtime + time_sep, hardware will clear mip.mtip 86 | la s0, mtime_addr 87 | ld s0, 0(s0) # s0 = mtime 88 | la s1, time_sep 89 | add s1, s0, s1 # s1 = mtime+sep 90 | la s0, mtimecmp_addr 91 | sd s1, 0(s0) 92 | 93 | # enable mie.mtie 94 | li s0, 0x80 95 | csrs mie, s0 96 | 97 | j trap_m_except_end 98 | 99 | trap_m_except_end: 100 | ld s0, 0(sp) 101 | addi s0, s0, 4 # mepc += 4 102 | sd s0, 0(sp) 103 | 104 | trap_m_end: 105 | 106 | # ================================ trap_m ends here ================================ 107 | 108 | # Get regs back 109 | ld s0, 0(sp) 110 | csrw mepc, s0 111 | ld s0, 8(sp) 112 | csrw mcause, s0 113 | ld x31, 16(sp) 114 | ld x30, 24(sp) 115 | ld x29, 32(sp) 116 | ld x28, 40(sp) 117 | ld x27, 48(sp) 118 | ld x26, 56(sp) 119 | ld x25, 64(sp) 120 | ld x24, 72(sp) 121 | ld x23, 80(sp) 122 | ld x22, 88(sp) 123 | ld x21, 96(sp) 124 | ld x20, 104(sp) 125 | ld x19, 112(sp) 126 | ld x18, 120(sp) 127 | ld x17, 128(sp) 128 | ld x16, 136(sp) 129 | ld x15, 144(sp) 130 | ld x14, 152(sp) 131 | ld x13, 160(sp) 132 | ld x12, 168(sp) 133 | ld x11, 176(sp) 134 | ld x10, 184(sp) 135 | ld x9, 192(sp) 136 | ld x8, 200(sp) 137 | ld x7, 208(sp) 138 | ld x6, 216(sp) 139 | ld x5, 224(sp) 140 | ld x4, 232(sp) 141 | ld x3, 240(sp) 142 | ld x2, 248(sp) 143 | ld x1, 256(sp) 144 | addi sp, sp, 264 145 | # Exchange sp and mscratch to use physical stack 146 | csrrw sp, mscratch, sp 147 | mret 148 | 149 | 150 | .global trap_s 151 | trap_s: 152 | # Save regs 153 | addi sp, sp, -264 154 | sd x1, 256(sp) 155 | sd x2, 248(sp) 156 | sd x3, 240(sp) 157 | sd x4, 232(sp) 158 | sd x5, 224(sp) 159 | sd x6, 216(sp) 160 | sd x7, 208(sp) 161 | sd x8, 200(sp) 162 | sd x9, 192(sp) 163 | sd x10, 184(sp) 164 | sd x11, 176(sp) 165 | sd x12, 168(sp) 166 | sd x13, 160(sp) 167 | sd x14, 152(sp) 168 | sd x15, 144(sp) 169 | sd x16, 136(sp) 170 | sd x17, 128(sp) 171 | sd x18, 120(sp) 172 | sd x19, 112(sp) 173 | sd x20, 104(sp) 174 | sd x21, 96(sp) 175 | sd x22, 88(sp) 176 | sd x23, 80(sp) 177 | sd x24, 72(sp) 178 | sd x25, 64(sp) 179 | sd x26, 56(sp) 180 | sd x27, 48(sp) 181 | sd x28, 40(sp) 182 | sd x29, 32(sp) 183 | sd x30, 24(sp) 184 | sd x31, 16(sp) 185 | csrr s0, scause 186 | sd s0, 8(sp) 187 | csrr s0, sepc 188 | sd s0, 0(sp) 189 | 190 | # ================================ trap_s starts here ================================ 191 | 192 | csrr s0, scause 193 | srli s1, s0, 63 # s1 = MSB 194 | andi s0, s0, 0xff # s0 = code 195 | beq s1, zero, trap_s_except 196 | 197 | trap_s_int: 198 | la s1, scause_i_STimer 199 | beq s0, s1, trap_s_timer 200 | j trap_s_end 201 | 202 | trap_s_timer: 203 | ecall 204 | call do_timer 205 | j trap_s_end 206 | 207 | trap_s_except: 208 | 209 | la s1, scause_e_instPF 210 | beq s0, s1, trap_s_instPF 211 | la s1, scause_e_loadPF 212 | beq s0, s1, trap_s_loadPF 213 | la s1, scause_e_storePF 214 | beq s0, s1, trap_s_storePF 215 | j trap_s_except_end 216 | 217 | trap_s_instPF: 218 | call strap_instPF 219 | j trap_s_except_end 220 | 221 | trap_s_loadPF: 222 | call strap_loadPF 223 | j trap_s_except_end 224 | 225 | trap_s_storePF: 226 | call strap_storePF 227 | j trap_s_except_end 228 | 229 | trap_s_except_end: 230 | ld s0, 0(sp) 231 | addi s0, s0, 4 # sepc += 4 232 | sd s0, 0(sp) 233 | 234 | trap_s_end: 235 | 236 | # ================================ trap_s ends here ================================ 237 | 238 | # Get regs back 239 | ld s0, 0(sp) 240 | csrw sepc, s0 241 | ld s0, 8(sp) 242 | csrw scause, s0 243 | ld x31, 16(sp) 244 | ld x30, 24(sp) 245 | ld x29, 32(sp) 246 | ld x28, 40(sp) 247 | ld x27, 48(sp) 248 | ld x26, 56(sp) 249 | ld x25, 64(sp) 250 | ld x24, 72(sp) 251 | ld x23, 80(sp) 252 | ld x22, 88(sp) 253 | ld x21, 96(sp) 254 | ld x20, 104(sp) 255 | ld x19, 112(sp) 256 | ld x18, 120(sp) 257 | ld x17, 128(sp) 258 | ld x16, 136(sp) 259 | ld x15, 144(sp) 260 | ld x14, 152(sp) 261 | ld x13, 160(sp) 262 | ld x12, 168(sp) 263 | ld x11, 176(sp) 264 | ld x10, 184(sp) 265 | ld x9, 192(sp) 266 | ld x8, 200(sp) 267 | ld x7, 208(sp) 268 | ld x6, 216(sp) 269 | ld x5, 224(sp) 270 | ld x4, 232(sp) 271 | ld x3, 240(sp) 272 | ld x2, 248(sp) 273 | ld x1, 256(sp) 274 | addi sp, sp, 264 275 | 276 | sret 277 | -------------------------------------------------------------------------------- /Lab6/lab6_3180103012/arch/riscv/kernel/sched.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sched.c 3 | * @author Scott Chen 4 | * @brief the scheduler implementation of oslab4 5 | * @version 0.2 6 | * @date 2020-12-05 7 | * @ref https://gitee.com/zjuicsr/lab20fall-stu/wikis/lab4 8 | */ 9 | #include "sched.h" 10 | #include "buddy.h" 11 | #include "mm.h" 12 | #include "rand.h" 13 | #include "slub.h" 14 | #include "stdio.h" 15 | #include "string.h" 16 | #include "syscall.h" 17 | #include "vm.h" 18 | #include "vm_flag.h" 19 | 20 | struct task_struct *current; 21 | struct task_struct *task[NR_TASKS]; 22 | 23 | /** 24 | * @brief init tasks, create 4 threads running dead-loop 25 | */ 26 | void task_init(void) { 27 | current = (struct task_struct *)TASK_BASE; 28 | 29 | static struct mm_struct mm_tmp[LAB_TEST_NUM]; // Static for thread to use 30 | 31 | slub_init(); 32 | 33 | uint64 *k_rtpg; 34 | asm("la t0, kernel_rt_pg_addr"); 35 | asm("sd t0, %0" : : "m"(k_rtpg)); 36 | 37 | for (int i = 0; i <= LAB_TEST_NUM; i++) { 38 | task[i] = (struct task_struct *)(long)(TASK_BASE + TASK_SIZE * i); 39 | task[i]->state = TASK_RUNNING; 40 | task[i]->counter = i == 0 ? 0 : (PREEMPT_ENABLE ? 8 - i : rand()); 41 | task[i]->priority = 5; 42 | task[i]->blocked = 0; 43 | task[i]->pid = i; 44 | 45 | task[i]->thread.sp = TASK_BASE + TASK_SIZE * (i + 1); 46 | asm("la t0, thread_init"); 47 | asm("sd t0, %0" : : "m"(task[i]->thread.ra)); 48 | 49 | task[i]->sscratch = (size_t)task[i]->thread.sp; 50 | 51 | task[i]->mm = &mm_tmp[i]; 52 | task[i]->mm->vm_area_list = NULL; 53 | 54 | // task[i]->mm->rtpg_addr = user_paging_init(); 55 | // task[i]->mm->rtpg_addr = (uint64 *)VA2PA(alloc_pages(1)); 56 | task[i]->mm->rtpg_addr = (uint64 *)VA2PA(kmalloc(PAGE_SIZE)); 57 | 58 | memcpy(task[i]->mm->rtpg_addr, k_rtpg, PAGE_SIZE); 59 | 60 | // create_mapping(task[i]->mm->rtpg_addr, 0, USER_PHY_ENTRY, USER_MAPPING_SIZE, 61 | // PROT_U | PERM_R | PERM_W | PERM_X); 62 | do_mmap(task[i]->mm, 0, USER_MAPPING_SIZE, VM_READ | VM_WRITE | VM_EXEC, 63 | MAP_PRIVATE | MAP_ANONYMOUS, 0); 64 | do_mmap(task[i]->mm, USER_STACK_TOP - USER_MAPPING_SIZE, USER_MAPPING_SIZE, 65 | VM_READ | VM_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); 66 | 67 | if (i != 0) 68 | #if PREEMPT_ENABLE == 0 // SJF 69 | printf("[PID = %d] Process Create Successfully! counter = %d\n", task[i]->pid, 70 | task[i]->counter); 71 | #else // PRIORITY 72 | printf("[PID = %d] Process Create Successfully! counter = %d priority = %d\n", 73 | task[i]->pid, task[i]->counter, task[i]->priority); 74 | #endif 75 | } 76 | asm("ld t0, %0" : : "m"(task[0]->sscratch)); 77 | asm("csrw sscratch, t0"); 78 | } 79 | 80 | /** 81 | * @brief called by timer int 82 | */ 83 | void do_timer(void) { 84 | #if PREEMPT_ENABLE == 0 // SJF 85 | // Print thread info for SJF 86 | // printf("[PID = %d] Context Calculation: counter = %d\n", current->pid, 87 | // current->counter); 88 | 89 | // Decrease counter and schedule 90 | current->counter--; 91 | if (current->counter <= 0) 92 | schedule(); 93 | 94 | #else // PRIORITY 95 | current->counter--; 96 | if (current->counter <= 0) 97 | current->counter = (current->pid == 0) ? 5 : 8 - current->pid; 98 | schedule(); 99 | #endif 100 | } 101 | 102 | /** 103 | * @brief context switch from current to next 104 | * 105 | * @param next 106 | */ 107 | void switch_to(struct task_struct *next) { 108 | if (current == next) 109 | return; 110 | 111 | asm("addi sp, sp, 32"); // Restore the stack of switch_to 112 | CONTEXT_SAVE(current); // Do context save 113 | 114 | asm("csrr t0, sscratch"); 115 | asm("sd t0, %0" : : "m"(current->sscratch)); 116 | 117 | current = next; // `next` in $s0(-O0), will be overwrite soon 118 | 119 | asm("ld t0, %0" : : "m"(current->sscratch)); 120 | asm("csrw sscratch, t0"); 121 | 122 | asm("ori t0, zero, 8"); 123 | asm("sll t0, t0, 16"); 124 | asm("ori t0, t0, 0"); 125 | asm("sll t0, t0, 44"); 126 | asm("ld t1, %0" : : "m"(current->mm->rtpg_addr)); 127 | asm("srl t1, t1, 12"); 128 | asm("or t0, t0, t1"); 129 | asm("csrw satp, t0"); 130 | asm("sfence.vma"); 131 | 132 | CONTEXT_LOAD(current); // This `current` is the argv `next` 133 | 134 | asm("ret"); 135 | } 136 | 137 | /** 138 | * @brief schedule implementation 139 | */ 140 | void schedule(void) { 141 | #if PREEMPT_ENABLE == 0 // SJF 142 | int i_min_cnt = LAB_TEST_NUM; // index of min but not zero counter 143 | _Bool all_zeroes = 1; 144 | for (int i = LAB_TEST_NUM; i > 0; i--) 145 | if (task[i]->state == TASK_RUNNING) { 146 | if (task[i]->counter > 0 && task[i]->counter < task[i_min_cnt]->counter || 147 | task[i_min_cnt]->counter == 0) 148 | i_min_cnt = i; 149 | if (task[i]->counter > 0) // In case of negative cnt 150 | all_zeroes = 0; 151 | } 152 | if (all_zeroes) { 153 | for (int i = 1; i <= LAB_TEST_NUM; i++) 154 | if (task[i]->state == TASK_RUNNING) { 155 | task[i]->counter = rand(); 156 | // printf("[PID = %d] Reset counter = %d\n", task[i]->pid, task[i]->counter); 157 | } 158 | schedule(); 159 | } else { 160 | printf("[!] Switch from task %d[%lx] to task %d[%lx], prio: %d, counter: %d\n", 161 | current->pid, (unsigned long)current, task[i_min_cnt]->pid, 162 | (unsigned long)task[i_min_cnt], task[i_min_cnt]->priority, 163 | task[i_min_cnt]->counter); 164 | switch_to(task[i_min_cnt]); 165 | } 166 | 167 | #else // PRIORITY 168 | int max_pri = __INT_MAX__, i_min_cnt = 1; 169 | for (int i = 1; i <= LAB_TEST_NUM; i++) 170 | if (task[i]->state == TASK_RUNNING) 171 | if (task[i]->priority < max_pri) { 172 | i_min_cnt = i; 173 | max_pri = task[i]->priority; 174 | } else if (task[i]->priority == max_pri && 175 | task[i]->counter < task[i_min_cnt]->counter && task[i]->counter > 0) 176 | i_min_cnt = i; 177 | 178 | // Must be printed here to meet demands, else the printed info is out-dated 179 | printf("[!] Switch from task %d[%lx] to task %d[%lx], prio: %d, counter: %d\n", 180 | current->pid, (unsigned long)current, task[i_min_cnt]->pid, 181 | (unsigned long)task[i_min_cnt], task[i_min_cnt]->priority, task[i_min_cnt]->counter); 182 | 183 | // Use another loop to update prio 184 | for (int i = 1; i <= LAB_TEST_NUM; i++) 185 | if (task[i]->state == TASK_RUNNING) 186 | task[i]->priority = rand(); 187 | 188 | // Print all threads' info for PRIORITY 189 | // puts("tasks' priority changed\n"); 190 | for (int i = 1; i <= LAB_TEST_NUM; i++) 191 | if (task[i]->state == TASK_RUNNING) { 192 | // printf("[PID = %d] counter = %d priority = %d\n", task[i]->pid, 193 | // task[i]->counter, task[i]->priority); 194 | } 195 | switch_to(task[i_min_cnt]); 196 | #endif 197 | } 198 | --------------------------------------------------------------------------------