diff --git a/.clang-format b/.clang-format index fe894e980847c0f3d02a12810ede23c8da586f9d..738b35547cd682c6775ec2e219500f63c9fc4822 100644 --- a/.clang-format +++ b/.clang-format @@ -12,10 +12,11 @@ AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Never +AllowShortBlocksOnASingleLine: Empty AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortLambdasOnASingleLine: All +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortLambdasOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None @@ -84,6 +85,7 @@ IndentGotoLabels: true IndentPPDirectives: None IndentWidth: 4 IndentWrappedFunctionNames: false +InsertBraces: true JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: true diff --git a/.gitignore b/.gitignore index b1d35f9e4a7e8f2106e5ac28a9c2578d014f5e13..798579adcad77570b3f973f66b1b1825790015ba 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ !Makefile !Makefile.in !Dockerfile +!compile_commands.json !*.S !*.s diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Makefile b/Makefile index d5ffdfba87f0f2f7d61b165d633655f9403f76ff..26c98d26ef80e83caec009b42a53d979b6572897 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,8 @@ dst := /mnt fs_img := sdcard.img modules := $(src_dir) -objects := $(shell find $(src_dir) -name "*.o") +sources := $(shell find $(src_dir) \( -name "*.S" -o -name "*.c" \)) +objects := $(patsubst %.S,%.o, $(patsubst %.c,%.o, $(sources))) .PHONY: build clean $(modules) run GDB := n @@ -21,7 +22,7 @@ ifeq ($(MAKECMDGOALS), gdb) GDB = y endif -all : clean build +all: clean build build: $(modules) mkdir -p $(target_dir) diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000000000000000000000000000000000000..3e32e9e3f328e3e210ed5662a603ce3703590d97 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,694 @@ +[ + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "exception.S" + ], + "file": "exception.S" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "head.S" + ], + "file": "head.S" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "stack.c" + ], + "file": "stack.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "vm.c" + ], + "file": "vm.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "context.S" + ], + "file": "context.S" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../../include", + "-I../../include", + "-c", + "smp.S" + ], + "file": "smp.S" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/sbi", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../include", + "-I../include", + "-c", + "common.c" + ], + "file": "common.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/syscall", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../../include", + "-I../include", + "-c", + "syscall.c" + ], + "file": "syscall.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/drivers", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I..", + "-I../include", + "-I../arch/riscv/include", + "-c", + "screen.c" + ], + "file": "screen.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/fs", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "fs.c" + ], + "file": "fs.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "main.c" + ], + "file": "main.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/init", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "vm.c" + ], + "file": "vm.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/irq", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "irq.c" + ], + "file": "irq.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/mm", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "ioremap.c" + ], + "file": "ioremap.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/mm", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "mm.c" + ], + "file": "mm.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sync", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "lock.c" + ], + "file": "lock.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sync", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "sync.c" + ], + "file": "sync.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "info.c" + ], + "file": "info.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "pcb.c" + ], + "file": "pcb.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "smp.c" + ], + "file": "smp.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../../include", + "-I../../arch/riscv/include", + "-I../../", + "-c", + "time.c" + ], + "file": "time.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/libs", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "printk.c" + ], + "file": "printk.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/libs", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "string.c" + ], + "file": "string.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/user", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "payload.c" + ], + "file": "payload.c" + }, + { + "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/user", + "arguments": [ + "riscv64-unknown-elf-gcc", + "-Wall", + "-Werror", + "-O", + "-fno-omit-frame-pointer", + "-ggdb", + "-g", + "-march=rv64g", + "-mabi=lp64f", + "-MD", + "-mcmodel=medany", + "-ffreestanding", + "-fno-common", + "-nostdlib", + "-mno-relax", + "-I.", + "-fno-stack-protector", + "-I../include", + "-I../arch/riscv/include", + "-I../", + "-c", + "user_programs.c" + ], + "file": "user_programs.c" + } +] diff --git a/docs/development.md b/docs/development.md index c1bc6bc4ac2ef831257d1aaced5696b2f2643d96..ca1bfe6472b495bc1f80c888a2aa7ddb3775e93b 100644 --- a/docs/development.md +++ b/docs/development.md @@ -8,7 +8,7 @@ æºæ–‡ä»¶å‘½å采用lower_case_with_underscores -å¼€å‘完æˆåŽä¸€å®šè¦åœ¨ä½¿ç”¨`./script/format.sh`æ¥æ ¼å¼åŒ–代ç (注æ„ä¸è¦ç”¨clang formatæ ¼å¼åŒ–`.h, .S`的代ç ),本项目coding style基于llvm clang-formatåšäº†ä¸€äº›è°ƒæ•´ã€‚ +å¼€å‘完æˆåŽä¸€å®šè¦åœ¨ä½¿ç”¨`./script/format.sh`æ¥æ ¼å¼åŒ–代ç (注æ„ä¸è¦ç”¨clang formatæ ¼å¼åŒ–`.h, .S`的代ç ),本项目coding style基于llvm clang-formatåšäº†ä¸€äº›è°ƒæ•´ã€‚注æ„使用`clang-format 15`以上的版本,å¯ä»¥æŒ‰ç…§`./script/setup.sh`è¿è¡Œã€‚ 全局å˜é‡å¤´æ–‡ä»¶é‡Œéƒ½ç”¨`extern`,在`.c`ä¸å®šä¹‰ï¼›å…¶ä½™éœ€è¦å…±äº«çš„`#define`直接写,ä¸ç”¨å‰ç¼€ï¼›ç±»åž‹å£°æ˜Žã€å‡½æ•°ç‰åªèƒ½å£°æ˜Žä¸€æ¬¡ï¼Œåœ¨å…¶ä½™å¤´æ–‡ä»¶ä¸ä½¿ç”¨`extern`。 @@ -32,7 +32,7 @@ - `typedef` - `typedef struct` - `extern` -- 函数按照ä¾èµ–æ¬¡åºæŽ’åˆ—ï¼ŒåŒç±»å‡½æ•°æ”¾åœ¨ä¸€èµ· +- 函数按照ä¾èµ–æ¬¡åºæŽ’åˆ—ï¼ŒåŒç±»å‡½æ•°æ”¾åœ¨ä¸€èµ·ï¼Œ`.c`文件的实现ä¸å‡½æ•°ä¸Žå¤´æ–‡ä»¶ä¸å‡½æ•°é¡ºåºä¸€è‡´ 系统调用全部使用`sys_`开头lower_case_with_underscores,系统调用å·ä½¿ç”¨`SYS_`åŽé¢æ˜¯lower_case_with_underscores。系统调用在å„ä¸ªåæ¨¡å—头文件ä¸å®žçŽ°ï¼Œè€ŒåŽå°†å¤´æ–‡ä»¶åŠ å…¥./src/os/syscall.h。 @@ -53,12 +53,20 @@ func_name_out: } ``` +å‡½æ•°å‘½åæ¨¡æ¿ï¼š + +- 系统调用全部使用`long sys_xxx(args)`的命åå½¢å¼ï¼Œå¼€å§‹ä¸€å®šè¦è¿›è¡Œå‚数检查,指针一定是用户地å€ç©ºé—´ã€‚ +- å†…æ ¸å†…äº’ç›¸è°ƒç”¨çš„å‡½æ•°ï¼Œå³åœ¨å¤´æ–‡ä»¶ä¸åƒå†…æ ¸å…¶ä»–æ¨¡å—æš´éœ²çš„函数全部以`k_`开头,效率起è§å¯ä¸åšå‚æ•°æ£€æŸ¥ï¼Œå‚æ•°å¯å…¼å®¹ç”¨æˆ·æ€å’Œå†…æ ¸æ€åœ°å€ã€‚ +- 其余函数ä¸è¦æ”¾åœ¨å¤´æ–‡ä»¶ä¸ï¼Œåœ¨å‡½æ•°å†…定义,使用`static`ä¿è¯å®‰å…¨ï¼Œå¼€å¤´ä¸èƒ½æ˜¯`k_`å’Œ`sys_` + +函数实现ä¸å°½é‡æå–å¤šä¸ªç±»ä¼¼å‡½æ•°çš„å…±åŒæ“作组æˆ`static`函数公用,å‡å°‘代ç é‡ã€‚ + +å†…æ ¸ä¸å…±äº«çš„å˜é‡å’Œç±»åž‹å®šä¹‰æœ€å¥½ä¹Ÿä½¿ç”¨`k_`å¼€å¤´å®šä¹‰ï¼Œå¦‚æžœå‡½æ•°æœ‰æžšä¸¾ä½œç”¨çš„å‚æ•°åªåœ¨å†…æ ¸æ€èŒƒå›´äº¤æ¢åˆ™ä½¿ç”¨`enum`,如果是用户æ€ä¼ 入则使用其他`int`或`long`类型。 + ## 编译 使用`./script/build.sh`æ¥ç¼–译 -有时候需è¦é‡å¤è¿è¡Œä¸¤æ¬¡ï¼Œå› 为文件åªèƒ½ä¸€æ¬¡é‡‡æ ·ï¼Œä¸å¥½åЍæ€èµ‹å€¼ç»™Makefileå˜é‡ - ## è¿è¡ŒQEMU 使用`./script/qemu_run.sh`æ¥è¿è¡Œ diff --git a/kernel-qemu b/kernel-qemu index dbeddc76352fa33314cbee6b99d30758e99a5820..0889007e912ba1e8d88651387209e63a443d5e40 100755 --- a/kernel-qemu +++ b/kernel-qemu @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04166f8722a87c2749cbb25f9a7f2c46f03867f88726245214756c92263abfc1 -size 1502872 +oid sha256:236f6d777344e58eca173840c83333e5f4242545faf95447760a4f75d7a777a9 +size 1539688 diff --git a/scripts/format.sh b/scripts/format.sh index d4dc099373e91d1c4d26e784b946ac1cb5e35323..34b8afccc2a413454b695579d142874c1e2ac838 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -1 +1 @@ -find src -regex '.*\.\(cpp\|hpp\|cu\|c\)' -exec clang-format -style=file -i {} \; \ No newline at end of file +find src -regex '.*\.\(cpp\|hpp\|cu\|c\)' -exec clang-format-17 -style=file -i {} \; \ No newline at end of file diff --git a/scripts/setup.sh b/scripts/setup.sh index 15e17b0412d1619f192df0cfb88273de0e052c48..687ffa5a7d9877283659a58fda3cb41d17ecb218 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -21,9 +21,11 @@ echo "REPO = $REPO" echo "RISCV_DIR = $RISCV_DIR" echo "QEMU_DIR = $QEMU_DIR" echo "=== Install dependencies ===" +wget https://apt.llvm.org/llvm-snapshot.gpg.key if [[ "$use_sudo_opt" = "y" ]] then - sudo apt update && \ + sudo apt-key add llvm-snapshot.gpg.key + sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main' sudo apt install -y apt-transport-https ca-certificates && \ sudo update-ca-certificates sudo sed -i s@/archive.ubuntu.com/@/mirrors.tuna.tsinghua.edu.cn/@g /etc/apt/sources.list @@ -33,14 +35,15 @@ then gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \ libpixman-1-0 git python3 python3-pip make curl \ sshpass openssh-client clang-10 libtinfo5 libc6-dev-i386 \ - libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev + libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev clang-format-17 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs git lfs install pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip3 install pytz Cython jwt jinja2 requests else - apt update && \ + sudo apt-key add llvm-snapshot.gpg.key + sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main' apt install -y apt-transport-https ca-certificates && \ update-ca-certificates sed -i s@/archive.ubuntu.com/@/mirrors.tuna.tsinghua.edu.cn/@g /etc/apt/sources.list @@ -50,13 +53,14 @@ else gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \ libpixman-1-0 git python3 python3-pip make curl \ sshpass openssh-client clang-10 libtinfo5 libc6-dev-i386 \ - libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev + libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev clang-format-17 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash apt-get install git-lfs git lfs install pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip3 install pytz Cython jwt jinja2 requests fi +rm llvm-snapshot.gpg.key echo "=== Clone Repository ===" test -d env || mkdir env diff --git a/src/arch/riscv/include/asm/context.h b/src/arch/riscv/include/asm/context.h index 92cdc2e5e5da4d8a429490299a99f20c4a8cf392..1bc4771d1f0e51bca81d1697cc0f47e331a6297d 100644 --- a/src/arch/riscv/include/asm/context.h +++ b/src/arch/riscv/include/asm/context.h @@ -12,6 +12,7 @@ typedef struct regs_context { reg_t sepc; reg_t sbadaddr; reg_t scause; + reg_t sscratch; } regs_context_t; /* used to save register infomation in switch_to */ diff --git a/src/arch/riscv/include/asm/csr.h b/src/arch/riscv/include/asm/csr.h index 16edd2f06c15c9ea8d535da448b63be2bd044753..830460a0c44d224823c81dd66edaf83a7fd623e5 100644 --- a/src/arch/riscv/include/asm/csr.h +++ b/src/arch/riscv/include/asm/csr.h @@ -75,3 +75,6 @@ #define CSR_INSTRETH 0xc82 #define CSR_MHARTID 0xf14 + +#define BOOT_STACK_MASTER 0x80600000 +#define BOOT_STACK_SLAVE 0x805ff000 \ No newline at end of file diff --git a/src/arch/riscv/include/asm/regs.h b/src/arch/riscv/include/asm/regs.h index b9f3db666e08eb980ab1ad10db0003bc5c9554b8..8325a001d492356f102cdeb06babed6c8c4a94d5 100644 --- a/src/arch/riscv/include/asm/regs.h +++ b/src/arch/riscv/include/asm/regs.h @@ -53,13 +53,13 @@ #define OFFSET_REG_SEPC 256 #define OFFSET_REG_SBADADDR 264 #define OFFSET_REG_SCAUSE 272 +#define OFFSET_REG_SSCRATCH 280 /* Size of stack frame, word/double word alignment */ -#define OFFSET_SIZE 280 +#define OFFSET_SIZE 288 #define PCB_KERNEL_SP 0 #define PCB_USER_SP 8 -#define PCB_PREEMPT_COUNT 16 /* offset in switch_to */ #define SS(x,y) sd x,SWITCH_TO_##y##(t0) diff --git a/src/arch/riscv/include/asm/stack.h b/src/arch/riscv/include/asm/stack.h index 0c37373bb58e3f495a75c6252cf739d6cad92120..0d7eb17903700aee4f21571436cf47ad1ef643e6 100644 --- a/src/arch/riscv/include/asm/stack.h +++ b/src/arch/riscv/include/asm/stack.h @@ -5,6 +5,8 @@ ptr_t get_kernel_address(pid_t pid); -void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb, uint64_t argc, char **argv); +void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb); -void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb); \ No newline at end of file +void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb); + +void clone_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb, unsigned long flags, void *tls); \ No newline at end of file diff --git a/src/arch/riscv/kernel/init/exception.S b/src/arch/riscv/kernel/init/exception.S index e010d37177b41660bc5c52e0ef6df00ea263c3c5..c8c273d616e200896e3a6cb01e52a273b79628ce 100644 --- a/src/arch/riscv/kernel/init/exception.S +++ b/src/arch/riscv/kernel/init/exception.S @@ -22,7 +22,7 @@ ENTRY(setup_exception) CORE2_EXCEP: la t0, exception_handler_entry csrw CSR_STVEC, t0 - li t0, 0x222 + li t0, SIE_STIE csrw CSR_SIE, t0 li t0, SR_SIE csrw CSR_SSTATUS, t0 diff --git a/src/arch/riscv/kernel/init/head.S b/src/arch/riscv/kernel/init/head.S index eab96cab100d94843ab8e383e250670009ed1e57..90870ad76d530ee80d02fd4ad199514ae195eedd 100644 --- a/src/arch/riscv/kernel/init/head.S +++ b/src/arch/riscv/kernel/init/head.S @@ -26,7 +26,7 @@ ENTRY(_start) .option pop csrr t0, CSR_MHARTID - bnez t0, CORE2 + bnez t0, slave //these instructions will modify memory /* Clear BSS for flat non-ELF images */ @@ -39,22 +39,25 @@ clear_bss: blt a3, a4, clear_bss clear_bss_done: - //la a0, riscv_dtb - //sd a1, (a0) -//for boot_kernel? + // core 0 +master: + li sp, BOOT_STACK_MASTER csrr a0, CSR_MHARTID -// - //la tp, pid0_pcb - li sp, 0x50202000 - call prepare_vm - //j loop -CORE2: -//for boot_kernel? - csrr a0, CSR_MHARTID -// - //la tp, pid0_pcb2 - li sp, 0x50203000 call prepare_vm +slave: + /* Mark all interrupt */ + li t0, SR_FS + csrc sstatus, t0 + /* Set stvec to kernel entry */ + csrw CSR_SSCRATCH, t0 + la t0, prepare_vm + csrw CSR_STVEC, t0 + /* Enable supervisor software interrupt (ipi) */ + li t0, SIE_SSIE + csrw CSR_SIE, t0 + li t0, SR_SIE + csrw CSR_SSTATUS, t0 + li sp, BOOT_STACK_SLAVE loop: wfi diff --git a/src/arch/riscv/kernel/init/stack.c b/src/arch/riscv/kernel/init/stack.c index 4929a3e8c5772fc4d0fc9528a7c1cf7655c16e03..405e8ca4b5b8d1a5079b3574895e9d83e36aacd7 100644 --- a/src/arch/riscv/kernel/init/stack.c +++ b/src/arch/riscv/kernel/init/stack.c @@ -1,6 +1,9 @@ +#include <asm/csr.h> #include <asm/pgtable.h> #include <asm/stack.h> #include <lib/stdio.h> +#include <lib/string.h> +#include <os/mm.h> #include <os/smp.h> extern void ret_from_exception(); @@ -8,75 +11,56 @@ extern void __global_pointer$(); ptr_t address_base = 0xffffffc050504000lu; -ptr_t get_kernel_address(pid_t pid) { return address_base + (pid + 1) * 0x2000; } +ptr_t get_kernel_address(pid_t pid) { + return address_base + (pid + 1) * 2 * PAGE_SIZE; +} -ptr_t get_user_address(pid_t pid) { return address_base + pid * 0x2000 + 0x1000; } +ptr_t get_user_address(pid_t pid) { + return address_base + pid * 2 * PAGE_SIZE + PAGE_SIZE; +} -void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb, uint64_t argc, char **argv) { +void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb) { regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t)); - uint64_t user_stack_kva = kernel_stack - 0x1000; - for (int i = 5; i < 32; i++) - pt_regs->regs[i] = 0; - if (argv != NULL) { - char **u_argv = (char **)(user_stack_kva - 100); - for (int i = 0; i < argc; i++) { - char *s = (char *)(user_stack_kva - 100 - 20 * (i + 1)); - char *t = argv[i]; - int j = 0; - for (j = 0; t[j] != '\0'; j++) - s[j] = t[j]; - s[j] = '\0'; - u_argv[i] = (char *)(user_stack - 100 - 20 * (i + 1)); - // prints("%x\n",u_argv[i]); - } - pcb->user_sp = user_stack - 256; - // prints("sp:%x\n", pcb->user_sp); - pt_regs->regs[11] = user_stack - 100; - } else - pcb->user_sp = user_stack; + k_memset(pt_regs, 0, sizeof(regs_context_t)); pcb->kernel_sp = kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t); + pcb->user_sp = user_stack; pt_regs->regs[0] = 0; pt_regs->regs[1] = entry_point; pt_regs->regs[2] = pcb->user_sp; - if (pcb->type == USER_PROCESS) + if (pcb->type == USER_PROCESS) { pt_regs->regs[3] = (reg_t)__global_pointer$; - else if (pcb->type == USER_THREAD) { + } else if (pcb->type == USER_THREAD) { regs_context_t *cur_regs = (regs_context_t *)((*current_running)->kernel_sp + sizeof(switchto_context_t)); pt_regs->regs[3] = cur_regs->regs[3]; } pt_regs->regs[4] = (reg_t)pcb; - pt_regs->regs[10] = argc; pt_regs->sepc = entry_point; - pt_regs->sstatus = 0x40020; + pt_regs->sstatus = SR_SUM | SR_FS; pt_regs->sbadaddr = 0; pt_regs->scause = 0; + pt_regs->sscratch = (reg_t)pcb; switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t)); - sw_regs->regs[0] = (reg_t)ret_from_exception; - // sw_regs->regs[1] = pcb->user_sp; + sw_regs->regs[0] = (pcb->type == USER_PROCESS || pcb->type == USER_THREAD) ? (reg_t)&ret_from_exception : entry_point; + sw_regs->regs[1] = pcb->kernel_sp; + pcb->save_context = pt_regs; + pcb->switch_context = sw_regs; } void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb) { regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t)); regs_context_t *cur_regs = (regs_context_t *)((*current_running)->kernel_sp + sizeof(switchto_context_t)); ptr_t cur_address = get_user_address((*current_running)->pid); - ptr_t off = 0x1000 - 1; - char *p = (char *)(user_stack - 1); - char *q = (char *)(cur_address - 1); - // i is unsigned - // printk("here1\n"); - for (ptr_t i = off + 1; i > 0; i--) { - *p = *q; - p--; - q--; - } - pcb->user_sp = (*current_running)->user_sp; + k_memcpy((uint8_t *)(user_stack - PAGE_SIZE), (uint8_t *)(cur_address - PAGE_SIZE), PAGE_SIZE - 1); pcb->kernel_sp = kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t); - for (int i = 0; i < 32; i++) + pcb->user_sp = (*current_running)->user_sp; + + for (int i = 0; i < 32; i++) { pt_regs->regs[i] = cur_regs->regs[i]; + } // tp - pt_regs->regs[4] = (reg_t)pcb; pt_regs->regs[2] = pcb->user_sp; + pt_regs->regs[4] = (reg_t)pcb; // a0 pt_regs->regs[10] = 0; // pt_regs->regs[8] = user_stack; @@ -84,7 +68,27 @@ void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb) { pt_regs->sstatus = cur_regs->sstatus; pt_regs->sbadaddr = cur_regs->sbadaddr; pt_regs->scause = cur_regs->scause; + pt_regs->sscratch = (reg_t)pcb; + switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t)); sw_regs->regs[0] = (reg_t)ret_from_exception; // sw_regs->regs[1] = pcb->user_sp; + pcb->save_context = pt_regs; + pcb->switch_context = sw_regs; +} + +void clone_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb, unsigned long flags, void *tls) { + regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t)); + switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t)); + pcb->save_context = pt_regs; + pcb->switch_context = sw_regs; + pcb->kernel_sp = (uintptr_t)pcb->switch_context; + pcb->switch_context->regs[0] = (reg_t)&ret_from_exception; + pcb->switch_context->regs[1] = pcb->kernel_sp; + pcb->save_context->regs[2] = user_stack == USER_STACK_ADDR ? (*current_running)->save_context->regs[2] : user_stack; + if (flags & CLONE_SETTLS) { + pcb->save_context->regs[4] = (reg_t)tls; + } + pcb->save_context->regs[10] = 0; + pcb->save_context->sscratch = (reg_t)pcb; } \ No newline at end of file diff --git a/src/arch/riscv/kernel/sys/context.S b/src/arch/riscv/kernel/sys/context.S index 0ad984d9952fb04983111dd60e736a4d2b998e90..e24d326a00213d7a248f94d8793155e3c5719b03 100644 --- a/src/arch/riscv/kernel/sys/context.S +++ b/src/arch/riscv/kernel/sys/context.S @@ -19,6 +19,7 @@ _save_context: sd sp, PCB_USER_SP(tp) ld sp, PCB_KERNEL_SP(tp) + csrrw tp, CSR_SSCRATCH, tp addi sp, sp, SWITCH_TO_SIZE /* TODO: save all general purpose registers here! */ @@ -58,6 +59,8 @@ _save_context: SAVE(a0,SEPC) csrr a0, CSR_SCAUSE SAVE(a0,SCAUSE) + csrr a0, CSR_SSCRATCH + SAVE(a0,SSCRATCH) ld a0, PCB_USER_SP(tp) SAVE(a0,SP) /* @@ -70,11 +73,20 @@ _save_context: li t0, SR_SUM | SR_FS //addi sp, sp, -(SWITCH_TO_SIZE) /* TODO: save sstatus, sepc, stval, scause and sscratch on user stack */ + csrrw tp, CSR_SSCRATCH, tp + ld sp, PCB_KERNEL_SP(tp) .endm .macro RESTORE_CONTEXT ld sp, PCB_KERNEL_SP(tp) addi sp, sp, SWITCH_TO_SIZE + LOAD(s0,SSTATUS) + csrw CSR_SSTATUS, s0 + LOAD(s0,SEPC) + csrw CSR_SEPC, s0 + LOAD(s0, SSCRATCH) + csrw CSR_SSCRATCH, s0 + csrrw tp, CSR_SSCRATCH, tp LOAD(ra,RA) LOAD(gp,GP) LOAD(tp,TP) @@ -105,10 +117,6 @@ _save_context: LOAD(t4,T4) LOAD(t5,T5) LOAD(t6,T6) - LOAD(s0,SSTATUS) - csrw CSR_SSTATUS, s0 - LOAD(s0,SEPC) - csrw CSR_SEPC, s0 LOAD(s0,S0) LOAD(sp,SP) fence @@ -121,27 +129,10 @@ _save_context: ENTRY(enable_preempt) jr ra - ld t1, current_running0 - ld t0, PCB_PREEMPT_COUNT(t1) - beq t0, zero, do_enable - addi t0, t0, -1 - sd t0, PCB_PREEMPT_COUNT(t1) - beq t0, zero, do_enable - jr ra -do_enable: - not t0, x0 - csrs CSR_SIE, t0 - jr ra ENDPROC(enable_preempt) ENTRY(disable_preempt) jr ra - csrw CSR_SIE, zero - ld t1, current_running0 - ld t0, PCB_PREEMPT_COUNT(t1) - addi t0, t0, 1 - sd t0, PCB_PREEMPT_COUNT(t1) - jr ra ENDPROC(disable_preempt) ENTRY(enable_interrupt) diff --git a/src/arch/riscv/sbi/common.c b/src/arch/riscv/sbi/common.c index 9b15be2aa5ed5cdaba8cae4aa6f44cd71da0acbc..63da1232036ad992aae63364e37a6eae6e3c2950 100644 --- a/src/arch/riscv/sbi/common.c +++ b/src/arch/riscv/sbi/common.c @@ -1,8 +1,14 @@ #include <asm/common.h> #include <asm/sbi.h> -void port_write_ch(char ch) { sbi_console_putchar((int)ch); } +void port_write_ch(char ch) { + sbi_console_putchar((int)ch); +} -void port_write(char *str) { sbi_console_putstr(str); } +void port_write(char *str) { + sbi_console_putstr(str); +} -long sys_port_read() { return sbi_console_getchar(); } +long sys_port_read() { + return sbi_console_getchar(); +} diff --git a/src/drivers/screen.c b/src/drivers/screen.c index 40f22012d36d362854d228cafc6ace2c5f60fd73..8bb359fd9fcdc2b19852f9a7ef2f34b2ed872f97 100644 --- a/src/drivers/screen.c +++ b/src/drivers/screen.c @@ -46,10 +46,11 @@ static void screen_write_ch(char ch) { k_screen_reflush(); for (int i = start_line - 1; i < SCREEN_HEIGHT; i++) { for (int j = 0; j < SCREEN_WIDTH; j++) { - if (i == SCREEN_HEIGHT - 1) + if (i == SCREEN_HEIGHT - 1) { new_screen[i * SCREEN_WIDTH + j] = ' '; - else + } else { new_screen[i * SCREEN_WIDTH + j] = old_screen[(i + 1) * SCREEN_WIDTH + j]; + } } } (*current_running)->cursor_y = SCREEN_HEIGHT; @@ -96,7 +97,7 @@ long sys_screen_move_cursor(int x, int y) { long sys_screen_write(char *buff) { int i = 0; - int l = strlen(buff); + int l = k_strlen(buff); for (i = 0; i < l; i++) { screen_write_ch(buff[i]); @@ -133,7 +134,9 @@ long k_screen_reflush(void) { return 0; } -void load_curpcb_cursor() { kernel_move_cursor((*current_running)->cursor_x, (*current_running)->cursor_y); } +void load_curpcb_cursor() { + kernel_move_cursor((*current_running)->cursor_x, (*current_running)->cursor_y); +} void kernel_move_cursor(int x, int y) { // \033[y;xH diff --git a/src/fs/fs.c b/src/fs/fs.c index 49d278dd96499c2efbd0d70a96c93f716da48cc5..1e026846f6698246f378177713796af99a83a4b6 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c @@ -119,8 +119,9 @@ int alloc_fid() { if (freenum > 0) { id = freefid[freenum]; freenum--; - } else + } else { id = nowfid++; + } return id; } @@ -141,12 +142,14 @@ int alloc_inode() { imap[id] = imap[id] | ((uint64_t)1 << (i % 64)); inodeid = i; superblock.inode_used++; - if ((((superblock.inode_used - 1) * sizeof(inode_t)) % 512) + sizeof(inode_t) > 512 || (((superblock.inode_used - 1) * sizeof(inode_t)) % 512) == 0) + if ((((superblock.inode_used - 1) * sizeof(inode_t)) % 512) + sizeof(inode_t) > 512 || (((superblock.inode_used - 1) * sizeof(inode_t)) % 512) == 0) { superblock.sector_used += 1; + } break; } - if ((i % 64) == 63) + if ((i % 64) == 63) { id++; + } } sbi_sd_write(kva2pa(FS_KERNEL_ADDR + iab_map_addr_offset), 1, superblock.imap_sec_offset + superblock.fs_start_sec); sbi_sd_write(kva2pa((long unsigned int)&superblock), 1, fs_start_sec + sb_sec_offset); @@ -165,8 +168,9 @@ int alloc_block(inode_t *inode) { superblock.sector_used += 8; break; } - if ((i % 64) == 56) + if ((i % 64) == 56) { id++; + } } inode->sec_size += 8; sbi_sd_write(kva2pa(empty_block), 8, superblock.data_sec_offset + superblock.fs_start_sec + sectorid); @@ -183,16 +187,18 @@ int look_up_1dir(char *name) { dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) { + if (k_strcmp(dir->name, name) == 0) { flag = 1; break; } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { flag = 1; - if (flag == 0) + } + if (flag == 0) { return -1; + } inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += dir->inode_id; @@ -209,7 +215,7 @@ int look_up_dir(const char *buff) { char name[20]; int i = 0; int inodeid = nowinodeid; - int num = strlen(buff); + int num = k_strlen(buff); sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); inode_t *inode = &nowinode; @@ -224,13 +230,15 @@ int look_up_dir(const char *buff) { i = k + 1; // file has no subdir - if (inode->mode == 1) + if (inode->mode == 1) { return -1; + } inodeid = look_up_1dir(name); // no file/dir matched - if (inodeid == -1) + if (inodeid == -1) { return -1; + } inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += inodeid; } @@ -242,9 +250,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { if (rpos_block < 11) { int point_num = rpos_block; if (inode->direct_block_pointers[point_num] == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { inode->direct_block_pointers[point_num] = alloc_block(inode); } } @@ -255,19 +263,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { int point1_num = (rpos_block - 11) % 1024; if (inode->indirect_block_pointers[point2_num] == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) + } else if (mode == 1) { inode->indirect_block_pointers[point2_num] = alloc_block(inode); + } } sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->indirect_block_pointers[point2_num]); int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset); p += point1_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->indirect_block_pointers[point2_num]); } @@ -280,19 +289,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { int point1_num = (rpos_block - 11 - 1024 * 3) % 1024; if (inode->double_block_pointers[point3_num] == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) + } else if (mode == 1) { inode->double_block_pointers[point3_num] = alloc_block(inode); + } } sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->double_block_pointers[point3_num]); int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset); p += point2_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->double_block_pointers[point3_num]); } @@ -304,9 +314,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { p += point1_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of2); } @@ -320,19 +330,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { int point1_num = (rpos_block - 11 - 1024 * 3 - 2 * 1024 * 1024) % 1024; if (inode->trible_block_pointers == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) + } else if (mode == 1) { inode->trible_block_pointers = alloc_block(inode); + } } sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->trible_block_pointers); int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset); p += point3_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->trible_block_pointers); } @@ -344,9 +355,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { p += point2_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of2); } @@ -358,9 +369,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) { p += point1_num; if (*p == 0) { - if (mode == 0) + if (mode == 0) { return -1; - else if (mode == 1) { + } else if (mode == 1) { *p = alloc_block(inode); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of1); } @@ -377,12 +388,15 @@ void init_file(int inodeid) { inode->sec_size = 0; inode->mode = 1; // 0-directory, 1-file inode->link_num = 0; - for (int i = 0; i < 11; i++) + for (int i = 0; i < 11; i++) { inode->direct_block_pointers[i] = 0; - for (int i = 0; i < 3; i++) + } + for (int i = 0; i < 3; i++) { inode->indirect_block_pointers[i] = 0; - for (int i = 0; i < 2; i++) + } + for (int i = 0; i < 2; i++) { inode->double_block_pointers[i] = 0; + } inode->trible_block_pointers = 0; // no write, no need for data block @@ -394,19 +408,21 @@ long sys_touch(const char *name) { sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } dir->last = 0; dir++; dir->inode_id = alloc_inode(); init_file(dir->inode_id); dir->mode = 1; dir->last = 1; - strcpy(dir->name, name); + k_strcpy(dir->name, name); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); return 1; @@ -417,17 +433,19 @@ long sys_fopen(const char *name, int access) { sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); while (!(dir->last)) { - if (strcmp(dir->name, name) == 0 && dir->mode == 1) { + if (k_strcmp(dir->name, name) == 0 && dir->mode == 1) { flag = 1; break; } dir++; } - if (strcmp(dir->name, name) == 0 && dir->mode == 1) + if (k_strcmp(dir->name, name) == 0 && dir->mode == 1) { flag = 1; + } if (flag == 0) { - if (access == -1) + if (access == -1) { return -1; + } sys_touch(name); dir++; } @@ -440,8 +458,9 @@ long sys_fopen(const char *name, int access) { } int fread(int fid, unsigned char *buff, int size) { - if (fd[fid].prive == O_WRONLY) + if (fd[fid].prive == O_WRONLY) { return -1; + } int rpos_block = fd[fid].pos_block; int rpos_offset = fd[fid].pos_offset; @@ -453,8 +472,9 @@ int fread(int fid, unsigned char *buff, int size) { while (nowsize < size) { int offset = rpos_offset; int flag = seek_pos(rpos_block, rpos_offset, inode, 0); - if (flag == 0 || flag == -1) + if (flag == 0 || flag == -1) { return -1; + } src = (unsigned char *)(FS_KERNEL_ADDR + data_addr_offset + offset); while (rpos_offset < 512 * 8 && nowsize < size) { *(buff++) = *(src++); @@ -476,8 +496,9 @@ int file_len = 0; int try_get_from_file(const char *file_name, unsigned char **binary, int *length) { int fid = sys_fopen(file_name, -1); - if (fid == -1) + if (fid == -1) { return 0; + } inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += fd[fid].inodeid; @@ -491,8 +512,9 @@ int try_get_from_file(const char *file_name, unsigned char **binary, int *length } long sys_fread(int fid, char *buff, int size) { - if (fd[fid].prive == O_WRONLY) + if (fd[fid].prive == O_WRONLY) { return -1; + } int rpos_block = fd[fid].pos_block; int rpos_offset = fd[fid].pos_offset; @@ -504,8 +526,9 @@ long sys_fread(int fid, char *buff, int size) { while (nowsize < size) { int offset = rpos_offset; int flag = seek_pos(rpos_block, rpos_offset, inode, 0); - if (flag == 0 || flag == -1) + if (flag == 0 || flag == -1) { return -1; + } src = (char *)(FS_KERNEL_ADDR + data_addr_offset + offset); while (rpos_offset < 512 * 8 && nowsize < size) { *(buff++) = *(src++); @@ -523,8 +546,9 @@ long sys_fread(int fid, char *buff, int size) { } long sys_fwrite(int fid, char *buff, int size) { - if (fd[fid].prive == O_RDONLY) + if (fd[fid].prive == O_RDONLY) { return -1; + } int rpos_block = fd[fid].pos_block; int rpos_offset = fd[fid].pos_offset; @@ -567,11 +591,11 @@ void init_dir(int inodeid) { dentry_t *dentry = (dentry_t *)(FS_KERNEL_ADDR + data_addr_offset); dentry->inode_id = inodeid; - strcpy(dentry->name, "."); + k_strcpy(dentry->name, "."); dentry->last = 0; dentry++; dentry->inode_id = nowinodeid; - strcpy(dentry->name, ".."); + k_strcpy(dentry->name, ".."); dentry->last = 1; sbi_sd_write(kva2pa(FS_KERNEL_ADDR + inode_addr_offset), superblock.inode_sec_size, superblock.fs_start_sec + superblock.inode_sec_offset); @@ -582,19 +606,21 @@ long sys_mkdir(const char *name) { sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } dir->last = 0; dir++; dir->inode_id = alloc_inode(); init_dir(dir->inode_id); dir->mode = 0; dir->last = 1; - strcpy(dir->name, name); + k_strcpy(dir->name, name); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); return 1; } @@ -605,19 +631,23 @@ long sys_ln(const char *name, char *path) { sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir2_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir2_addr_offset); while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { return 0; + } int inodeid = look_up_dir(path); - if (inodeid == -1) + if (inodeid == -1) { return 0; + } inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += inodeid; - if (inode->mode == 0) + if (inode->mode == 0) { return 0; + } inode->link_num++; dir->last = 0; @@ -625,7 +655,7 @@ long sys_ln(const char *name, char *path) { dir->inode_id = inodeid; dir->mode = 1; dir->last = 1; - strcpy(dir->name, name); + k_strcpy(dir->name, name); sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir2_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]); return 1; @@ -637,20 +667,24 @@ long sys_rmdir(const char *name) { dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); int dinode; while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) { + if (k_strcmp(dir->name, name) == 0) { flag = 1; break; } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { flag = 1; - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) + } + if (k_strcmp(name, ".") == 0 || k_strcmp(name, "..") == 0) { flag = 0; - if (flag == 0) + } + if (flag == 0) { return 0; - if (dir->mode == 1) + } + if (dir->mode == 1) { return 0; // file not dir + } dinode = dir->inode_id; if (dir->last) { @@ -663,7 +697,7 @@ long sys_rmdir(const char *name) { p->inode_id = (p + 1)->inode_id; p->last = (p + 1)->last; p->mode = (p + 1)->mode; - strcpy(p->name, (p + 1)->name); + k_strcpy(p->name, (p + 1)->name); p++; } } @@ -712,8 +746,9 @@ int getback_block(inode_t *inode) { getback_1block(data_sec_start, smap, &nowsec); } } - if (nowsec >= inode->sec_size) + if (nowsec >= inode->sec_size) { return nowsec; + } for (int i = 0; i < 3; i++) { pointer1_sec_start = inode->indirect_block_pointers[i]; if (pointer1_sec_start != 0) { @@ -725,8 +760,9 @@ int getback_block(inode_t *inode) { if (p[j] != 0) { getback_1block(p[j], smap, &nowsec); } - if (nowsec >= inode->sec_size) + if (nowsec >= inode->sec_size) { return nowsec; + } } } } @@ -747,8 +783,9 @@ int getback_block(inode_t *inode) { if (p2[k] != 0) { getback_1block(p2[k], smap, &nowsec); } - if (nowsec >= inode->sec_size) + if (nowsec >= inode->sec_size) { return nowsec; + } } } } @@ -773,8 +810,9 @@ int getback_block(inode_t *inode) { if (p3[m] != 0) { getback_1block(p3[m], smap, &nowsec); } - if (nowsec >= inode->sec_size) + if (nowsec >= inode->sec_size) { return nowsec; + } } } } @@ -790,18 +828,21 @@ long sys_rm(const char *name) { dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); int dinode; while (!(dir->last)) { - if (strcmp(dir->name, name) == 0) { + if (k_strcmp(dir->name, name) == 0) { flag = 1; break; } dir++; } - if (strcmp(dir->name, name) == 0) + if (k_strcmp(dir->name, name) == 0) { flag = 1; - if (flag == 0) + } + if (flag == 0) { return 0; - if (dir->mode == 0) + } + if (dir->mode == 0) { return 0; // dir not file + } dinode = dir->inode_id; if (dir->last) { dir--; @@ -813,7 +854,7 @@ long sys_rm(const char *name) { p->inode_id = (p + 1)->inode_id; p->last = (p + 1)->last; p->mode = (p + 1)->mode; - strcpy(p->name, (p + 1)->name); + k_strcpy(p->name, (p + 1)->name); p++; } } @@ -845,12 +886,15 @@ long sys_rm(const char *name) { void update_inode(inode_t *src, int id) { nowinode.mode = src->mode; nowinode.sec_size = src->sec_size; - for (int i = 0; i < 11; i++) + for (int i = 0; i < 11; i++) { nowinode.direct_block_pointers[i] = src->direct_block_pointers[i]; - for (int i = 0; i < 3; i++) + } + for (int i = 0; i < 3; i++) { nowinode.indirect_block_pointers[i] = src->indirect_block_pointers[i]; - for (int i = 0; i < 2; i++) + } + for (int i = 0; i < 2; i++) { nowinode.double_block_pointers[i] = src->double_block_pointers[i]; + } nowinode.trible_block_pointers = src->trible_block_pointers; nowinodeid = id; } @@ -858,22 +902,25 @@ void update_inode(inode_t *src, int id) { long sys_cd(const char *name) { int inodeid = 0; inodeid = look_up_dir(name); - if (inodeid == -1) + if (inodeid == -1) { return 0; + } // update nowinode inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += inodeid; - if (inode->mode == 1) + if (inode->mode == 1) { return 0; // file + } update_inode(inode, inodeid); return 1; } int getwei(int a) { int num = 0; - if (a == 0) + if (a == 0) { return 1; + } while (a) { num++; a /= 10; @@ -882,34 +929,40 @@ int getwei(int a) { } void printw(int num, int what) { - while (num--) + while (num--) { prints(" "); + } prints("%d", what); } long sys_ls(const char *name, int func) { int inodeid = look_up_dir(name); - if (inodeid == -1) + if (inodeid == -1) { return 0; + } dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset); inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += inodeid; - if (inode->mode == 1) + if (inode->mode == 1) { return 0; + } int len = 0; int num = 0; - if (func == 1) + if (func == 1) { prints("[%d] name inode ln size(B)\n", num++); + } while (!(dir->last)) { prints("[%d] %s", num++, dir->name); - if (dir->mode == 0) + if (dir->mode == 0) { prints("/"); + } if (func == 1) { - len = strlen(dir->name); - if (dir->mode == 0) + len = k_strlen(dir->name); + if (dir->mode == 0) { len++; + } inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += dir->inode_id; len = 13 - len; @@ -923,12 +976,14 @@ long sys_ls(const char *name, int func) { dir++; } prints("[%d] %s", num++, dir->name); - if (dir->mode == 0) + if (dir->mode == 0) { prints("/"); + } if (func == 1) { - len = strlen(dir->name); - if (dir->mode == 0) + len = k_strlen(dir->name); + if (dir->mode == 0) { len++; + } inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += dir->inode_id; len = 13 - len; @@ -944,12 +999,14 @@ long sys_ls(const char *name, int func) { long sys_cat(const char *name) { int inodeid = look_up_dir(name); - if (inodeid == -1) + if (inodeid == -1) { return 0; + } inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); inode += inodeid; - if (inode->sec_size == 0 || inode->mode == 0) + if (inode->sec_size == 0 || inode->mode == 0) { return 0; + } sbi_sd_read(kva2pa(FS_KERNEL_ADDR + data_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->direct_block_pointers[0]); @@ -957,8 +1014,9 @@ long sys_cat(const char *name) { int off = 0; int times = 1024; while (*c && (times--)) { - if (*c == '\n') + if (*c == '\n') { off++; + } prints("%c", *c); c++; } @@ -983,12 +1041,13 @@ long sys_mkfs(int func) { // root occupy inode[0] and data[0-7] uint64_t *iabmap = (uint64_t *)(FS_KERNEL_ADDR + iab_map_addr_offset); for (int i = 0; i < iab_map_addr_size / 8; i++) { - if (i == 0) + if (i == 0) { iabmap[i] = 1; - else if (i == 64) + } else if (i == 64) { iabmap[i] = 0xff; - else + } else { iabmap[i] = 0; + } } inode_t *root_inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); root_inode->link_num = 0; @@ -998,12 +1057,12 @@ long sys_mkfs(int func) { dentry_t *root_dentry = (dentry_t *)(FS_KERNEL_ADDR + data_addr_offset); root_dentry->inode_id = 0; - strcpy(root_dentry->name, "."); + k_strcpy(root_dentry->name, "."); root_dentry->mode = 0; root_dentry->last = 0; root_dentry++; root_dentry->inode_id = 0; - strcpy(root_dentry->name, ".."); + k_strcpy(root_dentry->name, ".."); root_dentry->mode = 0; root_dentry->last = 1; @@ -1052,7 +1111,7 @@ extern void map_fs_space(); void init_fs() { map_fs_space(); - memset((void *)empty_block, 0, 0x1000); + k_memset((void *)empty_block, 0, 0x1000); // main superblock and back-up superblock sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 1, fs_start_sec + sb_sec_offset); @@ -1060,13 +1119,15 @@ void init_fs() { super_block_t *sb = (super_block_t *)(FS_KERNEL_ADDR + dir_addr_offset); super_block_t *sb2 = (super_block_t *)(FS_KERNEL_ADDR + dir_addr_offset + 512); // not inited, then initialize - if (sb->magic != magic_number && sb2->magic != magic_number) + if (sb->magic != magic_number && sb2->magic != magic_number) { sys_mkfs(-1); + } // make sure one of them can work - else if (sb->magic != magic_number && sb2->magic == magic_number) + else if (sb->magic != magic_number && sb2->magic == magic_number) { cpy_sb(1, sb2); - else + } else { cpy_sb(1, sb); + } sbi_sd_read(kva2pa(FS_KERNEL_ADDR + iab_map_addr_offset), superblock.imap_sec_size + superblock.smap_sec_size, superblock.imap_sec_offset + superblock.fs_start_sec); sbi_sd_read(kva2pa(FS_KERNEL_ADDR + inode_addr_offset), superblock.inode_sec_size, superblock.inode_sec_offset + superblock.fs_start_sec); inode_t *root_inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset); diff --git a/src/fs/fs.h b/src/fs/fs.h index 840d56e113cca5b476e3ed477bff533a8dca0d43..052ec20ba1b91853215431748e59b4d1f09a5ee0 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -115,6 +115,8 @@ extern int nowfid; extern int freefid[20]; extern int freenum; +int try_get_from_file(const char *file_name, unsigned char **binary, int *length); + void init_fs(); int k_mkfs(int func); long sys_getcwd(const char *buf, unsigned long size); @@ -125,11 +127,18 @@ long sys_unlinkat(int dfd, const char *pathname, int flag); long sys_linkat(int olddfd, const char *oldname, int newdfd, const char *newname, int flags); long sys_umount2(const char *name, int flags); long sys_mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data); -long sys_chdir(const char *filename); -long sys_openat(int dfd, const char *filename, int flags, umode_t mode); +long sys_chdir(const char *file_name); +long sys_openat(int dfd, const char *file_name, int flags, umode_t mode); long sys_close(unsigned long fd); long sys_pipe2(int *fildes, int flags); long sys_getdents64(unsigned int fd, dirent64_t *dirent, unsigned int count); long sys_read(unsigned int fd, char *buf, size_t count); long sys_write(unsigned int fd, const char *buf, size_t count); -long sys_fstat(unsigned int fd, kstat_t *statbuf); \ No newline at end of file +long sys_fstat(unsigned int fd, kstat_t *statbuf); + +void *sys_mmap(void *addr, size_t length, int prot, int flags, + int fd, off_t offset); +long sys_munmap(unsigned long addr, size_t len); +long sys_mremap(unsigned long addr, + unsigned long old_len, unsigned long new_len, + unsigned long flags, unsigned long new_addr); \ No newline at end of file diff --git a/src/include/common/elf.h b/src/include/common/elf.h index 6e4265db7d5c85b786a8bf9c71ff2e56936cc2fb..6020efc0813eb7b135b8b946b6f72694ce64f332 100644 --- a/src/include/common/elf.h +++ b/src/include/common/elf.h @@ -119,6 +119,15 @@ typedef struct elf64_phdr Elf64_Xword p_align; /* Segment alignment, file & memory */ } Elf64_Phdr; +typedef struct ELF_info{ + uint64_t text_begin; + uint64_t phoff; + uint64_t phent; + uint64_t phnum; + uint64_t entry; + uint64_t edata; +} ELF_info_t; + #define MIN(a, b) ((a) < (b) ? (a) : (b)) static inline int is_elf_format(unsigned char *binary) @@ -169,7 +178,7 @@ static inline uintptr_t load_elf( unsigned char *bytes_of_page = (unsigned char *)prepare_page_for_va( (uintptr_t)(phdr->p_vaddr + i), pgdir); - memcpy( + k_memcpy( bytes_of_page, elf_binary + phdr->p_offset + i, MIN(phdr->p_filesz - i, NORMAL_PAGE_SIZE)); diff --git a/src/include/common/types.h b/src/include/common/types.h index 06a65abaacf91f5c498445c8df1bb86b0cae513e..eb0daf55b43737b61974b28adf05d25af5b79b4c 100644 --- a/src/include/common/types.h +++ b/src/include/common/types.h @@ -71,6 +71,7 @@ typedef __u32 u32; typedef int64_t s64; typedef uint64_t u64; +typedef uint8_t byte_size_t; #ifndef __kernel_long_t typedef long __kernel_long_t; @@ -146,7 +147,7 @@ typedef __kernel_long_t __kernel_time_t; typedef long long __kernel_time64_t; typedef __kernel_long_t __kernel_clock_t; typedef int __kernel_timer_t; -typedef int __kernel_clockid_t; +typedef int __kernel_clock_ids_t; typedef char * __kernel_caddr_t; typedef unsigned short __kernel_uid16_t; typedef unsigned short __kernel_gid16_t; diff --git a/src/include/lib/math.h b/src/include/lib/math.h new file mode 100644 index 0000000000000000000000000000000000000000..6905bf8ea086d1e0af0224eca37c6c3084ba5a9a --- /dev/null +++ b/src/include/lib/math.h @@ -0,0 +1,7 @@ +#pragma once + +/* Rounding; only works for n = power of two */ +#define ROUND(a, n) (((((uint64_t)(a)) + (n)-1)) & ~((n)-1)) +#define ROUNDDOWN(a, n) (((uint64_t)(a)) & ~((n)-1)) + +int k_min(int a, int b); \ No newline at end of file diff --git a/src/include/lib/string.h b/src/include/lib/string.h index 2a8db624b3440f88dfeb1b6441c0db072592b629..1ea374481dffb67cad396a335e9996d529b5e361 100644 --- a/src/include/lib/string.h +++ b/src/include/lib/string.h @@ -2,10 +2,11 @@ #include <common/types.h> -void memcpy(uint8_t *dest, const uint8_t *src, uint32_t len); -void memset(void *dest, uint8_t val, uint32_t len); -void bzero(void *dest, uint32_t len); -int strcmp(const char *str1, const char *str2); -char *strcpy(char *dest, const char *src); -char *strcat(char *dest, const char *src); -int strlen(const char *src); +void k_memcpy(uint8_t *dest, const uint8_t *src, uint32_t len); +void k_memset(void *dest, uint8_t val, uint32_t len); +void k_bzero(void *dest, uint32_t len); +int k_strcmp(const char *str1, const char *str2); +char *k_strcpy(char *dest, const char *src); +char *k_strcat(char *dest, const char *src); +int k_strlen(const char *src); +int k_strlistlen(char *src[]); \ No newline at end of file diff --git a/src/include/os/cpu.h b/src/include/os/cpu.h new file mode 100644 index 0000000000000000000000000000000000000000..ecccd28f0ff3cbd5cfa57dd73061886bff711b42 --- /dev/null +++ b/src/include/os/cpu.h @@ -0,0 +1,4 @@ +#pragma once + +#define CPU_NUM 2 +#define CPU_SET_SIZE 1 \ No newline at end of file diff --git a/src/include/os/mm.h b/src/include/os/mm.h index 2d96b3f21a5d4085c112d04148ac00b32474ecaf..9a98c01e66368fd64561d48259fb06d3d10eadeb 100644 --- a/src/include/os/mm.h +++ b/src/include/os/mm.h @@ -23,34 +23,34 @@ #define MAP_PRIVATE 0X02 #define MAP_FAILED ((void *) -1) -/* Rounding; only works for n = power of two */ -#define ROUND(a, n) (((((uint64_t)(a)) + (n)-1)) & ~((n)-1)) -#define ROUNDDOWN(a, n) (((uint64_t)(a)) & ~((n)-1)) +#define MAP_KERNEL 1 +#define MAP_USER 2 typedef uint64_t PTE; extern ptr_t memCurr; extern int diskpg_num; extern uint64_t diskpg[1000]; -void movetodisk(uint64_t pg_kva, uint64_t user_va); -void getbackdisk(uint64_t va, uint64_t new_addr); +void k_move_to_disk(uint64_t pg_kva, uint64_t user_va); +void k_get_back_disk(uint64_t va, uint64_t new_addr); void en_invalid(uint64_t pa_kva, PTE *pgdir); -ptr_t allocmem(int numPage, uint64_t user_va); -ptr_t allocPage(int numPage); +ptr_t k_alloc_mem(int numPage, uint64_t user_va); +ptr_t k_alloc_page(int numPage); void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir); void fork_page_helper(uintptr_t va, PTE *destpgdir, PTE *srcpgdir); uint64_t get_kva_from_va(uint64_t va, PTE *pgdir); long sys_getpa(uint64_t va); void map_kp(uint64_t va, uint64_t pa, PTE *pgdir); -// ptr_t allocPage(int numPage); -void freePage(ptr_t baseAddr, int numPage); -void *kmalloc(size_t size); +void k_free_page(ptr_t baseAddr, int numPage); +void *k_malloc(size_t size); void share_pgtable(PTE *dest_pgdir, PTE *src_pgdir); -uintptr_t alloc_page_helper(uintptr_t va, PTE *pgdir); -long sys_shm_page_get(int key); -long sys_shm_page_dt(uintptr_t addr); +uintptr_t k_alloc_page_helper(uintptr_t va, PTE *pgdir); +long shm_page_get(int key); +long shm_page_dt(uintptr_t addr); void map(uint64_t va, uint64_t pa, PTE *pgdir); void getback_page(int pid); PTE *get_kva(PTE entry); void cancelpg(PTE *pgdir); + +long sys_brk(unsigned long brk); \ No newline at end of file diff --git a/src/include/os/pcb.h b/src/include/os/pcb.h index 02a5d527ddaa73b7441f2d8414c7310dd694cee3..cfa28d34a0df5fa16f44874b7e39ef8e328a0481 100644 --- a/src/include/os/pcb.h +++ b/src/include/os/pcb.h @@ -1,9 +1,11 @@ #pragma once #include <asm/context.h> -#include <common/types.h> +#include <common/elf.h> #include <lib/list.h> +#include <os/cpu.h> #include <os/mm.h> +#include <os/sync.h> #include <os/time.h> #define NUM_MAX_PRCESS 16 @@ -31,17 +33,34 @@ #define PRIO_PGRP 1 #define PRIO_USER 2 -#define ENQUEUE_LIST 0 -#define ENQUEUE_PCB 1 -#define DEQUEUE_LIST 0 -#define DEQUEUE_WAITLIST 1 -#define DEQUEUE_WAITLIST_DESTROY 2 -#define DEQUEUE_LIST_STRATEGY 3 - -#define UNBLOCK_TO_LIST_FRONT 0 -#define UNBLOCK_TO_LIST_BACK 1 -#define UNBLOCK_ONLY 2 -#define UNBLOCK_TO_LIST_STRATEGY 3 +/* + * cloning flags: + */ +#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_FS 0x00000200 /* set if fs info shared between processes */ +#define CLONE_FILES 0x00000400 /* set if open files shared between processes */ +#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ +#define CLONE_PIDFD 0x00001000 /* set if a pidfd should be placed in parent */ +#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ +#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ +#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ +#define CLONE_THREAD 0x00010000 /* Same thread group? */ +#define CLONE_NEWNS 0x00020000 /* New mount namespace group */ +#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ +#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ +#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ +#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ +#define CLONE_DETACHED 0x00400000 /* Unused, ignored */ +#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ +#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ +#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ +#define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ +#define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ +#define CLONE_NEWUSER 0x10000000 /* New user namespace */ +#define CLONE_NEWPID 0x20000000 /* New pid namespace */ +#define CLONE_NEWNET 0x40000000 /* New network namespace */ +#define CLONE_IO 0x80000000 /* Clone io context */ typedef void (*void_task)(); @@ -51,26 +70,58 @@ typedef struct prior uint64_t last_sched_time; } prior_t; -typedef enum { +typedef enum task_status { TASK_BLOCKED, TASK_RUNNING, TASK_READY, - TASK_ZOMBIE, TASK_EXITED, } task_status_t; -typedef enum { - ENTER_ZOMBIE_ON_EXIT, - AUTO_CLEANUP_ON_EXIT, -} spawn_mode_t; - -typedef enum { +typedef enum task_type { KERNEL_PROCESS, KERNEL_THREAD, USER_PROCESS, USER_THREAD, } task_type_t; +typedef enum enqueue_way { + ENQUEUE_LIST, + ENQUEUE_TIMER_LIST, +} enqueue_way_t; + +typedef enum dequeue_way { + DEQUEUE_LIST, + DEQUEUE_WAITLIST, + DEQUEUE_WAITLIST_DESTROY, + DEQUEUE_LIST_STRATEGY, +} dequeue_way_t; + +typedef enum unblock_way { + UNBLOCK_TO_LIST_FRONT, + UNBLOCK_TO_LIST_BACK, + UNBLOCK_ONLY, + UNBLOCK_TO_LIST_STRATEGY, +} unblock_way_t; + +typedef struct rusage { + __kernel_timeval_t ru_utime; /* user time used */ + __kernel_timeval_t ru_stime; /* system time used */ + __kernel_long_t ru_maxrss; /* maximum resident set size */ + __kernel_long_t ru_ixrss; /* integral shared memory size */ + __kernel_long_t ru_idrss; /* integral unshared data size */ + __kernel_long_t ru_isrss; /* integral unshared stack size */ + __kernel_long_t ru_minflt; /* page reclaims */ + __kernel_long_t ru_majflt; /* page faults */ + __kernel_long_t ru_nswap; /* swaps */ + __kernel_long_t ru_inblock; /* block input operations */ + __kernel_long_t ru_oublock; /* block output operations */ + __kernel_long_t ru_msgsnd; /* messages sent */ + __kernel_long_t ru_msgrcv; /* messages received */ + __kernel_long_t ru_nsignals; /* signals received */ + __kernel_long_t ru_nvcsw; /* voluntary context switches */ + __kernel_long_t ru_nivcsw; /* involuntary " */ +} rusage_t; + /* Process Control Block */ typedef struct pcb { /* register context */ @@ -78,33 +129,34 @@ typedef struct pcb { reg_t kernel_sp; reg_t user_sp; - // count the number of disable_preempt - // enable_preempt enables CSR_SIE only when preempt_count == 0 - reg_t preempt_count; - - ptr_t kernel_stack_base; - ptr_t user_stack_base; - /* previous, next pointer */ list_node_t list; list_head wait_list; + + regs_context_t *save_context; + switchto_context_t *switch_context; + + bool in_use; + ELF_info_t elf; + /* process id */ pid_t pid; // real offset of pcb[] pid_t fpid; // threads' fpid is process pid pid_t tid; + uint32_t *clear_ctid; pid_t father_pid; - pid_t child_pid[NUM_MAX_CHILD]; + pid_t child_pids[NUM_MAX_CHILD]; int child_num; int *child_stat_addrs[NUM_MAX_CHILD]; int threadsum; - int threadid[NUM_MAX_CHILD_THREADS]; + int thread_ids[NUM_MAX_CHILD_THREADS]; /* kernel/user thread/process */ task_type_t type; /* BLOCK | READY | RUNNING | ZOMBIE */ task_status_t status; - spawn_mode_t mode; + int exit_status; /* cursor position */ int cursor_x; @@ -112,48 +164,24 @@ typedef struct pcb { prior_t priority; - int locksum; - int lockid[NUM_MAX_LOCK]; + uint8_t core_mask[CPU_SET_SIZE]; + + uint64_t pgdir; - int mboxsum; - int mboxid[NUM_MAX_MBOX]; + int locksum; + int lock_ids[NUM_MAX_LOCK]; - int core_mask; - uint64_t pgdir; - int port; + pcb_mbox_t mbox; /* time */ - __kernel_time_t stime; - __kernel_time_t stime_last; // last time into kernel - __kernel_time_t utime; - __kernel_time_t utime_last; // last time out kernel + __kernel_timeval_t stime_last; // last time into kernel + __kernel_timeval_t utime_last; // last time out kernel pcbtimer_t timer; -} pcb_t; - -/* task information, used to init PCB */ -typedef struct task_info { - ptr_t entry_point; - task_type_t type; -} task_info_t; + __kernel_clock_t dead_child_stime; + __kernel_clock_t dead_child_utime; -typedef struct rusage { - __kernel_timeval_t ru_utime; /* user time used */ - __kernel_timeval_t ru_stime; /* system time used */ - __kernel_long_t ru_maxrss; /* maximum resident set size */ - __kernel_long_t ru_ixrss; /* integral shared memory size */ - __kernel_long_t ru_idrss; /* integral unshared data size */ - __kernel_long_t ru_isrss; /* integral unshared stack size */ - __kernel_long_t ru_minflt; /* page reclaims */ - __kernel_long_t ru_majflt; /* page faults */ - __kernel_long_t ru_nswap; /* swaps */ - __kernel_long_t ru_inblock; /* block input operations */ - __kernel_long_t ru_oublock; /* block output operations */ - __kernel_long_t ru_msgsnd; /* messages sent */ - __kernel_long_t ru_msgrcv; /* messages received */ - __kernel_long_t ru_nsignals; /* signals received */ - __kernel_long_t ru_nvcsw; /* voluntary context switches */ - __kernel_long_t ru_nivcsw; /* involuntary " */ -} rusage_t; + rusage_t resources; +} pcb_t; /* current running task PCB */ @@ -162,9 +190,6 @@ extern pcb_t *volatile current_running1; extern pcb_t **volatile current_running; /* ready queue to run */ extern list_head ready_queue; -// pcb_t * volatile (*current_running)[NR_CPUS]; -extern pid_t process_id; -extern int allocpid; extern pcb_t pcb[NUM_MAX_TASK]; // pcb_t kernel_pcb[NR_CPUS]; @@ -173,41 +198,31 @@ extern const ptr_t pid0_stack2; extern pcb_t pid0_pcb; extern pcb_t pid0_pcb2; -extern int freepidnum; -extern int nowpid; -extern int glmask; -extern int glvalid; - extern pid_t freepid[NUM_MAX_TASK]; -pid_t nextpid(); - -void init_pcb(); -int check_pcb(int cpuid); - -void switch_to(pcb_t *prev, pcb_t *next); +void k_init_pcb(); +extern void switch_to(pcb_t *prev, pcb_t *next); long k_scheduler(void); +void k_block(list_head *, list_head *queue, enqueue_way_t way); +void k_unblock(list_head *, list_head *, unblock_way_t way); +long k_getpid(void); + long sys_sched_yield(void); long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp); -void check_sleeping(); - -void k_block(list_head *, list_head *queue); -void k_unblock(list_head *, list_head *, int way); -long k_taskset(int pid, int mask); - -long sys_spawn(task_info_t *task, void *arg, spawn_mode_t mode); -long sys_fork(int prior); -// long sys_execve(const char *filename, const char **argv, const char **envp); -// long sys_clone(int (*fn)(void *), void *stack, int flags, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid); +long sys_spawn(const char *file_name); +long sys_fork(void); +long sys_exec(const char *file_name, const char *argv[], const char *envp[]); +long sys_execve(const char *file_name, const char *argv[], const char *envp[]); +long sys_clone(unsigned long flags, void *stack, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid); long sys_kill(pid_t pid); long sys_exit(int error_code); long sys_wait4(pid_t pid, int *stat_addr, int options, rusage_t *ru); long sys_process_show(); -long sys_exec(const char *file_name, int argc, char **argv); -long sys_show_exec(); long sys_setpriority(int which, int who, int niceval); long sys_getpriority(int which, int who); long sys_getpid(void); long sys_getppid(void); - -long sys_mthread_create(pid_t *thread, void (*start_routine)(void *), void *arg); \ No newline at end of file +long sys_sched_setaffinity(pid_t pid, unsigned int len, + const uint8_t *user_mask_ptr); +long sys_sched_getaffinity(pid_t pid, unsigned int len, + uint8_t *user_mask_ptr); \ No newline at end of file diff --git a/src/include/os/sync.h b/src/include/os/sync.h index c645ed747900caa4725123c469d62f907877d3ea..a89dcc752bd90af2c5db2c4c910c9034706cedbb 100644 --- a/src/include/os/sync.h +++ b/src/include/os/sync.h @@ -6,6 +6,10 @@ #define MBOX_NAME_LEN 64 #define MBOX_MSG_MAX_LEN 128 #define MBOX_MAX_USER 10 + +#define PCB_MBOX_MAX_MSG_NUM 16 +#define PCB_MBOX_MSG_MAX_LEN 256 + typedef struct basic_info{ int id; int initialized; @@ -44,12 +48,19 @@ typedef struct mbox{ int cited_pid[MBOX_MAX_USER]; } mbox_t; -typedef struct mbox_arg{ +typedef struct mbox_arg { void *msg; int msg_length; int sleep_operation; } mbox_arg_t; +typedef struct pcb_mbox { + int pcb_i; + char buff[PCB_MBOX_MAX_MSG_NUM][PCB_MBOX_MSG_MAX_LEN]; + int read_head, write_head; + int used_units; +} pcb_mbox_t; + int k_commop(void *key_id, void *arg, int op); int k_semaphore_init(int *key, int sem); @@ -70,7 +81,11 @@ int k_barrier_destroy(int *key); int k_mbox_open(char *name); int k_mbox_close(); -int k_mbox_send(int key, mbox_arg_t *arg); -int k_mbox_recv(int key, mbox_arg_t *arg); +int k_mbox_send(int key, mbox_t *target, mbox_arg_t *arg); +int k_mbox_recv(int key, mbox_t *target, mbox_arg_t *arg); int k_mbox_try_send(int key, mbox_arg_t *arg); -int k_mbox_try_recv(int key, mbox_arg_t *arg); \ No newline at end of file +int k_mbox_try_recv(int key, mbox_arg_t *arg); + +void k_pcb_mbox_init(pcb_mbox_t *target, int owner_id); +int sys_mailread(void* buf, int len); +int sys_mailwrite(int pid, void* buf, int len); \ No newline at end of file diff --git a/src/include/os/time.h b/src/include/os/time.h index 59db138599e434a7565834eb5502f08aa3242fef..f6e0be430eeac39ddbb3119e5166a2cfedae9360 100644 --- a/src/include/os/time.h +++ b/src/include/os/time.h @@ -28,8 +28,8 @@ typedef struct timezone { typedef struct pcbtimer { bool initialized; - nanotime_val_t time; nanotime_val_t start_time; + nanotime_val_t end_time; nanotime_val_t *remain_time; } pcbtimer_t; @@ -43,12 +43,16 @@ long get_ticks(void); void nano_u_time_converter(nanotime_val_t *nanotime, time_val_t *utime, bool direction); void get_nanotime(nanotime_val_t *ntimebuf); +uint64_t get_ticks_from_nanotime(nanotime_val_t *ntimebuf); void copy_nanotime(nanotime_val_t *src, nanotime_val_t *dst); void minus_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res); +void add_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res); int cmp_nanotime(nanotime_val_t *first, nanotime_val_t *sec); void get_utime(time_val_t *ntimebuf); +uint64_t get_ticks_from_time(time_val_t *timebuf); void copy_utime(time_val_t *src, time_val_t *dst); void minus_utime(time_val_t *first, time_val_t *sec, time_val_t *res); +void add_utime(time_val_t *first, time_val_t *sec, time_val_t *res); int cmp_utime(time_val_t *first, time_val_t *sec); long sys_time(__kernel_time_t *tloc); diff --git a/src/init/main.c b/src/init/main.c index 3ce28e38dab910ff3a3a69a227275b79d4ae01bf..758aa00271c7dc8c09087f8c45ad30494c2d4261 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -17,6 +17,7 @@ int main() { int id = get_current_cpu_id(); if (id == 1) { + (*current_running) = get_current_running(); setup_exception(); cancelpg(pa2kva(PGDIR_PA)); sbi_set_timer(0); @@ -27,7 +28,7 @@ int main() { // init Process Control Block (-_-!) - init_pcb(); + k_init_pcb(); // printk("> [INIT] PCB initialization succeeded.\n\r"); diff --git a/src/kernel/irq/irq.c b/src/kernel/irq/irq.c index e6fed17eecee15551e59007a137abbd9f9590360..dfe8e2e88bd5af693836bac409845f2695a42ce8 100644 --- a/src/kernel/irq/irq.c +++ b/src/kernel/irq/irq.c @@ -36,6 +36,9 @@ void init_syscall(void) { // syscall[SYS_read] = (long (*)())sys_read; // syscall[SYS_write] = (long (*)())sys_write; // syscall[SYS_fstat] = (long (*)())sys_fstat; + // syscall[SYS_munmap] = (long (*)())sys_munmap; + // syscall[SYS_mremap] = (long (*)())sys_mremap; + // syscall[SYS_mmap] = (long (*)())sys_mmap; // Terminal syscall[SYS_uname] = (long (*)())sys_uname; // Functions @@ -43,12 +46,12 @@ void init_syscall(void) { syscall[SYS_times] = (long (*)())sys_times; syscall[SYS_time] = (long (*)())sys_time; syscall[SYS_gettimeofday] = (long (*)())sys_gettimeofday; - // syscall[SYS_mailread] = (long (*)())sys_mailread; - // syscall[SYS_mailwrite] = (long (*)())sys_mailwrite; + syscall[SYS_mailread] = (long (*)())sys_mailread; + syscall[SYS_mailwrite] = (long (*)())sys_mailwrite; // Process & Threads syscall[SYS_exit] = (long (*)())sys_exit; - // syscall[SYS_clone] = (long (*)())sys_clone; - // syscall[SYS_execve] = (long (*)())sys_execve; + syscall[SYS_clone] = (long (*)())sys_clone; + syscall[SYS_execve] = (long (*)())sys_execve; syscall[SYS_wait4] = (long (*)())sys_wait4; syscall[SYS_spawn] = (long (*)())sys_spawn; syscall[SYS_sched_yield] = (long (*)())sys_sched_yield; @@ -56,10 +59,10 @@ void init_syscall(void) { syscall[SYS_get_mempolicy] = (long (*)())sys_getpriority; syscall[SYS_getpid] = (long (*)())sys_getpid; syscall[SYS_getppid] = (long (*)())sys_getppid; + syscall[SYS_sched_setaffinity] = (long (*)())sys_sched_setaffinity; + // Memory - // syscall[SYS_brk] = (long (*)())sys_brk; - // syscall[SYS_munmap] = (long (*)())sys_munmap; - // syscall[SYS_mmap] = (long (*)())sys_mmap; + syscall[SYS_brk] = (long (*)())sys_brk; } void reset_irq_timer() { @@ -74,9 +77,12 @@ void interrupt_helper(regs_context_t *regs, uint64_t stval, uint64_t cause, uint lock_kernel(); // call corresponding handler by the value of `cause` (*current_running) = get_current_running(); - long ticks = get_ticks(); - (*current_running)->utime += (ticks - (*current_running)->utime_last); - (*current_running)->stime_last = ticks; + time_val_t now; + get_utime(&now); + time_val_t last_run; + minus_utime(&now, &(*current_running)->utime_last, &last_run); + add_utime(&last_run, &(*current_running)->resources.ru_utime, &(*current_running)->resources.ru_utime); + copy_utime(&now, &(*current_running)->stime_last); uint64_t check = cause; // if(check>>63 && check%16!=5) //{ @@ -88,36 +94,41 @@ void interrupt_helper(regs_context_t *regs, uint64_t stval, uint64_t cause, uint } else { exc_table[cause](regs, stval, cause, cpuid); } - ticks = get_ticks(); - (*current_running)->utime_last = ticks; - (*current_running)->stime += (ticks - (*current_running)->stime_last); + get_utime(&now); + copy_utime(&now, &(*current_running)->utime_last); + minus_utime(&now, &(*current_running)->stime_last, &last_run); + add_utime(&last_run, &(*current_running)->resources.ru_stime, &(*current_running)->resources.ru_stime); unlock_kernel(); } -void handle_int(regs_context_t *regs, uint64_t interrupt, uint64_t cause, uint64_t cpuid) { reset_irq_timer(); } +void handle_int(regs_context_t *regs, uint64_t interrupt, uint64_t cause, uint64_t cpuid) { + reset_irq_timer(); +} PTE *check_pf(uint64_t va, PTE *pgdir) { va &= VA_MASK; uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS)); uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); - if (pgdir[vpn2] == 0) + if (pgdir[vpn2] == 0) { return 0; + } PTE *pmd = get_kva(pgdir[vpn2]); - if (pmd[vpn1] == 0) + if (pmd[vpn1] == 0) { return 0; + } PTE *pld = get_kva(pmd[vpn1]); - if (pld[vpn0] == 0) + if (pld[vpn0] == 0) { return 0; + } return &pld[vpn0]; } void handle_disk(uint64_t stval, PTE *pte_addr) { pcb_t *cur = *current_running; - allocpid = cur->pid; - uint64_t newmem_addr = allocmem(1, stval); + uint64_t newmem_addr = k_alloc_mem(1, stval); map(stval, kva2pa(newmem_addr), (pa2kva(cur->pgdir << 12))); - getbackdisk(stval, newmem_addr); + k_get_back_disk(stval, newmem_addr); (*pte_addr) = (*pte_addr) | 1; } @@ -129,26 +140,25 @@ void handle_pf(regs_context_t *regs, uint64_t stval, uint64_t cause, uint64_t cp PTE va_pte = *pte_addr; if (cause == EXCC_STORE_PAGE_FAULT) { // child process - allocpid = cur->pid; if (cur->father_pid != cur->pid) { fork_page_helper(stval, (pa2kva(cur->pgdir << 12)), (pa2kva(pcb[cur->father_pid].pgdir << 12))); } else { // father process for (int i = 0; i < cur->child_num; i++) { - fork_page_helper(stval, (pa2kva(pcb[cur->child_pid[i]].pgdir << 12)), (pa2kva(cur->pgdir << 12))); + fork_page_helper(stval, (pa2kva(pcb[cur->child_pids[i]].pgdir << 12)), (pa2kva(cur->pgdir << 12))); } } *pte_addr = (*pte_addr) | (3 << 6); *pte_addr = (*pte_addr) | ((uint64_t)1 << 2); - } else if (cause == EXCC_INST_PAGE_FAULT) + } else if (cause == EXCC_INST_PAGE_FAULT) { *pte_addr = (*pte_addr) | (3 << 6); - else if ((((va_pte >> 6) & 1) == 0) && (cause == EXCC_LOAD_PAGE_FAULT)) + } else if ((((va_pte >> 6) & 1) == 0) && (cause == EXCC_LOAD_PAGE_FAULT)) { *pte_addr = (*pte_addr) | ((uint64_t)1 << 6); - else if ((va_pte & 1) == 0) // physical frame was on disk + } else if ((va_pte & 1) == 0) { // physical frame was on disk handle_disk(stval, pte_addr); + } } else { // No virtual-physical map - allocpid = cur->pid; - alloc_page_helper(stval, (pa2kva(cur->pgdir << 12))); + k_alloc_page_helper(stval, (pa2kva(cur->pgdir << 12))); local_flush_tlb_all(); } } diff --git a/src/kernel/mm/mm.c b/src/kernel/mm/mm.c index b3da2df8892327509a1e34f7592e46a71673ef37..0fe9938da056d33ca7103e0992ddc787b9a21667 100644 --- a/src/kernel/mm/mm.c +++ b/src/kernel/mm/mm.c @@ -1,7 +1,9 @@ #include <asm/pgtable.h> #include <asm/sbi.h> +#include <common/elf.h> #include <drivers/screen.h> #include <lib/assert.h> +#include <lib/math.h> #include <os/mm.h> #include <os/pcb.h> #include <os/smp.h> @@ -36,8 +38,9 @@ PTE *get_kva(PTE entry) { } void getback_page(int pid) { - if (freepg_num >= 999) + if (freepg_num >= 999) { return; + } for (int i = 1; i <= allpg[pid][0]; i++) { freepg_num++; freepg[freepg_num] = allpg[pid][i]; @@ -52,10 +55,11 @@ void getback_page(int pid) { } // start block = 250 -void movetodisk(uint64_t pg_kva, uint64_t user_va) { +void k_move_to_disk(uint64_t pg_kva, uint64_t user_va) { // one block = 512B = 0.5KB - if (diskpg_num >= 999) + if (diskpg_num >= 999) { assert(0); + } sys_screen_move_cursor(1, 5); prints("[k] From 0x%x to disk sector %d, for user_vaddr 0x%x\n", pg_kva, START_BLOCK + diskpg_num * 2, user_va); @@ -66,7 +70,7 @@ void movetodisk(uint64_t pg_kva, uint64_t user_va) { clear_pgdir(pg_kva); } -void getbackdisk(uint64_t user_va, uint64_t new_addr) { +void k_get_back_disk(uint64_t user_va, uint64_t new_addr) { int flag = 0; for (int i = 0; i < diskpg_num; i++) { if (diskpg[i] == user_va) { @@ -78,8 +82,9 @@ void getbackdisk(uint64_t user_va, uint64_t new_addr) { break; } } - if (flag == 0) + if (flag == 0) { assert(0); + } } void en_invalid(uint64_t va, PTE *pgdir) { @@ -87,26 +92,31 @@ void en_invalid(uint64_t va, PTE *pgdir) { uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS)); uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); - if (pgdir[vpn2] == 0) + if (pgdir[vpn2] == 0) { assert(0); + } PTE *pmd = get_kva(pgdir[vpn2]); - if (pmd[vpn1] == 0) + if (pmd[vpn1] == 0) { assert(0); + } PTE *pld = get_kva(pmd[vpn1]); pld[vpn0] = (pld[vpn0] >> 1) << 1; } -ptr_t allocmem(int numPage, uint64_t user_va) { +ptr_t k_alloc_mem(int numPage, uint64_t user_va) { ptr_t ret; + int allocpid = (*current_running)->pid; if (allmem[allocpid][0] >= MAXPAGES) { // no enough page allowed ret = allmem[allocpid][STARTPAGE]; - movetodisk(allmem[allocpid][STARTPAGE], alluserva[allocpid][STARTPAGE]); + k_move_to_disk(allmem[allocpid][STARTPAGE], alluserva[allocpid][STARTPAGE]); en_invalid(alluserva[allocpid][STARTPAGE], (pa2kva(pcb[allocpid].pgdir << 12))); - for (int i = STARTPAGE; i < allmem[allocpid][0]; i++) + for (int i = STARTPAGE; i < allmem[allocpid][0]; i++) { allmem[allocpid][i] = allmem[allocpid][i + 1]; - for (int i = STARTPAGE; i < alluserva[allocpid][0]; i++) + } + for (int i = STARTPAGE; i < alluserva[allocpid][0]; i++) { alluserva[allocpid][i] = alluserva[allocpid][i + 1]; + } allmem[allocpid][allmem[allocpid][0]] = ret; alluserva[allocpid][alluserva[allocpid][0]] = user_va; return ret; @@ -119,8 +129,9 @@ ptr_t allocmem(int numPage, uint64_t user_va) { freepg_num--; } if (allocpid != 0) { - if (allmem[allocpid][0] >= MAXPAGES) + if (allmem[allocpid][0] >= MAXPAGES) { return ret; + } allmem[allocpid][0]++; allmem[allocpid][allmem[allocpid][0]] = ret; alluserva[allocpid][0]++; @@ -130,7 +141,7 @@ ptr_t allocmem(int numPage, uint64_t user_va) { return ret; } // return kva -ptr_t allocPage(int numPage) { +ptr_t k_alloc_page(int numPage) { ptr_t ret; if (freepg_num == 0) { ret = ROUND(memCurr, PAGE_SIZE); @@ -139,9 +150,11 @@ ptr_t allocPage(int numPage) { ret = freepg[freepg_num]; freepg_num--; } + int allocpid = (*current_running)->pid; if (allocpid != 0) { - if (allpg[allocpid][0] >= 98) + if (allpg[allocpid][0] >= 98) { return ret; + } allpg[allocpid][0]++; allpg[allocpid][allpg[allocpid][0]] = ret; } @@ -149,27 +162,31 @@ ptr_t allocPage(int numPage) { return ret; } -void *kmalloc(size_t size) { +void k_free_page(ptr_t baseAddr, int numPage) {} + +void *k_malloc(size_t size) { ptr_t ret = ROUND(memCurr, 4); memCurr = ret + size; return (void *)ret; } uint64_t alloc_newva() { + int allocpid = (*current_running)->pid; for (uint64_t i = 0x100000; i < 0x1000000; i += 0x1000) { int flag = 1; for (int j = 1; j <= alluserva[allocpid][0]; j++) { - if (i == alluserva[allocpid][j]) + if (i == alluserva[allocpid][j]) { flag = 0; + } } - if (flag) + if (flag) { return i; + } } return 0; } -long sys_shm_page_get(int key) { - allocpid = (*current_running)->pid; +long shm_page_get(int key) { for (int i = 0; i < shm_num; i++) { if (shm_all[i].key == key && shm_all[i].pro_num != 0) { map(shm_all[i].uva, kva2pa(shm_all[i].kva), (pa2kva((*current_running)->pgdir << 12))); @@ -184,19 +201,20 @@ long sys_shm_page_get(int key) { break; } } - allocpid = (*current_running)->pid; - if (num == -1) + if (num == -1) { num = shm_num; + } shm_all[num].key = key; shm_all[num].uva = alloc_newva(); - shm_all[num].kva = alloc_page_helper(shm_all[num].uva, (pa2kva((*current_running)->pgdir << 12))); + shm_all[num].kva = k_alloc_page_helper(shm_all[num].uva, (pa2kva((*current_running)->pgdir << 12))); shm_all[num].pro_num = 1; - if (num == shm_num) + if (num == shm_num) { shm_num++; + } return shm_all[num].uva; } -long sys_shm_page_dt(uintptr_t addr) { +long shm_page_dt(uintptr_t addr) { for (int i = 0; i < shm_num; i++) { if (shm_all[i].uva == addr) { uint64_t va = addr; @@ -205,11 +223,13 @@ long sys_shm_page_dt(uintptr_t addr) { uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS)); uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); - if (pgdir[vpn2] == 0) + if (pgdir[vpn2] == 0) { assert(0); + } PTE *pmd = get_kva(pgdir[vpn2]); - if (pmd[vpn1] == 0) + if (pmd[vpn1] == 0) { assert(0); + } PTE *pld = get_kva(pmd[vpn1]); pld[vpn0] = 0; // cancel finished @@ -238,7 +258,7 @@ void share_pgtable(PTE *dest_pgdir, PTE *src_pgdir) { } void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir) { - uint64_t sva = USER_STACK_ADDR - 0x1000; + uint64_t sva = USER_STACK_ADDR - PAGE_SIZE; sva &= VA_MASK; uint64_t va = 0; // kernel not to clear write bit @@ -278,30 +298,33 @@ void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir) { } void fork_page_helper(uintptr_t va, PTE *destpgdir, PTE *srcpgdir) { - uint64_t dest_kva = alloc_page_helper(va, destpgdir); + uint64_t dest_kva = k_alloc_page_helper(va, destpgdir); va &= VA_MASK; uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS)); uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); - if (srcpgdir[vpn2] == 0) + if (srcpgdir[vpn2] == 0) { assert(0); + } PTE *pmd = get_kva(srcpgdir[vpn2]); - if (pmd[vpn1] == 0) + if (pmd[vpn1] == 0) { assert(0); + } PTE *pld = get_kva(pmd[vpn1]); uint64_t src_kva = (uint64_t)get_kva(pld[vpn0]); unsigned char *src = (unsigned char *)src_kva; unsigned char *dest = (unsigned char *)dest_kva; - for (int i = 0; i < 0x1000; i++) + for (int i = 0; i < 0x1000; i++) { dest[i] = src[i]; + } } /* allocate physical page for `va`, mapping it into `pgdir`, return the kernel virtual address for the page. */ -uintptr_t alloc_page_helper(uintptr_t va, PTE *pgdir) { - uint64_t kva = allocmem(1, va); +uintptr_t k_alloc_page_helper(uintptr_t va, PTE *pgdir) { + uint64_t kva = k_alloc_mem(1, va); uint64_t pa = kva2pa(kva); map(va, pa, pgdir); return kva; @@ -312,11 +335,13 @@ uint64_t get_kva_from_va(uint64_t va, PTE *pgdir) { uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS)); uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); - if (pgdir[vpn2] == 0) + if (pgdir[vpn2] == 0) { assert(0); + } PTE *pmd = get_kva(pgdir[vpn2]); - if (pmd[vpn1] == 0) + if (pmd[vpn1] == 0) { assert(0); + } PTE *pld = get_kva(pmd[vpn1]); return (uint64_t)get_kva(pld[vpn0]); } @@ -338,13 +363,13 @@ void map_kp(uint64_t va, uint64_t pa, PTE *pgdir) { uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); if (pgdir[vpn2] == 0) { // alloc a new second-level page directory - set_pfn(&pgdir[vpn2], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT); + set_pfn(&pgdir[vpn2], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT); set_attribute(&pgdir[vpn2], _PAGE_PRESENT); clear_pgdir((uintptr_t)get_kva(pgdir[vpn2])); } PTE *pmd = get_kva(pgdir[vpn2]); if (pmd[vpn1] == 0) { - set_pfn(&pmd[vpn1], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT); + set_pfn(&pmd[vpn1], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT); set_attribute(&pmd[vpn1], _PAGE_PRESENT); clear_pgdir((uintptr_t)get_kva(pmd[vpn1])); } @@ -374,13 +399,13 @@ void map(uint64_t va, uint64_t pa, PTE *pgdir) { uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT)); if (pgdir[vpn2] == 0) { // alloc a new second-level page directory - set_pfn(&pgdir[vpn2], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT); + set_pfn(&pgdir[vpn2], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT); set_attribute(&pgdir[vpn2], _PAGE_PRESENT); clear_pgdir((uintptr_t)get_kva(pgdir[vpn2])); } PTE *pmd = get_kva(pgdir[vpn2]); if (pmd[vpn1] == 0) { - set_pfn(&pmd[vpn1], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT); + set_pfn(&pmd[vpn1], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT); set_attribute(&pmd[vpn1], _PAGE_PRESENT); clear_pgdir((uintptr_t)get_kva(pmd[vpn1])); } @@ -401,4 +426,77 @@ void cancelpg(PTE *pgdir) { uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS); pgdir[vpn2] = 0; } +} + +/* allocate physical page for `va`, mapping it into `pgdir`, + return the kernel virtual address for the page. + */ + +uint32_t check_page_map(uintptr_t vta, uintptr_t pgdir) { + uint64_t vpn[] = { + (vta >> 12) & ~(~0 << 9), // vpn0 + (vta >> 21) & ~(~0 << 9), // vpn1 + (vta >> 30) & ~(~0 << 9) // vpn2 + }; + PTE *page_base = (uint64_t *)pgdir; + PTE *second_page = NULL; + PTE *third_page = NULL; + if (((page_base[vpn[2]]) & _PAGE_PRESENT) == 0) { + return 1; + } else { + second_page = (PTE *)pa2kva((get_pfn(page_base[vpn[2]]) << NORMAL_PAGE_SHIFT)); + } + + if (((second_page[vpn[1]]) & _PAGE_PRESENT) == 0) { + return 1; + } else { + third_page = (PTE *)pa2kva((get_pfn(second_page[vpn[1]]) << NORMAL_PAGE_SHIFT)); + } + + if ((third_page[vpn[0]] & _PAGE_PRESENT) == 0) { + return 1; + } else { + return 0; + } +} + +uintptr_t free_page_helper(uintptr_t va, uintptr_t pgdir) { + uint64_t vpn[] = {(va >> 12) & ~(~0 << 9), (va >> 21) & ~(~0 << 9), (va >> 30) & ~(~0 << 9)}; + PTE *page_base = (uint64_t *)pgdir; + PTE *second_page = NULL; + PTE *third_page = NULL; + if ((page_base[vpn[2]] & _PAGE_PRESENT )== 0) { + return -1; + } + second_page = (PTE *)pa2kva((get_pfn(page_base[vpn[2]]) << NORMAL_PAGE_SHIFT)); + if ((second_page[vpn[1]] & _PAGE_PRESENT) == 0) { + return -1; + } + third_page = (PTE *)pa2kva((get_pfn(second_page[vpn[1]]) << NORMAL_PAGE_SHIFT)); + k_free_page(get_kva_of(va, pgdir), 1); + third_page[vpn[0]] = 0; + return 0; +} + +long sys_brk(unsigned long brk) { + if (brk > ROUND((*current_running)->user_sp, NORMAL_PAGE_SIZE)) { + return -EINVAL; + } + if (brk == 0) { + return (*current_running)->elf.edata; + } + if (brk < (*current_running)->elf.edata) { + for (uintptr_t iterator = brk; iterator < (*current_running)->elf.edata; iterator += NORMAL_PAGE_SIZE) { + if (get_kva_of(iterator, (*current_running)->pgdir)) { + free_page_helper(iterator, (*current_running)->pgdir); + } + } + } else { + for (uintptr_t iterator = (*current_running)->elf.edata; iterator < brk; iterator += NORMAL_PAGE_SIZE) { + k_alloc_page_helper(iterator, (pa2kva((*current_running)->pgdir << 12))); + local_flush_tlb_all(); + } + } + (*current_running)->elf.edata = brk; + return brk; } \ No newline at end of file diff --git a/src/kernel/sync/lock.c b/src/kernel/sync/lock.c index 4073590bb005abe3711cfdc0043c17deec589452..a9cdad9e51d343649204953451085d857f68dad8 100644 --- a/src/kernel/sync/lock.c +++ b/src/kernel/sync/lock.c @@ -6,16 +6,22 @@ int first_time = 1; mutex_lock_t *locks[LOCK_NUM]; -void spin_lock_init(spin_lock_t *lock) { lock->flag = UNLOCKED; } +void spin_lock_init(spin_lock_t *lock) { + lock->flag = UNLOCKED; +} -int spin_lock_try_acquire(spin_lock_t *lock) { return atomic_swap_d(LOCKED, (ptr_t)&lock->flag); } +int spin_lock_try_acquire(spin_lock_t *lock) { + return atomic_swap_d(LOCKED, (ptr_t)&lock->flag); +} void spin_lock_acquire(spin_lock_t *lock) { while (spin_lock_try_acquire(lock) == LOCKED) ; } -void spin_lock_release(spin_lock_t *lock) { lock->flag = UNLOCKED; } +void spin_lock_release(spin_lock_t *lock) { + lock->flag = UNLOCKED; +} long k_mutex_lock_op(int *key, int op) { if (op == 0) { @@ -44,7 +50,7 @@ static inline int find_lock() { long k_mutex_lock_init(int *key) { if (first_time) { for (int i = 0; i < LOCK_NUM; i++) { - locks[i] = (mutex_lock_t *)kmalloc(sizeof(mutex_lock_t)); + locks[i] = (mutex_lock_t *)k_malloc(sizeof(mutex_lock_t)); locks[i]->initialized = 0; } first_time = 0; @@ -78,10 +84,10 @@ long k_mutex_lock_acquire(int key) { if (locks[key]->lock.flag == 0) { locks[key]->lock.flag = 1; locks[key]->lock.guard = 0; - (*current_running)->lockid[(*current_running)->locksum++] = key + 1; + (*current_running)->lock_ids[(*current_running)->locksum++] = key + 1; return locks[key]->lock_id; } else { - k_block(&(*current_running)->list, &locks[key]->block_queue); + k_block(&(*current_running)->list, &locks[key]->block_queue, ENQUEUE_LIST); locks[key]->lock.guard = 0; k_scheduler(); return -2; @@ -93,7 +99,7 @@ long k_mutex_lock_release(int key) { return -1; } if ((*current_running)->locksum) { - (*current_running)->lockid[--(*current_running)->locksum] = 0; + (*current_running)->lock_ids[--(*current_running)->locksum] = 0; } while (atomic_cmpxchg(UNGUARDED, GUARDED, (ptr_t) & (locks[key]->lock.guard)) == GUARDED) { ; @@ -112,9 +118,9 @@ long k_mutex_lock_destroy(int *key) { return -1; } while ((*current_running)->locksum) { - (*current_running)->lockid[--(*current_running)->locksum] = 0; + (*current_running)->lock_ids[--(*current_running)->locksum] = 0; } - memset(locks[*key - 1], 0, sizeof(locks[*key])); + k_memset(locks[*key - 1], 0, sizeof(mutex_lock_t *)); *key = 0; return 0; } diff --git a/src/kernel/sync/sync.c b/src/kernel/sync/sync.c index d30614a0f30e346f7d81c12d16e5f90cd8044ed8..e797e31e4f33fd0faeaeeb723a6b187679ba365d 100644 --- a/src/kernel/sync/sync.c +++ b/src/kernel/sync/sync.c @@ -1,3 +1,4 @@ +#include <lib/math.h> #include <lib/string.h> #include <os/lock.h> #include <os/pcb.h> @@ -85,11 +86,11 @@ int k_commop(void *key_id, void *arg, int op) { case 7: return k_mbox_open((char *)key_id); case 8: - return k_mbox_close(); + return k_mbox_close((char *)key_id); case 9: - return k_mbox_send(*key - 1, (mbox_arg_t *)arg); + return k_mbox_send(*key - 1, NULL, (mbox_arg_t *)arg); case 10: - return k_mbox_recv(*key - 1, (mbox_arg_t *)arg); + return k_mbox_recv(*key - 1, NULL, (mbox_arg_t *)arg); case 11: return k_mbox_try_send(*key - 1, (mbox_arg_t *)arg); case 12: @@ -104,7 +105,7 @@ int k_commop(void *key_id, void *arg, int op) { int k_semaphore_init(int *key, int sem) { if (sem_first_time) { for (int i = 0; i < COMM_NUM; i++) { - sem_list[i] = (Semaphore_t *)kmalloc(sizeof(Semaphore_t)); + sem_list[i] = (Semaphore_t *)k_malloc(sizeof(Semaphore_t)); sem_list[i]->sem_info.initialized = 0; } sem_first_time = 0; @@ -133,7 +134,7 @@ int k_semaphore_p(int key) { } sem_list[key]->sem--; if (sem_list[key]->sem < 0) { - k_block(&(*current_running)->list, &sem_list[key]->wait_queue); + k_block(&(*current_running)->list, &sem_list[key]->wait_queue, ENQUEUE_LIST); k_scheduler(); } return 0; @@ -154,7 +155,7 @@ int k_semaphore_destroy(int *key) { if (!sem_list[*key - 1]->sem_info.initialized) { return -1; } - memset(sem_list[*key - 1], 0, sizeof(sem_list[*key - 1])); + k_memset(sem_list[*key - 1], 0, sizeof(Semaphore_t *)); *key = 0; return 0; } @@ -162,7 +163,7 @@ int k_semaphore_destroy(int *key) { int k_cond_init(int *key) { if (cond_first_time) { for (int i = 0; i < COMM_NUM; i++) { - cond_list[i] = (cond_t *)kmalloc(sizeof(cond_t)); + cond_list[i] = (cond_t *)k_malloc(sizeof(cond_t)); cond_list[i]->cond_info.initialized = 0; } cond_first_time = 0; @@ -190,7 +191,7 @@ int k_cond_wait(int key) { return -1; } cond_list[key]->num_wait++; - k_block(&(*current_running)->list, &cond_list[key]->wait_queue); + k_block(&(*current_running)->list, &cond_list[key]->wait_queue, ENQUEUE_LIST); k_scheduler(); return 0; } @@ -221,7 +222,7 @@ int k_cond_destroy(int *key) { if (!cond_list[*key - 1]->cond_info.initialized) { return -1; } - memset(cond_list[*key - 1], 0, sizeof(cond_list[*key])); + k_memset(cond_list[*key - 1], 0, sizeof(cond_t *)); *key = 0; return 0; } @@ -229,7 +230,7 @@ int k_cond_destroy(int *key) { int k_barrier_init(int *key, int total) { if (barrier_first_time) { for (int i = 0; i < COMM_NUM; i++) { - barrier_list[i] = (barrier_t *)kmalloc(sizeof(barrier_t)); + barrier_list[i] = (barrier_t *)k_malloc(sizeof(barrier_t)); barrier_list[i]->barrier_info.initialized = 0; } barrier_first_time = 0; @@ -272,7 +273,7 @@ int k_barrier_destroy(int *key) { return -1; } k_cond_destroy(&barrier_list[*key - 1]->cond_id); - memset(barrier_list[*key - 1], 0, sizeof(barrier_list[*key - 1])); + k_memset(barrier_list[*key - 1], 0, sizeof(barrier_t *)); *key = 0; return 0; } @@ -281,7 +282,7 @@ int k_mbox_open(char *name) { int operator= sys_getpid(); if (mbox_first_time) { for (int i = 0; i < COMM_NUM; i++) { - mbox_list[i] = (mbox_t *)kmalloc(sizeof(mbox_t)); + mbox_list[i] = (mbox_t *)k_malloc(sizeof(mbox_t)); mbox_list[i]->mailbox_info.initialized = 0; } mbox_first_time = 0; @@ -290,9 +291,8 @@ int k_mbox_open(char *name) { return -2; } for (int i = 0; i < COMM_NUM; i++) { - if (mbox_list[i]->mailbox_info.initialized && strcmp(mbox_list[i]->name, name) == 0) { + if (mbox_list[i]->mailbox_info.initialized && k_strcmp(mbox_list[i]->name, name) == 0) { mbox_list[i]->cited_pid[mbox_list[i]->cited_num++] = operator; - pcb[operator-1].mboxid[pcb[operator-1].mboxsum++] = i + 1; return i + 1; } } @@ -302,84 +302,92 @@ int k_mbox_open(char *name) { } mbox_list[mbox_i]->mailbox_info.id = mbox_i + 1; mbox_list[mbox_i]->mailbox_info.initialized = 1; - strcpy(mbox_list[mbox_i]->name, name); - memset(mbox_list[mbox_i]->buff, 0, sizeof(mbox_list[mbox_i]->buff)); - mbox_list[mbox_i]->read_head = 0; - mbox_list[mbox_i]->write_tail = 0; - mbox_list[mbox_i]->used_units = 0; - mbox_list[mbox_i]->full_cond_id = 0; - mbox_list[mbox_i]->empty_cond_id = 0; + k_strcpy(mbox_list[mbox_i]->name, name); + // k_memset(mbox_list[mbox_i]->buff, 0, sizeof(mbox_list[mbox_i]->buff)); + // mbox_list[mbox_i]->read_head = 0; + // mbox_list[mbox_i]->write_tail = 0; + // mbox_list[mbox_i]->used_units = 0; + // mbox_list[mbox_i]->full_cond_id = 0; + // mbox_list[mbox_i]->empty_cond_id = 0; k_cond_init(&mbox_list[mbox_i]->full_cond_id); k_cond_init(&mbox_list[mbox_i]->empty_cond_id); - memset(mbox_list[mbox_i]->cited_pid, 0, sizeof(mbox_list[mbox_i]->cited_pid)); - mbox_list[mbox_i]->cited_num = 0; + // k_memset(mbox_list[mbox_i]->cited_pid, 0, sizeof(mbox_list[mbox_i]->cited_pid)); + // mbox_list[mbox_i]->cited_num = 0; mbox_list[mbox_i]->cited_pid[mbox_list[mbox_i]->cited_num++] = operator; - pcb[operator-1].mboxid[pcb[operator-1].mboxsum++] = mbox_i + 1; return mbox_i + 1; } -int k_mbox_close() { +int k_mbox_close(int mbox_id) { int operator= sys_getpid(); - for(int i = 0; i < pcb[operator-1].mboxsum; i++){ - mbox_list[pcb[operator-1].mboxid[i] - 1]->cited_num--; - if(mbox_list[pcb[operator-1].mboxid[i] - 1]->cited_num == 0){ - k_cond_destroy(&mbox_list[pcb[operator-1].mboxid[i] - 1]->full_cond_id); - k_cond_destroy(&mbox_list[pcb[operator-1].mboxid[i] - 1]->empty_cond_id); - memset(mbox_list[pcb[operator-1].mboxid[i] - 1],0,sizeof(mbox_list[pcb[operator-1].mboxid[i] - 1])); + mbox_t *target = mbox_list[mbox_id]; + for (int i = 0; i < target->cited_num; i++) { + if (target->cited_pid[i] == operator) { + target->cited_pid[i] = 0; } } + if (!target->cited_num) { + k_cond_destroy(&target->full_cond_id); + k_cond_destroy(&target->empty_cond_id); + k_memset((void *)target, 0, sizeof(mbox_t)); + } return 0; } -int k_mbox_send(int key, mbox_arg_t *arg) { - if (!mbox_list[key]->mailbox_info.initialized) { +int k_mbox_send(int key, mbox_t *target, mbox_arg_t *arg) { + if (!target) { + target = mbox_list[key]; + } + if (!target->mailbox_info.initialized) { return -1; } if (arg->sleep_operation == 1 && k_mbox_try_send(key, arg) < 0) { return -2; } int blocked_time = 0; - while (arg->msg_length > MBOX_MSG_MAX_LEN - mbox_list[key]->used_units) { + while (arg->msg_length > MBOX_MSG_MAX_LEN - target->used_units) { blocked_time++; - k_cond_wait(mbox_list[key]->full_cond_id - 1); + k_cond_wait(target->full_cond_id - 1); } - int left_space = MBOX_MSG_MAX_LEN - (mbox_list[key]->write_tail + arg->msg_length); + int left_space = MBOX_MSG_MAX_LEN - (target->write_tail + arg->msg_length); if (left_space < 0) { - memcpy((uint8_t *)mbox_list[key]->buff + mbox_list[key]->write_tail, arg->msg, MBOX_MSG_MAX_LEN - mbox_list[key]->write_tail); - memcpy((uint8_t *)mbox_list[key]->buff, arg->msg + MBOX_MSG_MAX_LEN - mbox_list[key]->write_tail, -left_space); - mbox_list[key]->write_tail = -left_space; + k_memcpy((uint8_t *)target->buff + target->write_tail, arg->msg, MBOX_MSG_MAX_LEN - target->write_tail); + k_memcpy((uint8_t *)target->buff, arg->msg + MBOX_MSG_MAX_LEN - target->write_tail, -left_space); + target->write_tail = -left_space; } else { - memcpy((uint8_t *)mbox_list[key]->buff + mbox_list[key]->write_tail, arg->msg, arg->msg_length); - mbox_list[key]->write_tail += arg->msg_length; + k_memcpy((uint8_t *)target->buff + target->write_tail, arg->msg, arg->msg_length); + target->write_tail += arg->msg_length; } - mbox_list[key]->used_units += arg->msg_length; - k_cond_broadcast(mbox_list[key]->empty_cond_id - 1); + target->used_units += arg->msg_length; + k_cond_broadcast(target->empty_cond_id - 1); return blocked_time; } -int k_mbox_recv(int key, mbox_arg_t *arg) { - if (!mbox_list[key]->mailbox_info.initialized) { +int k_mbox_recv(int key, mbox_t *target, mbox_arg_t *arg) { + if (!target) { + target = mbox_list[key]; + } + if (!target->mailbox_info.initialized) { return -1; } if (arg->sleep_operation == 1 && k_mbox_try_recv(key, arg) < 0) { return -2; } int blocked_time = 0; - while (arg->msg_length > mbox_list[key]->used_units) { + while (arg->msg_length > target->used_units) { blocked_time++; - k_cond_wait(mbox_list[key]->empty_cond_id - 1); + k_cond_wait(target->empty_cond_id - 1); } - int left_space = MBOX_MSG_MAX_LEN - (mbox_list[key]->read_head + arg->msg_length); + int left_space = MBOX_MSG_MAX_LEN - (target->read_head + arg->msg_length); if (left_space < 0) { - memcpy((uint8_t *)arg->msg, (const uint8_t *)mbox_list[key]->buff + mbox_list[key]->read_head, MBOX_MSG_MAX_LEN - mbox_list[key]->read_head); - memcpy((uint8_t *)arg->msg + MBOX_MSG_MAX_LEN - mbox_list[key]->read_head, (const uint8_t *)mbox_list[key]->buff, -left_space); - mbox_list[key]->read_head = -left_space; + k_memcpy((uint8_t *)arg->msg, (const uint8_t *)target->buff + target->read_head, MBOX_MSG_MAX_LEN - target->read_head); + k_memcpy((uint8_t *)arg->msg + MBOX_MSG_MAX_LEN - target->read_head, (const uint8_t *)target->buff, -left_space); + target->read_head = -left_space; } else { - memcpy((uint8_t *)arg->msg, (const uint8_t *)mbox_list[key]->buff + mbox_list[key]->read_head, arg->msg_length); - mbox_list[key]->read_head += arg->msg_length; + k_memcpy((uint8_t *)arg->msg, (const uint8_t *)target->buff + target->read_head, arg->msg_length); + target->read_head += arg->msg_length; } - mbox_list[key]->used_units -= arg->msg_length; - k_cond_broadcast(mbox_list[key]->full_cond_id - 1); + target->used_units -= arg->msg_length; + k_cond_broadcast(target->full_cond_id - 1); return blocked_time; } @@ -401,4 +409,44 @@ int k_mbox_try_recv(int key, mbox_arg_t *arg) { return -2; } return 0; +} + +void k_pcb_mbox_init(pcb_mbox_t *target, int owner_id) { + k_memset((void *)&(target), 0, sizeof(pcb_mbox_t)); + target->pcb_i = owner_id; +} + +int sys_mailread(void *buf, int len) { + pcb_mbox_t *target = &(*current_running)->mbox; + if (len == 0) { + if (target->used_units) { + return 0; + } else { + return -1; + } + } else if (len > PCB_MBOX_MSG_MAX_LEN) { + len = PCB_MBOX_MSG_MAX_LEN; + } + int str_len = k_strlen((const char *)target->buff[target->read_head]); + k_memcpy((uint8_t *)buf, (uint8_t *)target->buff[target->read_head], k_min(len, str_len)); + target->read_head = (target->read_head + 1) % PCB_MBOX_MAX_MSG_NUM; + target->used_units--; + return len; +} + +int sys_mailwrite(int pid, void *buf, int len) { + pcb_mbox_t *target = &(*current_running)->mbox; + if (len == 0) { + if (target->used_units == PCB_MBOX_MAX_MSG_NUM) { + return -1; + } else { + return 0; + } + } else if (len > PCB_MBOX_MSG_MAX_LEN) { + len = PCB_MBOX_MSG_MAX_LEN; + } + k_memcpy((uint8_t *)target->buff[target->write_head], (uint8_t *)buf, len); + target->write_head = (target->write_head + 1) % PCB_MBOX_MAX_MSG_NUM; + target->used_units++; + return len; } \ No newline at end of file diff --git a/src/kernel/sys/cpu.c b/src/kernel/sys/cpu.c new file mode 100644 index 0000000000000000000000000000000000000000..cf8f5463d222f84a024360962e84c6539c700996 --- /dev/null +++ b/src/kernel/sys/cpu.c @@ -0,0 +1 @@ +#include <os/cpu.h> \ No newline at end of file diff --git a/src/kernel/sys/sys.c b/src/kernel/sys/info.c similarity index 77% rename from src/kernel/sys/sys.c rename to src/kernel/sys/info.c index 427d217e877b7e8b32f958069d8b64ce33b0b7ef..09d9a0f608ae63b032232adb268dfc44d358b836 100644 --- a/src/kernel/sys/sys.c +++ b/src/kernel/sys/info.c @@ -4,6 +4,6 @@ uname_t uname_550w = {.sysname = "MOSS", .nodename = "oscomp", .release = "1.0.0", .version = "#1", .machine = "550W", .domainname = "bluespace.moss.com"}; long sys_uname(uname_t *dest) { - memcpy((uint8_t *)dest, (uint8_t *)&uname_550w, sizeof(uname_550w)); + k_memcpy((uint8_t *)dest, (uint8_t *)&uname_550w, sizeof(uname_t)); return 0; } \ No newline at end of file diff --git a/src/kernel/sys/pcb.c b/src/kernel/sys/pcb.c index f33bdd53d5cd5deeb6cce6947a26d1bd518c83db..f382bcde6802d1df959b1128f885cf5d5b547fa0 100644 --- a/src/kernel/sys/pcb.c +++ b/src/kernel/sys/pcb.c @@ -3,22 +3,16 @@ #include <asm/stack.h> #include <common/elf.h> #include <drivers/screen.h> -#include <lib/list.h> +#include <fs/fs.h> +#include <lib/math.h> #include <lib/stdio.h> #include <lib/string.h> #include <os/irq.h> #include <os/lock.h> #include <os/pcb.h> #include <os/smp.h> -#include <os/time.h> #include <user/user_programs.h> -pid_t process_id = 1; -int allocpid = 0; - -list_node_t *avalable0[20]; -list_node_t *avalable1[20]; - pcb_t *volatile current_running0; pcb_t *volatile current_running1; pcb_t **volatile current_running; @@ -29,80 +23,112 @@ pcb_t pcb[NUM_MAX_TASK]; const ptr_t pid0_stack = INIT_KERNEL_STACK + PAGE_SIZE * 3 - 112 - 288; const ptr_t pid0_stack2 = INIT_KERNEL_STACK + PAGE_SIZE * 4 - 112 - 288; -pcb_t pid0_pcb = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack, .user_sp = (ptr_t)pid0_stack, .preempt_count = 0}; -pcb_t pid0_pcb2 = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack2, .user_sp = (ptr_t)pid0_stack2, .preempt_count = 0}; - -int freepidnum = 0; -int nowpid = 1; -int glmask = 3; -int glvalid = 0; +pcb_t pid0_pcb = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack, .user_sp = (ptr_t)pid0_stack}; +pcb_t pid0_pcb2 = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack2, .user_sp = (ptr_t)pid0_stack2}; pid_t freepid[NUM_MAX_TASK]; pid_t nextpid() { - if (freepidnum != 0) - return freepid[freepidnum--]; - else - return nowpid++; + for (int i = 0; i < NUM_MAX_TASK; i++) { + if (!pcb[i].in_use) { + return i; + } + } + while (true) { + return nextpid(); + } } -unsigned x = 0; +void init_pcb_i(int pcb_i, task_type_t type, int pid, int fpid, int tid, int father_pid, uint8_t core_mask) { + init_list_head(&pcb[pcb_i].wait_list); + pcb[pcb_i].in_use = TRUE; + pcb[pcb_i].pid = pid; + pcb[pcb_i].fpid = fpid; + pcb[pcb_i].tid = tid; + pcb[pcb_i].father_pid = father_pid; + pcb[pcb_i].child_num = 0; + k_memset((void *)pcb[pcb_i].child_pids, 0, sizeof(pcb[pcb_i].child_pids)); + k_memset((void *)pcb[pcb_i].child_stat_addrs, 0, sizeof(pcb[pcb_i].child_stat_addrs)); + pcb[pcb_i].child_num = 0; + pcb[pcb_i].threadsum = 0; + k_memset((void *)pcb[pcb_i].thread_ids, 0, sizeof(pcb[pcb_i].child_pids)); + pcb[pcb_i].type = type; + pcb[pcb_i].status = TASK_READY; + pcb[pcb_i].cursor_x = 1; + pcb[pcb_i].cursor_y = 1; + pcb[pcb_i].priority.priority = 1; + pcb[pcb_i].priority.last_sched_time = 0; + pcb[pcb_i].core_mask[0] = core_mask; + pcb[pcb_i].locksum = 0; + k_pcb_mbox_init(&pcb[pcb_i].mbox, pcb_i); + k_memset((void *)&(pcb[pcb_i].stime_last), 0, sizeof(__kernel_time_t)); + k_memset((void *)&(pcb[pcb_i].utime_last), 0, sizeof(__kernel_time_t)); + k_memset((void *)&(pcb[pcb_i].timer), 0, sizeof(pcbtimer_t)); + pcb[pcb_i].dead_child_stime = 0; + pcb[pcb_i].dead_child_utime = 0; + k_memset((void *)&(pcb[pcb_i].resources), 0, sizeof(rusage_t)); +} -extern int check_wait_recv(int num_packet); +void init_user_stack(ptr_t *user_stack_kva, ptr_t *user_stack, const char *argv[], const char *envp[], const char *file_name) { + int argc = k_strlistlen((char **)argv); + int envpc = k_strlistlen((char **)envp); + int total_length = (argc + envpc + 3) * sizeof(uintptr_t *); + int pointers_length = total_length; + for (int i = 0; i < argc; i++) { + total_length += (k_strlen(argv[i]) + 1); + } + for (int i = 0; i < envpc; i++) { + total_length += (k_strlen(envp[i]) + 1); + } + total_length += (k_strlen(file_name) + 1); + total_length = ROUND(total_length, 0x100); + uintptr_t kargv_pointer = (uintptr_t)user_stack_kva - total_length; + intptr_t kargv = kargv_pointer + pointers_length; + + /* 1. store argc in the lowest */ + *((int *)kargv_pointer) = argc; + kargv_pointer += sizeof(uint64_t); + + /* 2. save argv pointer in 2nd lowest and argv in lowest strings */ + uintptr_t new_argv = (uintptr_t)user_stack - total_length + pointers_length; + for (int i = 0; i < argc; i++) { + *((uintptr_t *)kargv_pointer + i) = new_argv; + k_strcpy((char *)kargv, argv[i]); + new_argv += (k_strlen(argv[i]) + 1); + kargv += (k_strlen(argv[i]) + 1); + } + *((uintptr_t *)kargv_pointer + argc) = 0; + kargv_pointer += (argc + 1) * sizeof(uintptr_t); + + /* 3. save envp pointer in 3rd lowest and envp in 2nd lowest strings */ + for (int i = 0; i < envpc; i++) { + *((uintptr_t *)kargv_pointer + i) = new_argv; + k_strcpy((char *)kargv, envp[i]); + new_argv += k_strlen(envp[i]) + 1; + kargv += k_strlen(envp[i]) + 1; + } + *((uintptr_t *)kargv_pointer + envpc) = 0; -void mysrand(unsigned seed) { x = seed; } + /* 4. save file_name */ + k_strcpy((char *)kargv, file_name); + new_argv = new_argv + k_strlen(file_name) + 1; + kargv += k_strlen(file_name) + 1; -int myrand() { - long long tmp = 0x5deece66dll * x + 0xbll; - x = tmp & 0x7fffffff; - return x; + /* now user_sp is user_stack - total_length */ + user_stack_kva -= total_length; + user_stack -= total_length; } -void init_pcb() { - allocpid = 0; +void k_init_pcb() { + k_memset(&pcb, 0, sizeof(pcb)); for (int i = 0; i < NUM_MAX_TASK; i++) { pcb[i].status = TASK_EXITED; - pcb[i].stime = 0; - pcb[i].stime_last = 0; - pcb[i].utime = 0; - pcb[i].utime_last = 0; - memset(&pcb[i].timer, 0, sizeof(pcb[i].timer)); - } - pcb[0].type = USER_PROCESS; - pcb[0].pid = 0; - pcb[0].fpid = 0; - pcb[0].tid = 0; - pcb[0].threadsum = 0; - pcb[0].status = TASK_READY; - pcb[0].cursor_x = 1; - pcb[0].cursor_y = 1; - pcb[0].priority.priority = 0; - pcb[0].priority.last_sched_time = 0; - pcb[0].mode = AUTO_CLEANUP_ON_EXIT; - pcb[0].wait_list.next = &pcb[0].wait_list; - pcb[0].wait_list.prev = &pcb[0].wait_list; - pcb[0].core_mask = 3; - pcb[0].locksum = 0; - pcb[0].child_num = 0; - pcb[0].father_pid = 0; - ptr_t kernel_stack = get_kernel_address(0); - ptr_t user_stack = kernel_stack - 0x2000; - allocpid = 0; - PTE *pgdir = (PTE *)allocPage(1); - clear_pgdir((uintptr_t)pgdir); - int len = 0; - unsigned char *binary = NULL; - get_elf_file("shell", &binary, &len); - share_pgtable(pgdir, pa2kva(PGDIR_PA)); - void_task test_shell = (void_task)load_elf(binary, len, (ptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))alloc_page_helper); - map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack), pgdir); - init_pcb_stack(kernel_stack, USER_STACK_ADDR, (ptr_t)test_shell, &pcb[0], 0, NULL); - pcb[0].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT; + } current_running0 = &pid0_pcb; - list_add_tail(&(pcb[0].list), &ready_queue); current_running1 = &pid0_pcb2; - timers.next = &timers; - timers.prev = &timers; + (*current_running) = get_current_running(); + init_list_head(&timers); + sys_spawn("shell"); } long sys_setpriority(int which, int who, int niceval) { @@ -117,10 +143,10 @@ long sys_setpriority(int which, int who, int niceval) { case PRIO_PGRP: (*current_running)->priority.priority = niceval; for (int i = 0; i < (*current_running)->child_num; i++) { - pcb[(*current_running)->child_pid[i]].priority.priority = niceval; + pcb[(*current_running)->child_pids[i]].priority.priority = niceval; } for (int i = 0; i < (*current_running)->threadsum; i++) { - pcb[(*current_running)->threadid[i]].priority.priority = niceval; + pcb[(*current_running)->thread_ids[i]].priority.priority = niceval; } break; case PRIO_USER: @@ -156,7 +182,7 @@ pcb_t *choose_sched_task(list_head *queue) { int cpu_id = get_current_cpu_id(); while (list_iterator->next != queue) { pcb_iterator = list_entry(list_iterator, pcb_t, list); - if (!(pcb_iterator->core_mask & (0x1 << cpu_id))) { + if (!(pcb_iterator->core_mask[cpu_id / 8] & (0x1 << (cpu_id % 8)))) { continue; } cur_priority = cal_priority(cur_time, pcb_iterator->priority.last_sched_time, pcb_iterator->priority.priority); @@ -170,23 +196,21 @@ pcb_t *choose_sched_task(list_head *queue) { return max_one; } -void enqueue(list_head *new, list_head *head, int target) { - switch (target) { +void enqueue(list_head *new, list_head *head, enqueue_way_t way) { + switch (way) { case ENQUEUE_LIST: list_add_tail(new, head); - break; - case ENQUEUE_PCB: - { - pcb_t *curr = list_entry(new, pcb_t, list); - list_head *insert_point = head->next; - pcb_t *iterator = list_entry(insert_point, pcb_t, list); - // use >= because of FIFO - while (iterator->priority.priority >= curr->priority.priority && insert_point != &ready_queue) { - insert_point = insert_point->next; - iterator = list_entry(insert_point, pcb_t, list); + case ENQUEUE_TIMER_LIST: { + pcb_t *new_inserter = list_entry(new, pcb_t, list); + list_head *iterator_list = timers.next; + pcb_t *iterator_pcb = NULL; + while (iterator_list != &timers) { + iterator_pcb = list_entry(iterator_list, pcb_t, list); + if (cmp_nanotime(&iterator_pcb->timer.end_time, &new_inserter->timer.end_time) >= 0) { + break; + } } - // for head add to tail, for common position add to front - list_add_tail(&(curr->list), insert_point); + list_add_tail(new, iterator_list); break; } default: @@ -194,7 +218,7 @@ void enqueue(list_head *new, list_head *head, int target) { } } -pcb_t *dequeue(list_head *queue, int target) { +pcb_t *dequeue(list_head *queue, dequeue_way_t target) { // plain and simple way pcb_t *ret = NULL; switch (target) { @@ -209,7 +233,7 @@ pcb_t *dequeue(list_head *queue, int target) { case DEQUEUE_WAITLIST_DESTROY: ret = list_entry(queue->next, pcb_t, wait_list); list_del(&(ret->wait_list)); - memset(&ret->timer, 0, sizeof(ret->timer)); + k_memset(&ret->timer, 0, sizeof(pcbtimer_t)); list_init_with_null(&ret->wait_list); break; case DEQUEUE_LIST_STRATEGY: @@ -222,7 +246,7 @@ pcb_t *dequeue(list_head *queue, int target) { return ret; } -bool check_empty(int cpu_mask) { +bool check_empty(int cpuid) { if (list_is_empty(&ready_queue)) { return TRUE; } else { @@ -230,7 +254,7 @@ bool check_empty(int cpu_mask) { pcb_t *iterator = NULL; while (node != &ready_queue) { iterator = list_entry(node, pcb_t, list); - if (iterator->core_mask & cpu_mask) { + if (iterator->core_mask[cpuid / 8] & (0x1 << (cpuid % 8))) { return FALSE; } node = node->next; @@ -239,13 +263,40 @@ bool check_empty(int cpu_mask) { } } +long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp) { + (*current_running)->timer.initialized = true; + get_nanotime(&(*current_running)->timer.start_time); + add_nanotime(rqtp, &(*current_running)->timer.start_time, &(*current_running)->timer.end_time); + (*current_running)->timer.remain_time = rmtp; + k_block(&((*current_running)->list), &timers, ENQUEUE_TIMER_LIST); + k_scheduler(); + return 0; +} + +void check_sleeping() { + list_node_t *q; + nanotime_val_t now_time; + list_head *p = timers.next; + get_nanotime(&now_time); + while (p != &timers) { + pcb_t *p_pcb = list_entry(p, pcb_t, list); + if (cmp_nanotime(&now_time, &p_pcb->timer.end_time) >= 0) { + q = p->next; + k_unblock(p, &ready_queue, UNBLOCK_TO_LIST_STRATEGY); + p = q; + } else { + break; + } + } +} + long k_scheduler(void) { if (!list_is_empty(&timers)) { check_sleeping(); } pcb_t *curr = (*current_running); int cpuid = get_current_cpu_id(); - bool ready_queue_empty = check_empty(0x1 << cpuid); + bool ready_queue_empty = check_empty(cpuid); if (ready_queue_empty && curr->pid != 0 && curr->status == TASK_RUNNING) { return 0; } else if (ready_queue_empty) { @@ -262,7 +313,7 @@ long k_scheduler(void) { (*current_running) = curr; } if (curr->status == TASK_RUNNING && curr->pid != 0) { - enqueue(&curr->list, &ready_queue, ENQUEUE_PCB); + enqueue(&curr->list, &ready_queue, ENQUEUE_LIST); } pcb_t *next_pcb = dequeue(&ready_queue, DEQUEUE_LIST_STRATEGY); pcb_move_cursor(screen_cursor_x, screen_cursor_y); @@ -285,59 +336,28 @@ long sys_sched_yield(void) { return k_scheduler(); } -long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp) { - (*current_running)->timer.initialized = true; - copy_nanotime(&(*current_running)->timer.time, rqtp); - get_nanotime(&(*current_running)->timer.start_time); - k_block(&((*current_running)->list), &timers); - k_scheduler(); - // note: you can assume: 1 second = `timebase` ticks - // 1. block the (*current_running) - // 2. create a timer which calls `do_unblock` when timeout - // 3. reschedule because the (*current_running) is blocked. - return 0; -} - -void check_sleeping() { - list_node_t *q; - nanotime_val_t now_time; - list_head *p = timers.next; - while (p != &timers) { - get_nanotime(&now_time); - nanotime_val_t res_time; - pcb_t *p_pcb = list_entry(p, pcb_t, list); - minus_nanotime(&now_time, &p_pcb->timer.start_time, &res_time); - if (cmp_nanotime(&res_time, &p_pcb->timer.time) >= 0) { - q = p->next; - k_unblock(p, &ready_queue, UNBLOCK_TO_LIST_STRATEGY); - p = q; - } else - p = p->next; - } -} - -void k_block(list_node_t *pcb_node, list_head *queue) { - list_add_tail(pcb_node, queue); +void k_block(list_node_t *pcb_node, list_head *queue, enqueue_way_t way) { + enqueue(pcb_node, queue, way); (*current_running)->status = TASK_BLOCKED; } -void k_unblock(list_head *from_queue, list_head *to_queue, int way) { +void k_unblock(list_head *from_queue, list_head *to_queue, unblock_way_t way) { // TODO: unblock the `pcb` from the block queue pcb_t *fetch_pcb = NULL; switch (way) { case UNBLOCK_TO_LIST_FRONT: - fetch_pcb = dequeue(from_queue->prev, 0); + fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST); list_add(&fetch_pcb->list, to_queue); break; case UNBLOCK_TO_LIST_BACK: - fetch_pcb = dequeue(from_queue->prev, 0); + fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST); list_add_tail(&fetch_pcb->list, to_queue); break; case UNBLOCK_ONLY: - fetch_pcb = dequeue(from_queue->prev, 0); + fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST); break; case UNBLOCK_TO_LIST_STRATEGY: - fetch_pcb = dequeue(from_queue->prev, 2); + fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST_STRATEGY); list_add_tail(&fetch_pcb->list, to_queue); break; default: @@ -346,91 +366,76 @@ void k_unblock(list_head *from_queue, list_head *to_queue, int way) { fetch_pcb->status = TASK_READY; } -long k_taskset(int pid, int mask) { - int id = get_current_cpu_id(); - if (pid == 0) { - if (mask != 3 && mask != 1 + id) { - glmask = mask; - glvalid = 1; - return 1; - } else - glvalid = 0; +long sys_sched_setaffinity(pid_t pid, unsigned int len, const byte_size_t *user_mask_ptr) { + if (pid > NUM_MAX_TASK) { + return -EINVAL; } - pcb_t *target = &pcb[pid]; - if (pid > NUM_MAX_TASK || target->status == TASK_EXITED || target->status == TASK_ZOMBIE) - return 0; - target->core_mask = mask; - return 1; + pcb_t *target = pid ? &pcb[pid] : (*current_running); + if (target->status == TASK_EXITED) { + return -EINVAL; + } + int core_len = CPU_SET_SIZE; + int copy_len = k_min(core_len, len); + k_memcpy(target->core_mask, user_mask_ptr, copy_len); + return 0; +} + +long sys_sched_getaffinity(pid_t pid, unsigned int len, uint8_t *user_mask_ptr) { + if (pid > NUM_MAX_TASK) { + return -EINVAL; + } + pcb_t *target = pid ? &pcb[pid] : (*current_running); + if (target->status == TASK_EXITED) { + return -EINVAL; + } + int core_len = CPU_SET_SIZE; + int copy_len = k_min(core_len, len); + k_memcpy(user_mask_ptr, target->core_mask, copy_len); + return 0; } -long sys_spawn(task_info_t *info, void *arg, spawn_mode_t mode) { +long sys_spawn(const char *file_name) { int i = nextpid(); - pcb[i].type = info->type; - pcb[i].pid = i; - pcb[i].status = TASK_READY; - pcb[i].cursor_x = 1; - pcb[i].cursor_y = 1; - pcb[i].priority.priority = 0; - pcb[i].priority.last_sched_time = 0; - pcb[i].mode = mode; - pcb[i].wait_list.next = &pcb[i].wait_list; - pcb[i].wait_list.prev = &pcb[i].wait_list; - pcb[i].pgdir = 0; - if (glvalid) - pcb[i].core_mask = glmask; - else - pcb[i].core_mask = (*current_running)->core_mask; - pcb[i].locksum = 0; + + init_pcb_i(i, USER_PROCESS, i, i, 0, 0, (*current_running)->core_mask[0]); + ptr_t kernel_stack = get_kernel_address(i); - ptr_t user_stack = kernel_stack - 0x1000; - /* TODO: use glibc argument passing standards to restructure */ - /* 1, arg is wrong, only for passing compilation */ - init_pcb_stack(kernel_stack, user_stack, (uintptr_t)(info->entry_point), &pcb[i], (uint64_t)arg, NULL); + ptr_t user_stack_kva = kernel_stack - PAGE_SIZE; + PTE *pgdir = (PTE *)k_alloc_page(1); + clear_pgdir((uintptr_t)pgdir); + share_pgtable(pgdir, pa2kva(PGDIR_PA)); + pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT; + + int len = 0; + unsigned char *binary = NULL; + get_elf_file(file_name, &binary, &len); + share_pgtable(pgdir, pa2kva(PGDIR_PA)); + void_task process = (void_task)load_elf(binary, len, (ptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))k_alloc_page_helper); + map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir); + + init_pcb_stack(kernel_stack, user_stack_kva, (uintptr_t)(process), &pcb[i]); list_add_tail(&pcb[i].list, &ready_queue); return i; } -long sys_fork(int prior) { - - pid_t fpid = (*current_running)->pid; +long sys_fork() { int i = nextpid(); + pid_t fpid = (*current_running)->pid; + + init_pcb_i(i, USER_PROCESS, i, i, 0, fpid, (*current_running)->core_mask[0]); - pcb[fpid].child_pid[pcb[fpid].child_num] = i; + pcb[fpid].child_pids[pcb[fpid].child_num] = i; pcb[fpid].child_num++; - pcb[i].father_pid = fpid; - pcb[i].tid = 0; - pcb[i].fpid = i; - pcb[i].type = USER_PROCESS; - pcb[i].pid = i; - pcb[i].status = TASK_READY; - pcb[i].cursor_x = 1; - pcb[i].cursor_y = 1; - // pcb[i].priority = prior; - pcb[i].priority.priority = 0; - pcb[i].priority.last_sched_time = 0; - pcb[i].mode = ENTER_ZOMBIE_ON_EXIT; - // pcb[i].mode = AUTO_CLEANUP_ON_EXIT; - pcb[i].wait_list.next = &pcb[i].wait_list; - pcb[i].wait_list.prev = &pcb[i].wait_list; - pcb[i].threadsum = 0; - pcb[i].locksum = 0; - pcb[i].child_num = 0; - if (glvalid) - pcb[i].core_mask = glmask; - else - pcb[i].core_mask = (*current_running)->core_mask; ptr_t kernel_stack_kva = get_kernel_address(i); - ptr_t user_stack_kva = kernel_stack_kva - 0x2000; - - allocpid = i; - PTE *pgdir = (PTE *)allocPage(1); + ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE; + PTE *pgdir = (PTE *)k_alloc_page(1); clear_pgdir((ptr_t)pgdir); - - fork_pcb_stack(kernel_stack_kva, kernel_stack_kva - 0x1000, &pcb[i]); - fork_pgtable(pgdir, (pa2kva(pcb[fpid].pgdir << 12))); share_pgtable(pgdir, pa2kva(PGDIR_PA)); - map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack_kva), pgdir); + + fork_pcb_stack(kernel_stack_kva, user_stack_kva, &pcb[i]); + fork_pgtable(pgdir, (pa2kva((*current_running)->pgdir << NORMAL_PAGE_SHIFT))); + map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir); pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT; @@ -438,42 +443,37 @@ long sys_fork(int prior) { return i; } -long sys_exit(int error_code) { - pcb_t *father = &pcb[(*current_running)->father_pid]; - if (father->child_stat_addrs[(*current_running)->pid]) { - *father->child_stat_addrs[(*current_running)->pid] = error_code; - } - return sys_kill((*current_running)->pid); -} - long sys_kill(pid_t pid) { - pid -= 1; - if (pid < 1 || pid >= NUM_MAX_TASK) { - return -1; + if (pid < 0 || pid >= NUM_MAX_TASK) { + return -EINVAL; } pcb_t *target = &pcb[pid]; if (target->pid == 0) { - return -1; + return -EINVAL; } // realease lock for (int i = 0; i < target->locksum; i++) { - k_mutex_lock_release(target->lockid[i] - 1); - } - if (target->mode == ENTER_ZOMBIE_ON_EXIT) { - // wake up parent - if (target->father_pid > 0) { - pcb_t *parent = &pcb[target->father_pid]; - if (!parent->timer.initialized) { - k_unblock(&parent->list, &ready_queue, UNBLOCK_TO_LIST_STRATEGY); + k_mutex_lock_release(target->lock_ids[i] - 1); + } + if (target->father_pid > 0) { + pcb_t *parent = &pcb[target->father_pid]; + if (!parent->timer.initialized) { + k_unblock(&parent->list, &ready_queue, UNBLOCK_TO_LIST_STRATEGY); + } + for (int i = 0; i < NUM_MAX_CHILD; i++) { + if (parent->child_pids[i] == pid) { + parent->child_pids[i] = 0; + break; } } - target->status = TASK_ZOMBIE; - } else if (target->mode == AUTO_CLEANUP_ON_EXIT) { - target->pid = 0; - target->status = TASK_EXITED; - if(pcb[pid].type!=USER_THREAD) - getback_page(pid); + parent->dead_child_stime += get_ticks_from_time(&target->resources.ru_stime); + parent->dead_child_utime += get_ticks_from_time(&target->resources.ru_utime); + } + target->pid = 0; + target->status = TASK_EXITED; + if (pcb[pid].type != USER_THREAD) { + getback_page(pid); } // give up its sons for (int i = 0; i < NUM_MAX_TASK; i++) { @@ -481,25 +481,39 @@ long sys_kill(pid_t pid) { pcb[i].father_pid = target->father_pid; } } - if (target->list.next) + if (target->list.next) { list_del(&target->list); - if ((*current_running)->pid == pid + 1 || (*current_running)->pid == 0 || target->mode == AUTO_CLEANUP_ON_EXIT) { + } + target->exit_status = -1; + if ((*current_running)->pid == pid + 1 || (*current_running)->pid == 0) { k_scheduler(); } return 0; } +long sys_exit(int error_code) { + if ((*current_running)->father_pid > 0) { + pcb_t *father = &pcb[(*current_running)->father_pid]; + if (father->child_stat_addrs[(*current_running)->pid]) { + *father->child_stat_addrs[(*current_running)->pid] = error_code; + } + } + sys_kill((*current_running)->pid); + (*current_running)->exit_status = error_code; + return 0; +} + long sys_wait4(pid_t pid, int *stat_addr, int options, rusage_t *ru) { pcb_t *target = &pcb[pid]; - while (target->status != TASK_EXITED && target->status != TASK_ZOMBIE) { - k_block(&(*current_running)->list, &target->wait_list); + while (target->status != TASK_EXITED) { + k_block(&(*current_running)->list, &target->wait_list, ENQUEUE_LIST); k_scheduler(); } - if (target->status == TASK_ZOMBIE) { - freepidnum++; - freepid[freepidnum] = pid; - target->status = TASK_EXITED; + target->status = TASK_EXITED; + if (stat_addr) { + *stat_addr = (target->exit_status << 8); } + k_memcpy((uint8_t *)ru, (uint8_t *)&target->resources, sizeof(rusage_t)); return 1; } @@ -507,8 +521,9 @@ long sys_process_show() { int num = 0; for (int i = 0; i < NUM_MAX_TASK; i++) { if (pcb[i].status != TASK_EXITED) { - if (num == 0) + if (num == 0) { prints("[PROCESS TABLE]\n"); + } prints("[%d] PID : %d, TID : %d", num, pcb[i].fpid, pcb[i].tid); // pcb[i].tid switch (pcb[i].status) { @@ -518,19 +533,19 @@ long sys_process_show() { case TASK_BLOCKED: sys_screen_write(" STATUS : BLOCKED"); break; - case TASK_ZOMBIE: - sys_screen_write(" STATUS : ZOMBIE"); - break; case TASK_READY: sys_screen_write(" STATUS : READY"); break; + case TASK_EXITED: + sys_screen_write(" STATUS : EXITED"); + break; default: break; } - prints(" MASK : 0x%d", pcb[i].core_mask); + prints(" MASK : 0x%x", (int)pcb[i].core_mask[0]); if (pcb[i].status == TASK_RUNNING) { sys_screen_write(" on Core "); - switch (pcb[i].core_mask) { + switch (pcb[i].core_mask[0]) { case 1: sys_screen_write("0\n"); break; @@ -538,104 +553,116 @@ long sys_process_show() { sys_screen_write("1\n"); break; case 3: - if (&pcb[i] == current_running0) + if (&pcb[i] == current_running0) { sys_screen_write("0\n"); - else if (&pcb[i] == current_running1) + } else if (&pcb[i] == current_running1) { sys_screen_write("1\n"); + } break; default: break; } - } else + } else { sys_screen_write("\n"); + } num++; } } return num + 1; } -extern int try_get_from_file(const char *file_name, unsigned char **binary, int *length); -long sys_exec(const char *name, int argc, char **argv) { +long exec(int pid, const char *file_name, const char *argv[], const char *envp[]) { int len = 0; unsigned char *binary = NULL; /* TODO: use FAT32 disk to read program */ - if (get_elf_file(name, &binary, &len) == 0) { - if (try_get_from_file(name, &binary, &len) == 0) + if (get_elf_file(file_name, &binary, &len) == 0) { + if (try_get_from_file(file_name, &binary, &len) == 0) { return 0; + } } - int i = nextpid(); - pcb[i].fpid = i; - pcb[i].type = USER_PROCESS; - pcb[i].pid = i; - pcb[i].tid = 0; - pcb[i].threadsum = 0; - pcb[i].status = TASK_READY; - pcb[i].cursor_x = 1; - pcb[i].cursor_y = 1; - pcb[i].priority.priority = 0; - pcb[i].priority.last_sched_time = 0; - pcb[i].mode = AUTO_CLEANUP_ON_EXIT; - pcb[i].wait_list.next = &pcb[i].wait_list; - pcb[i].wait_list.prev = &pcb[i].wait_list; - pcb[i].locksum = 0; - pcb[i].child_num = 0; - pcb[i].father_pid = i; - if (glvalid) - pcb[i].core_mask = glmask; - else - pcb[i].core_mask = (*current_running)->core_mask; + int i = pid; + + init_pcb_i(i, USER_PROCESS, i, i, 0, i, (*current_running)->core_mask[0]); + ptr_t kernel_stack_kva = get_kernel_address(i); - ptr_t user_stack_kva = kernel_stack_kva - 0x2000; - allocpid = i; - PTE *pgdir = (PTE *)allocPage(1); + ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE; + ptr_t user_stack = USER_STACK_ADDR; + + PTE *pgdir = (PTE *)k_alloc_page(1); clear_pgdir((uintptr_t)pgdir); share_pgtable(pgdir, pa2kva(PGDIR_PA)); - void_task test_task = (void_task)load_elf(binary, len, (uintptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))alloc_page_helper); - map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack_kva), pgdir); - init_pcb_stack(kernel_stack_kva, USER_STACK_ADDR, (ptr_t)test_task, &pcb[i], argc, argv); + void_task test_task = (void_task)load_elf(binary, len, (uintptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))k_alloc_page_helper); + map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir); pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT; + + init_user_stack(&user_stack_kva, &user_stack, argv, envp, file_name); + + init_pcb_stack(kernel_stack_kva, user_stack, (ptr_t)test_task, &pcb[i]); + list_add_tail(&pcb[i].list, &ready_queue); return i; } -long sys_getpid() { return (*current_running)->fpid; } +long sys_exec(const char *file_name, const char *argv[], const char *envp[]) { + return exec(nextpid(), file_name, argv, envp); +} -long sys_getppid() { return (*current_running)->father_pid; } +long sys_execve(const char *file_name, const char *argv[], const char *envp[]) { + int ret; + ret = exec((*current_running)->pid, file_name, argv, envp); + if (ret) { + k_scheduler(); + } + return ret; +} -long sys_mthread_create(pid_t *thread, void (*start_routine)(void *), void *arg) { - pid_t fpid = (*current_running)->pid; +long sys_clone(unsigned long flags, void *stack, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid) { int i = nextpid(); - pcb[fpid].threadid[pcb[fpid].threadsum] = i; - pcb[fpid].threadsum++; - pcb[i].father_pid = i; - pcb[i].tid = pcb[fpid].threadsum; - pcb[i].fpid = fpid; - pcb[i].type = USER_THREAD; - pcb[i].pid = i; - pcb[i].status = TASK_READY; - pcb[i].cursor_x = 1; - pcb[i].cursor_y = 1; - pcb[i].priority.priority = 0; - pcb[i].priority.last_sched_time = 0; - // pcb[i].mode = ENTER_ZOMBIE_ON_EXIT; - pcb[i].mode = AUTO_CLEANUP_ON_EXIT; - pcb[i].wait_list.next = &pcb[i].wait_list; - pcb[i].wait_list.prev = &pcb[i].wait_list; - pcb[i].threadsum = 0; - pcb[i].locksum = 0; - pcb[i].child_num = 0; - if (glvalid) - pcb[i].core_mask = glmask; - else - pcb[i].core_mask = (*current_running)->core_mask; + pid_t fpid = (*current_running)->pid; + + init_pcb_i(i, USER_PROCESS, i, i, 0, fpid, (*current_running)->core_mask[0]); + if (flags & CLONE_CHILD_SETTID) { + *(int *)child_tid = pcb[i].tid; + } + if (flags & CLONE_PARENT_SETTID) { + *(int *)parent_tid = pcb[i].tid; + } + if (flags & CLONE_CHILD_CLEARTID) { + pcb[i].clear_ctid = (uint32_t *)child_tid; + } + + pcb[fpid].child_pids[pcb[fpid].child_num] = i; + pcb[fpid].child_num++; + ptr_t kernel_stack_kva = get_kernel_address(i); - ptr_t user_stack_kva = kernel_stack_kva - 0x2000; - uint64_t user_stack_uva = USER_STACK_ADDR + 0x1000 * pcb[fpid].threadsum + 0x1000; - pcb[i].pgdir = pcb[fpid].pgdir; - map(user_stack_uva - 0x1000, kva2pa(user_stack_kva), (pa2kva(pcb[i].pgdir << 12))); - init_pcb_stack(kernel_stack_kva, (ptr_t)user_stack_uva, (ptr_t)start_routine, &pcb[i], (uint64_t)arg, NULL); - // add pcb to the ready + ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE; + ptr_t user_stack = (ptr_t)stack ? (ptr_t)stack : USER_STACK_ADDR; + + if (flags & CLONE_VM) { + pcb[i].pgdir = (*current_running)->pgdir; + fork_pgtable((PTE *)(pcb[i].pgdir << NORMAL_PAGE_SHIFT), (pa2kva((*current_running)->pgdir << NORMAL_PAGE_SHIFT))); + } else { + PTE *pgdir = (PTE *)k_alloc_page(1); + clear_pgdir((ptr_t)pgdir); + share_pgtable(pgdir, pa2kva(PGDIR_PA)); + pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT; + } + k_memcpy((uint8_t *)&pcb[i].elf, (uint8_t *)&(*current_running)->elf, sizeof(ELF_info_t)); + + clone_pcb_stack(kernel_stack_kva, user_stack, &pcb[i], flags, tls); + map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pa2kva(pcb[i].pgdir << NORMAL_PAGE_SHIFT)); list_add_tail(&pcb[i].list, &ready_queue); - *thread = i; - return 1; + return i; +} + +long k_getpid(void) { + return (*current_running)->fpid; +} + +long sys_getpid() { + return k_getpid(); +} + +long sys_getppid() { + return (*current_running)->father_pid; } \ No newline at end of file diff --git a/src/kernel/sys/smp.c b/src/kernel/sys/smp.c index 306f1ae16941e54753d0cbb4b96eeb8562cd9e45..6c8ea73591120c6416371c18053a55a980c4afdb 100644 --- a/src/kernel/sys/smp.c +++ b/src/kernel/sys/smp.c @@ -5,15 +5,23 @@ spin_lock_t kernel_lock; -void smp_init() { spin_lock_init(&kernel_lock); } +void smp_init() { + spin_lock_init(&kernel_lock); +} void wakeup_other_hart() { sbi_send_ipi(NULL); __asm__ __volatile__("csrw sip, zero\n\t"); } -void lock_kernel() { spin_lock_acquire(&kernel_lock); } +void lock_kernel() { + spin_lock_acquire(&kernel_lock); +} -void unlock_kernel() { spin_lock_release(&kernel_lock); } +void unlock_kernel() { + spin_lock_release(&kernel_lock); +} -pcb_t *get_current_running() { return get_current_cpu_id() ? current_running1 : current_running0; } +pcb_t *get_current_running() { + return get_current_cpu_id() ? current_running1 : current_running0; +} diff --git a/src/kernel/sys/time.c b/src/kernel/sys/time.c index 7e3f8ae3fb6f676f10237377cf88cce5f32badc3..f7fdd4794369fde2d27c1b9866728e9675ec4913 100644 --- a/src/kernel/sys/time.c +++ b/src/kernel/sys/time.c @@ -15,9 +15,13 @@ long get_ticks() { return time_elapsed; } -uint64_t get_timer() { return get_ticks() / time_base; } +uint64_t get_timer() { + return get_ticks() / time_base; +} -uint64_t get_time_base() { return time_base; } +uint64_t get_time_base() { + return time_base; +} void nano_u_time_converter(nanotime_val_t *nanotime, time_val_t *utime, bool direction) { if (direction) { @@ -35,6 +39,11 @@ void get_nanotime(nanotime_val_t *ntimebuf) { ntimebuf->nsec = ((ticks % time_base) * 1e9) / time_base; } +uint64_t get_ticks_from_nanotime(nanotime_val_t *ntimebuf) { + uint64_t ticks = (ntimebuf->sec * 1e9 + ntimebuf->nsec) * 1e9 / time_base; + return ticks; +} + void copy_nanotime(nanotime_val_t *dst, nanotime_val_t *src) { dst->sec = src->sec; dst->nsec = src->nsec; @@ -50,6 +59,12 @@ void minus_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t * } } +void add_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res) { + int nsec = first->nsec + sec->nsec; + res->nsec = nsec % (int)1e9; + res->sec = first->sec + sec->sec + nsec / (int)1e9; +} + int cmp_nanotime(nanotime_val_t *first, nanotime_val_t *sec) { if (first->sec == sec->sec) { if (first->nsec > sec->nsec) { @@ -72,6 +87,11 @@ void get_utime(time_val_t *utimebuf) { utimebuf->usec = ((ticks % time_base) * 1e6) / time_base; } +uint64_t get_ticks_from_time(time_val_t *ntimebuf) { + uint64_t ticks = (ntimebuf->sec * 1e6 + ntimebuf->usec) * 1e6 / time_base; + return ticks; +} + void copy_utime(time_val_t *dst, time_val_t *src) { dst->sec = src->sec; dst->usec = src->usec; @@ -87,6 +107,12 @@ void minus_utime(time_val_t *first, time_val_t *sec, time_val_t *res) { } } +void add_utime(time_val_t *first, time_val_t *sec, time_val_t *res) { + int usec = first->usec + sec->usec; + res->usec = usec % (int)1e6; + res->sec = first->sec + sec->sec + usec / (int)1e6; +} + int cmp_utime(time_val_t *first, time_val_t *sec) { if (first->sec == sec->sec) { if (first->usec > sec->usec) { @@ -110,11 +136,16 @@ long sys_time(__kernel_time_t *tloc) { } long sys_times(tms_t *tbuf) { - tbuf->tms_stime = (*current_running)->stime; - tbuf->tms_utime = (*current_running)->utime; + tbuf->tms_stime = get_ticks_from_time(&(*current_running)->resources.ru_stime); + tbuf->tms_utime = get_ticks_from_time(&(*current_running)->resources.ru_utime); + tbuf->tms_cstime = (*current_running)->dead_child_stime; + tbuf->tms_cutime = (*current_running)->dead_child_utime; for (int i = 0; i < (*current_running)->child_num; i++) { - tbuf->tms_cstime += pcb[(*current_running)->child_pid[i]].stime; - tbuf->tms_cutime += pcb[(*current_running)->child_pid[i]].utime; + if ((*current_running)->child_pids[i] == 0) { + continue; + } + tbuf->tms_cstime += get_ticks_from_time(&pcb[(*current_running)->child_pids[i]].resources.ru_stime); + tbuf->tms_cutime += get_ticks_from_time(&pcb[(*current_running)->child_pids[i]].resources.ru_utime); } return get_ticks(); } diff --git a/src/libs/math.c b/src/libs/math.c new file mode 100644 index 0000000000000000000000000000000000000000..65898b53dcc39e6f34b9ec16585a4aeb8e7f28ce --- /dev/null +++ b/src/libs/math.c @@ -0,0 +1,8 @@ +#include <lib/math.h> + +int k_min(int a, int b) { + if (a < b) { + return a; + } + return b; +} \ No newline at end of file diff --git a/src/libs/printk.c b/src/libs/printk.c index 179ad6ef69fe4871b5202fe0dbdf87f0a82fc4b7..7d31439561e760f0751a06f5150e440c9182ccc6 100644 --- a/src/libs/printk.c +++ b/src/libs/printk.c @@ -7,8 +7,9 @@ static unsigned int mini_strlen(const char *s) { unsigned int len = 0; - while (s[len] != '\0') + while (s[len] != '\0') { len++; + } return len; } @@ -18,8 +19,9 @@ static unsigned int mini_itoa(long value, unsigned int radix, unsigned int upper unsigned int i, len; /* No support for unusual radixes. */ - if (radix > 16) + if (radix > 16) { return 0; + } if (value < 0 && !unsig) { negative = 1; @@ -42,11 +44,13 @@ static unsigned int mini_itoa(long value, unsigned int radix, unsigned int upper } } while (value != 0); - for (i = (pbuffer - buffer); i < zero_pad; i++) + for (i = (pbuffer - buffer); i < zero_pad; i++) { *(pbuffer++) = '0'; + } - if (negative) + if (negative) { *(pbuffer++) = '-'; + } *(pbuffer) = '\0'; @@ -68,8 +72,9 @@ struct mini_buff { }; static int _putc(int ch, struct mini_buff *b) { - if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len) + if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len) { return 0; + } *(b->pbuffer++) = ch; *(b->pbuffer) = '\0'; return 1; @@ -78,12 +83,14 @@ static int _putc(int ch, struct mini_buff *b) { static int _puts(char *s, unsigned int len, struct mini_buff *b) { unsigned int i; - if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len) + if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len) { len = b->buffer_len - (b->pbuffer - b->buffer) - 1; + } /* Copy to buffer */ - for (i = 0; i < len; i++) + for (i = 0; i < len; i++) { *(b->pbuffer++) = s[i]; + } *(b->pbuffer) = '\0'; return len; @@ -99,11 +106,12 @@ static int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt b.buffer_len = buffer_len; while ((ch = *(fmt++))) { - if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len) + if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len) { break; - if (ch != '%') + } + if (ch != '%') { _putc(ch, &b); - else { + } else { char zero_pad = 0; int longflag = 0; char *ptr; @@ -114,8 +122,9 @@ static int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt /* Zero padding requested */ if (ch == '0') { while ((ch = *(fmt++))) { - if (ch == '\0') + if (ch == '\0') { goto end; + } if (ch >= '0' && ch <= '9') { zero_pad = zero_pad * 10 + ch - '0'; } else { @@ -179,7 +188,6 @@ static int _vprint(const char *fmt, va_list _va, void (*output)(char *)) { buff[ret] = '\0'; - disable_preempt(); output(buff); /*for (int i = 0; i < ret; ++i) { if (buff[i] == '\n') { @@ -190,12 +198,13 @@ static int _vprint(const char *fmt, va_list _va, void (*output)(char *)) { (*current_running)->cursor_x++; } }*/ - enable_preempt(); return ret; } -int vprintk(const char *fmt, va_list _va) { return _vprint(fmt, _va, port_write); } +int vprintk(const char *fmt, va_list _va) { + return _vprint(fmt, _va, port_write); +} int printk(const char *fmt, ...) { __asm__ __volatile__("csrr x0, sscratch\n"); @@ -209,7 +218,9 @@ int printk(const char *fmt, ...) { return ret; } -int vprints(const char *fmt, va_list _va) { return _vprint(fmt, _va, (void (*)(char *))sys_screen_write); } +int vprints(const char *fmt, va_list _va) { + return _vprint(fmt, _va, (void (*)(char *))sys_screen_write); +} int prints(const char *fmt, ...) { int ret = 0; diff --git a/src/libs/string.c b/src/libs/string.c index acb7da1875ddfb42e31b280f448a63eff0bb7041..46f848374321cdb1aafda0f46fe11245f80b409d 100644 --- a/src/libs/string.c +++ b/src/libs/string.c @@ -1,19 +1,18 @@ #include <lib/string.h> -int strlen(const char *src) { +int k_strlen(const char *src) { int i; - for (i = 0; src[i] != '\0'; i++) { - } + for (i = 0; src[i] != '\0'; i++) {} return i; } -void memcpy(uint8_t *dest, const uint8_t *src, uint32_t len) { +void k_memcpy(uint8_t *dest, const uint8_t *src, uint32_t len) { for (; len != 0; len--) { *dest++ = *src++; } } -void memset(void *dest, uint8_t val, uint32_t len) { +void k_memset(void *dest, uint8_t val, uint32_t len) { uint8_t *dst = (uint8_t *)dest; for (; len != 0; len--) { @@ -21,9 +20,11 @@ void memset(void *dest, uint8_t val, uint32_t len) { } } -void bzero(void *dest, uint32_t len) { memset(dest, 0, len); } +void k_bzero(void *dest, uint32_t len) { + k_memset(dest, 0, len); +} -int strcmp(const char *str1, const char *str2) { +int k_strcmp(const char *str1, const char *str2) { while (*str1 && *str2) { if (*str1 != *str2) { return (*str1) - (*str2); @@ -34,7 +35,7 @@ int strcmp(const char *str1, const char *str2) { return (*str1) - (*str2); } -char *strcpy(char *dest, const char *src) { +char *k_strcpy(char *dest, const char *src) { char *tmp = dest; while (*src) { @@ -46,7 +47,7 @@ char *strcpy(char *dest, const char *src) { return tmp; } -char *strcat(char *dest, const char *src) { +char *k_strcat(char *dest, const char *src) { char *tmp = dest; while (*dest != '\0') { @@ -60,3 +61,13 @@ char *strcat(char *dest, const char *src) { return tmp; } + +int k_strlistlen(char *src[]) { + int num = 0; + if (src) { + while (src[num]) { + num++; + } + } + return num; +} \ No newline at end of file diff --git a/src/user/user_programs.c b/src/user/user_programs.c index ead83f4ceed6abcbcf705382c24d9f36d0ecc405..7171b3b6fecd65c125c2d42b8c5563ce037fd8f2 100644 --- a/src/user/user_programs.c +++ b/src/user/user_programs.c @@ -2284,7 +2284,7 @@ int _length___test_test_all_elf = 61944; ElfFile elf_files[8] = {{.file_name = "shell", .file_content = _elf___test_test_shell_elf, .file_length = &_length___test_test_shell_elf}, {.file_name = "fs", .file_content = _elf___test_test_fs_elf, .file_length = &_length___test_test_fs_elf}, {.file_name = "bigfile", .file_content = _elf___test_test_bigfile_elf, .file_length = &_length___test_test_bigfile_elf}, {.file_name = "emo", .file_content = _elf___test_emo_elf, .file_length = &_length___test_emo_elf}, {.file_name = "multi", .file_content = _elf___test_test_multi_elf, .file_length = &_length___test_test_multi_elf}, {.file_name = "check", .file_content = _elf___test_check_elf, .file_length = &_length___test_check_elf}, {.file_name = "fly", .file_content = _elf___test_fly_elf, .file_length = &_length___test_fly_elf}, {.file_name = "all", .file_content = _elf___test_test_all_elf, .file_length = &_length___test_test_all_elf}}; int get_elf_file(const char *file_name, unsigned char **binary, int *length) { for (int i = 0; i < 8; ++i) { - if (strcmp(elf_files[i].file_name, file_name) == 0) { + if (k_strcmp(elf_files[i].file_name, file_name) == 0) { *binary = elf_files[i].file_content; *length = *elf_files[i].file_length; return 1;