diff --git a/lab6/.vscode/c_cpp_properties.json b/lab6/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..9b3b8cfad --- /dev/null +++ b/lab6/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/lab6/.vscode/configurationCache.log b/lab6/.vscode/configurationCache.log index 28e17303b..4a2c63b1a 100644 --- a/lab6/.vscode/configurationCache.log +++ b/lab6/.vscode/configurationCache.log @@ -1 +1 @@ -{"buildTargets":["all","clean","debug","dev","kernel8.img","out","out/allocator.o","out/buffer.o","out/core_timer.o","out/cpio.o","out/dtb.o","out/excep_handler.o","out/exceptions.o","out/getopt.o","out/interrupt_queue.o","out/irq.o","out/irq2.o","out/jump.o","out/loadimg.o","out/local_timer.o","out/mailbox.o","out/main.o","out/math.o","out/mini_uart.o","out/panic.o","out/priority_queue.o","out/queue.o","out/reboot.o","out/scheduler.o","out/shell.o","out/signal.o","out/start.o","out/string.o","out/task.o","out/temp.o","out/thread.o","out/timer.o","run","screen","sender","super","tty","user/out","user/out/main.o","user/out/system.o","usercode.img"],"launchTargets":["/home/yuhu/osc2022/lab123>kernel8.elf()","/home/yuhu/osc2022/lab123>sender()","/home/yuhu/osc2022/lab123>usercode.img()"],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":["/home/yuhu/osc2022/lab123","/home/yuhu/osc2022/lab123/include","/home/yuhu/osc2022/lab123/src","/home/yuhu/osc2022/lab123/user/include","/home/yuhu/osc2022/lab123/user/src"],"compilerArgs":["-g","-Wall","-c","user/src/main.c","-o","user/out/main.o","-fno-stack-protector"],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","windowsSdkVersion":""},"fileIndex":[["/home/yuhu/osc2022/lab123/src/panic.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/panic.c","path":"/home/yuhu/osc2022/lab123/src/panic.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/panic.c","-o","out/panic.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/panic.c"}}],["/home/yuhu/osc2022/lab123/src/core_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/core_timer.c","path":"/home/yuhu/osc2022/lab123/src/core_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/core_timer.c","-o","out/core_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/core_timer.c"}}],["/home/yuhu/osc2022/lab123/src/getopt.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/getopt.c","path":"/home/yuhu/osc2022/lab123/src/getopt.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/getopt.c","-o","out/getopt.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/getopt.c"}}],["/home/yuhu/osc2022/lab123/src/dtb.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/dtb.c","path":"/home/yuhu/osc2022/lab123/src/dtb.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/dtb.c","-o","out/dtb.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/dtb.c"}}],["/home/yuhu/osc2022/lab123/src/mailbox.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/mailbox.c","path":"/home/yuhu/osc2022/lab123/src/mailbox.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mailbox.c","-o","out/mailbox.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/mailbox.c"}}],["/home/yuhu/osc2022/lab123/src/queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/queue.c","path":"/home/yuhu/osc2022/lab123/src/queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/queue.c","-o","out/queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/queue.c"}}],["/home/yuhu/osc2022/lab123/src/exceptions.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/exceptions.c","path":"/home/yuhu/osc2022/lab123/src/exceptions.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/exceptions.c","-o","out/exceptions.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/exceptions.c"}}],["/home/yuhu/osc2022/lab123/src/task.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/task.c","path":"/home/yuhu/osc2022/lab123/src/task.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/task.c","-o","out/task.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/task.c"}}],["/home/yuhu/osc2022/lab123/src/mini_uart.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/mini_uart.c","path":"/home/yuhu/osc2022/lab123/src/mini_uart.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mini_uart.c","-o","out/mini_uart.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/mini_uart.c"}}],["/home/yuhu/osc2022/lab123/src/math.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/math.c","path":"/home/yuhu/osc2022/lab123/src/math.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/math.c","-o","out/math.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/math.c"}}],["/home/yuhu/osc2022/lab123/src/allocator.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/allocator.c","path":"/home/yuhu/osc2022/lab123/src/allocator.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/allocator.c","-o","out/allocator.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/allocator.c"}}],["/home/yuhu/osc2022/lab123/src/cpio.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/cpio.c","path":"/home/yuhu/osc2022/lab123/src/cpio.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/cpio.c","-o","out/cpio.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/cpio.c"}}],["/home/yuhu/osc2022/lab123/src/local_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/local_timer.c","path":"/home/yuhu/osc2022/lab123/src/local_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/local_timer.c","-o","out/local_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/local_timer.c"}}],["/home/yuhu/osc2022/lab123/src/signal.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/signal.c","path":"/home/yuhu/osc2022/lab123/src/signal.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/signal.c","-o","out/signal.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/signal.c"}}],["/home/yuhu/osc2022/lab123/src/main.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/main.c","path":"/home/yuhu/osc2022/lab123/src/main.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/main.c","-o","out/main.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/main.c"}}],["/home/yuhu/osc2022/lab123/src/shell.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/shell.c","path":"/home/yuhu/osc2022/lab123/src/shell.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/shell.c","-o","out/shell.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/shell.c"}}],["/home/yuhu/osc2022/lab123/src/buffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/buffer.c","path":"/home/yuhu/osc2022/lab123/src/buffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/buffer.c","-o","out/buffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/buffer.c"}}],["/home/yuhu/osc2022/lab123/src/irq2.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/irq2.c","path":"/home/yuhu/osc2022/lab123/src/irq2.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/irq2.c","-o","out/irq2.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/irq2.c"}}],["/home/yuhu/osc2022/lab123/src/priority_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/priority_queue.c","path":"/home/yuhu/osc2022/lab123/src/priority_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/priority_queue.c","-o","out/priority_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/priority_queue.c"}}],["/home/yuhu/osc2022/lab123/src/reboot.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/reboot.c","path":"/home/yuhu/osc2022/lab123/src/reboot.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/reboot.c","-o","out/reboot.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/reboot.c"}}],["/home/yuhu/osc2022/lab123/src/loadimg.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/loadimg.c","path":"/home/yuhu/osc2022/lab123/src/loadimg.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/loadimg.c","-o","out/loadimg.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/loadimg.c"}}],["/home/yuhu/osc2022/lab123/src/thread.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/thread.c","path":"/home/yuhu/osc2022/lab123/src/thread.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/thread.c","-o","out/thread.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/thread.c"}}],["/home/yuhu/osc2022/lab123/src/string.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/string.c","path":"/home/yuhu/osc2022/lab123/src/string.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/string.c","-o","out/string.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/string.c"}}],["/home/yuhu/osc2022/lab123/src/interrupt_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/src/interrupt_queue.c","path":"/home/yuhu/osc2022/lab123/src/interrupt_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/interrupt_queue.c","-o","out/interrupt_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/src/interrupt_queue.c"}}],["/home/yuhu/osc2022/lab123/sendfile.cpp",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/sendfile.cpp","path":"/home/yuhu/osc2022/lab123/sendfile.cpp","scheme":"file"},"configuration":{"defines":[],"includePath":[],"forcedInclude":[],"compilerPath":"/usr/bin/g++-11","compilerArgs":["-o","sender"],"windowsSdkVersion":""},"compileCommand":{"command":"g++-11 sendfile.cpp -o sender","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/sendfile.cpp"}}],["/home/yuhu/osc2022/lab123/user/src/main.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab123/user/src/main.c","path":"/home/yuhu/osc2022/lab123/user/src/main.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab123/user/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","user/src/main.c","-o","user/out/main.o","-fno-stack-protector"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I user/include -c user/src/main.c -o user/out/main.o -fno-stack-protector","directory":"/home/yuhu/osc2022/lab123","file":"/home/yuhu/osc2022/lab123/user/src/main.c"}}]]}} \ No newline at end of file +{"buildTargets":[".PHONY","all","clean","debug","dev","kernel8.img","out","run","screen","sender","super","tty","user/out","usercode.img"],"launchTargets":["/home/yuhu/tmp/osc2022/lab6>kernel8.elf()","/home/yuhu/tmp/osc2022/lab6>sender()"],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":["/home/yuhu/tmp/osc2022/lab6","/home/yuhu/tmp/osc2022/lab6/include","/home/yuhu/tmp/osc2022/lab6/src"],"compilerArgs":["-o","sender"],"compilerPath":"/usr/bin/g++-11","windowsSdkVersion":""},"fileIndex":[["/home/yuhu/tmp/osc2022/lab6/src/panic.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/panic.c","path":"/home/yuhu/tmp/osc2022/lab6/src/panic.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/panic.c","-o","out/panic.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/panic.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/mmu.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/mmu.c","path":"/home/yuhu/tmp/osc2022/lab6/src/mmu.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mmu.c","-o","out/mmu.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/mmu.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/getopt.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/getopt.c","path":"/home/yuhu/tmp/osc2022/lab6/src/getopt.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/getopt.c","-o","out/getopt.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/getopt.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/core_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/core_timer.c","path":"/home/yuhu/tmp/osc2022/lab6/src/core_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/core_timer.c","-o","out/core_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/core_timer.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/dtb.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/dtb.c","path":"/home/yuhu/tmp/osc2022/lab6/src/dtb.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/dtb.c","-o","out/dtb.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/dtb.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/mailbox.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/mailbox.c","path":"/home/yuhu/tmp/osc2022/lab6/src/mailbox.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mailbox.c","-o","out/mailbox.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/mailbox.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/queue.c","path":"/home/yuhu/tmp/osc2022/lab6/src/queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/queue.c","-o","out/queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/queue.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/exceptions.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/exceptions.c","path":"/home/yuhu/tmp/osc2022/lab6/src/exceptions.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/exceptions.c","-o","out/exceptions.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/exceptions.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/task.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/task.c","path":"/home/yuhu/tmp/osc2022/lab6/src/task.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/task.c","-o","out/task.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/task.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/mini_uart.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/mini_uart.c","path":"/home/yuhu/tmp/osc2022/lab6/src/mini_uart.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mini_uart.c","-o","out/mini_uart.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/mini_uart.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/math.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/math.c","path":"/home/yuhu/tmp/osc2022/lab6/src/math.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/math.c","-o","out/math.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/math.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/allocator.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/allocator.c","path":"/home/yuhu/tmp/osc2022/lab6/src/allocator.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/allocator.c","-o","out/allocator.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/allocator.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/cpio.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/cpio.c","path":"/home/yuhu/tmp/osc2022/lab6/src/cpio.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/cpio.c","-o","out/cpio.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/cpio.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/local_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/local_timer.c","path":"/home/yuhu/tmp/osc2022/lab6/src/local_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/local_timer.c","-o","out/local_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/local_timer.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/signal.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/signal.c","path":"/home/yuhu/tmp/osc2022/lab6/src/signal.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/signal.c","-o","out/signal.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/signal.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/main.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/main.c","path":"/home/yuhu/tmp/osc2022/lab6/src/main.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/main.c","-o","out/main.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/main.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/shell.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/shell.c","path":"/home/yuhu/tmp/osc2022/lab6/src/shell.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/shell.c","-o","out/shell.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/shell.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/buffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/buffer.c","path":"/home/yuhu/tmp/osc2022/lab6/src/buffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/buffer.c","-o","out/buffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/buffer.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/irq2.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/irq2.c","path":"/home/yuhu/tmp/osc2022/lab6/src/irq2.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/irq2.c","-o","out/irq2.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/irq2.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/priority_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/priority_queue.c","path":"/home/yuhu/tmp/osc2022/lab6/src/priority_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/priority_queue.c","-o","out/priority_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/priority_queue.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/reboot.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/reboot.c","path":"/home/yuhu/tmp/osc2022/lab6/src/reboot.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/reboot.c","-o","out/reboot.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/reboot.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/loadimg.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/loadimg.c","path":"/home/yuhu/tmp/osc2022/lab6/src/loadimg.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/loadimg.c","-o","out/loadimg.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/loadimg.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/thread.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/thread.c","path":"/home/yuhu/tmp/osc2022/lab6/src/thread.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/thread.c","-o","out/thread.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/thread.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/string.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/string.c","path":"/home/yuhu/tmp/osc2022/lab6/src/string.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/string.c","-o","out/string.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/string.c"}}],["/home/yuhu/tmp/osc2022/lab6/src/interrupt_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/src/interrupt_queue.c","path":"/home/yuhu/tmp/osc2022/lab6/src/interrupt_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/tmp/osc2022/lab6/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/interrupt_queue.c","-o","out/interrupt_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/src/interrupt_queue.c"}}],["/home/yuhu/tmp/osc2022/lab6/sendfile.cpp",{"uri":{"$mid":1,"fsPath":"/home/yuhu/tmp/osc2022/lab6/sendfile.cpp","path":"/home/yuhu/tmp/osc2022/lab6/sendfile.cpp","scheme":"file"},"configuration":{"defines":[],"includePath":[],"forcedInclude":[],"compilerPath":"/usr/bin/g++-11","compilerArgs":["-o","sender"],"windowsSdkVersion":""},"compileCommand":{"command":"g++-11 sendfile.cpp -o sender","directory":"/home/yuhu/tmp/osc2022/lab6","file":"/home/yuhu/tmp/osc2022/lab6/sendfile.cpp"}}]]}} \ No newline at end of file diff --git a/lab6/.vscode/dryrun.log b/lab6/.vscode/dryrun.log index 7359410c6..d63004752 100644 --- a/lab6/.vscode/dryrun.log +++ b/lab6/.vscode/dryrun.log @@ -1,9 +1,10 @@ make --dry-run --always-make --keep-going --print-directory -make: Entering directory '/home/yuhu/osc2022/lab123' +make: Entering directory '/home/yuhu/tmp/osc2022/lab6' mkdir -p out aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align -aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align @@ -13,7 +14,6 @@ aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align - aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align @@ -26,20 +26,16 @@ aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o - aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align - aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/start.S -o out/start.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/timer.S -o out/timer.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/jump.S -o out/jump.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq.S -o out/irq.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/scheduler.S -o out/scheduler.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/temp.S -o out/temp.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu_asm.S -o out/mmu_asm.o aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/excep_handler.S -o out/excep_handler.o -aarch64-linux-gnu-ld -T src/linker.ld -o kernel8.elf out/panic.o out/task.o out/mini_uart.o out/core_timer.o out/exceptions.o out/queue.o out/dtb.o out/allocator.o out/math.o out/main.o out/priority_queue.o out/reboot.o out/thread.o out/string.o out/mailbox.o out/getopt.o out/loadimg.o out/cpio.o out/local_timer.o out/signal.o out/shell.o out/buffer.o out/irq2.o out/interrupt_queue.o out/timer.o out/temp.o out/start.o out/jump.o out/irq.o out/scheduler.o out/excep_handler.o +aarch64-linux-gnu-ld -T src/linker.ld -o kernel8.elf out/panic.o out/mini_uart.o out/core_timer.o out/exceptions.o out/queue.o out/dtb.o out/task.o out/allocator.o out/mmu.o out/math.o out/main.o out/priority_queue.o out/reboot.o out/thread.o out/string.o out/mailbox.o out/getopt.o out/loadimg.o out/cpio.o out/local_timer.o out/signal.o out/shell.o out/buffer.o out/irq2.o out/interrupt_queue.o out/timer.o out/temp.o out/start.o out/jump.o out/irq.o out/scheduler.o out/mmu_asm.o out/excep_handler.o aarch64-linux-gnu-objcopy -O binary kernel8.elf kernel8.img g++-11 sendfile.cpp -o sender -mkdir -p user/out -aarch64-linux-gnu-gcc-10 -g -Wall -I user/include -c user/src/main.c -o user/out/main.o -fno-stack-protector -aarch64-linux-gnu-gcc-10 -g -Wall -I user/include -c user/src/system.S -o user/out/system.o -aarch64-linux-gnu-gcc-10 -o usercode.img user/out/main.o user/out/system.o -make: Leaving directory '/home/yuhu/osc2022/lab123' +make: Leaving directory '/home/yuhu/tmp/osc2022/lab6' diff --git a/lab6/.vscode/settings.json b/lab6/.vscode/settings.json index 3cd3ba5cd..caeaa7e2d 100644 --- a/lab6/.vscode/settings.json +++ b/lab6/.vscode/settings.json @@ -1,12 +1,9 @@ { "files.associations": { - "getopt.h": "c", "uint.h": "c", + "mmu.h": "c", + "mini_uart.h": "c", "queue.h": "c", - "priority_queue.h": "c", - "type.h": "c", - "scheduler.h": "c", - "random": "c", - "signal.h": "c" + "task.h": "c" } } \ No newline at end of file diff --git a/lab6/.vscode/targets.log b/lab6/.vscode/targets.log index 2c03ea433..3784458fa 100644 --- a/lab6/.vscode/targets.log +++ b/lab6/.vscode/targets.log @@ -6,7 +6,7 @@ make all --print-data-base --no-builtin-variables --no-builtin-rules --question # This is free software: you are free to change and redistribute it. # There is NO WARRANTY, to the extent permitted by law. -# Make data base, printed on Tue May 10 03:08:34 2022 +# Make data base, printed on Wed May 18 17:42:47 2022 # Variables @@ -27,13 +27,13 @@ VSCODE_LOG_NATIVE = false # automatic @F = $(notdir $@) # makefile -CURDIR := /home/yuhu/osc2022/lab123 +CURDIR := /home/yuhu/tmp/osc2022/lab6 # makefile SHELL = /bin/sh # makefile (from 'makefile', line 8) USER_SRC_DIR = user/src # environment -VSCODE_NLS_CONFIG = {"locale":"zh-tw","availableLanguages":{}} +VSCODE_NLS_CONFIG = {"locale":"zh-tw","availableLanguages":{"*":"zh-tw"},"_languagePackId":"50a216cf84c622b1d20f706e15b82d72.zh-tw","_translationsConfigFile":"/home/yuhu/.vscode-server/data/clp/50a216cf84c622b1d20f706e15b82d72.zh-tw/tcf.json","_cacheRoot":"/home/yuhu/.vscode-server/data/clp/50a216cf84c622b1d20f706e15b82d72.zh-tw","_resolvedLanguagePackCoreLocation":"/home/yuhu/.vscode-server/data/clp/50a216cf84c622b1d20f706e15b82d72.zh-tw/da15b6fd3ef856477bf6f4fb29ba1b7af717770d","_corruptedFile":"/home/yuhu/.vscode-server/data/clp/50a216cf84c622b1d20f706e15b82d72.zh-tw/corrupted.info","_languagePackSupport":true} # environment _ = /mnt/c/Users/yh084/AppData/Local/Programs/Microsoft VS Code/bin/code # makefile (from 'makefile', line 1) @@ -55,7 +55,7 @@ VSCODE_CWD = /mnt/c/Users/yh084/AppData/Local/Programs/Microsoft VS Code # default MAKE_HOST := x86_64-pc-linux-gnu # environment -PATH = /home/yuhu/.vscode-server/bin/57fd6d0195bb9b9d1b49f6da5db789060795de47/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/usbipd-win/:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/ProgramData/DockerDesktop/version-bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Users/yh084/scoop/shims:/mnt/c/Users/yh084/AppData/Local/Programs/Python/Python310/Scripts/:/mnt/c/Users/yh084/AppData/Local/Programs/Python/Python310/:/mnt/c/Users/yh084/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/yh084/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/yh084/script:/mnt/c/Users/yh084/AppData/Local/GitHubDesktop/bin +PATH = /home/yuhu/.vscode-server/bin/da15b6fd3ef856477bf6f4fb29ba1b7af717770d/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/usbipd-win/:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/ProgramData/DockerDesktop/version-bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Users/yh084/scoop/shims:/mnt/c/Users/yh084/AppData/Local/Programs/Python/Python310/Scripts/:/mnt/c/Users/yh084/AppData/Local/Programs/Python/Python310/:/mnt/c/Users/yh084/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/yh084/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/yh084/script:/mnt/c/Users/yh084/AppData/Local/GitHubDesktop/bin # environment LSCOLORS = Gxfxcxdxbxegedabagacad # environment @@ -65,7 +65,7 @@ tool_chain = aarch64-linux-gnu- # environment VSCODE_LOG_STACK = false # environment -VSCODE_IPC_HOOK_CLI = /mnt/wslg/runtime-dir/vscode-ipc-9648bb33-3c00-4fdd-97b2-d99c2ccda9b9.sock +VSCODE_IPC_HOOK_CLI = /mnt/wslg/runtime-dir/vscode-ipc-43683b89-ac4d-4572-8041-bbe7fe25aaaa.sock # default .FEATURES := target-specific order-only second-expansion else-if shortest-stem undefine oneshell archives jobserver output-sync check-symlink load # environment @@ -77,15 +77,15 @@ DISPLAY = :0 # environment VSCODE_PIPE_LOGGING = true # environment -PWD = /home/yuhu/osc2022/lab123 +PWD = /home/yuhu/tmp/osc2022/lab6 # default .LOADED := # environment -WSL_INTEROP = /run/WSL/18312_interop +WSL_INTEROP = /run/WSL/26465_interop # environment PULSE_SERVER = /mnt/wslg/PulseServer # environment -WT_SESSION = 90311f67-caa3-4462-bd61-73072e720109 +WT_SESSION = 24bd0279-8729-41f5-802a-bf9088e6df48 # environment VSCODE_AMD_ENTRYPOINT = vs/workbench/api/node/extensionHostProcess # environment @@ -97,7 +97,7 @@ USER_OBJS = $(USER_SRCS:$(USER_SRC_DIR)/%.c=$(USER_DUM_DIR)/%.o) # environment LOGNAME = yuhu # environment -APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL = true +APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL = 1 # environment ZSH = /home/yuhu/.oh-my-zsh # environment @@ -131,7 +131,7 @@ LESS = -R # automatic %D = $(patsubst %/,%,$(dir $%)) # environment -VSCODE_WSL_EXT_LOCATION = /mnt/c/Users/yh084/.vscode/extensions/ms-vscode-remote.remote-wsl-0.66.2 +VSCODE_WSL_EXT_LOCATION = /mnt/c/Users/yh084/.vscode/extensions/ms-vscode-remote.remote-wsl-0.66.3 # default MAKE_COMMAND := make # environment @@ -193,7 +193,7 @@ WSL_DISTRO_NAME = Ubuntu # makefile (from 'makefile', line 9) USER_DUM_DIR = user/out # variable set hash-table stats: -# Load=91/1024=9%, Rehash=0, Collisions=6/149=4% +# Load=91/1024=9%, Rehash=0, Collisions=6/153=4% # Pattern-specific Variable Values @@ -201,11 +201,11 @@ USER_DUM_DIR = user/out # Directories -# . (device 2080, inode 60654): 18 files, no impossibilities. -# src (device 2080, inode 60664): 34 files, no impossibilities. -# user/src (device 2080, inode 60765): 4 files, no impossibilities. +# . (device 2080, inode 88868): 12 files, no impossibilities. +# src (device 2080, inode 88957): 36 files, no impossibilities. +# user/src (device 2080, inode 88999): 4 files, no impossibilities. -# 56 files, no impossibilities in 3 directories. +# 52 files, no impossibilities in 3 directories. # Implicit Rules @@ -230,399 +230,203 @@ user/out/%.o: user/src/%.c # Files # Not a target: -src/signal.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 21:46:49.8347972 -# File has been updated. -# Successfully updated. - -out/string.o: src/string.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'string' -# Last modified 2022-05-10 02:47:44.8222048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -user/out/main.o: user/src/main.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'main' -# Last modified 2022-04-23 18:01:02.9104718 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 48): - $(tool_chain)$(CC) -g -Wall -I user/include -c $< -o $@ -fno-stack-protector - -out/core_timer.o: src/core_timer.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'core_timer' -# Last modified 2022-05-10 02:47:44.2622048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +out/string.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/excep_handler.S: -# Implicit rule search has been done. -# Last modified 2022-05-05 03:58:01.4859354 -# File has been updated. -# Successfully updated. +user/out/main.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/interrupt_queue.c: -# Implicit rule search has been done. -# Last modified 2022-04-19 18:41:01.7245497 -# File has been updated. -# Successfully updated. +out/core_timer.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -all: kernel8.img sender usercode.img +all: kernel8.img sender # Phony target (prerequisite of .PHONY). - # Command line target. # Implicit rule search has not been done. # File does not exist. # File has been updated. -# Successfully updated. +# Needs to be updated (-q is set). +# variable set hash-table stats: +# Load=0/32=0%, Rehash=0, Collisions=0/4=0% screen: all # Implicit rule search has not been done. # Modification time never checked. # File has not been updated. # recipe to execute (from 'makefile', line 71): - $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -d int - -out/main.o: src/main.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'main' -# Last modified 2022-05-10 02:47:44.6122048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align + $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -out/task.o: src/task.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'task' -# Last modified 2022-05-10 02:47:44.4322048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -.PHONY: all clean run debug tty +# Not a target: +out/main.o: # Implicit rule search has not been done. # Modification time never checked. # File has not been updated. -out/math.o: src/math.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'math' -# Last modified 2022-05-10 02:47:44.4822048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - # Not a target: -src/local_timer.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - -out/scheduler.o: src/scheduler.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'scheduler' -# Last modified 2022-05-10 02:47:44.9122048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +out/task.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/priority_queue.o: src/priority_queue.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'priority_queue' -# Last modified 2022-05-10 02:47:44.7122048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align + +.PHONY: all clean run debug tty +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/loadimg.c: -# Implicit rule search has been done. -# Last modified 2022-04-24 02:46:21.7304718 -# File has been updated. -# Successfully updated. - -out/dtb.o: src/dtb.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'dtb' -# Last modified 2022-05-10 02:47:44.3322048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +out/math.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/shell.c: -# Implicit rule search has been done. -# Last modified 2022-05-03 23:47:33.352419 -# File has been updated. -# Successfully updated. +out/scheduler.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/jump.S: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. +out/priority_queue.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/thread.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 03:15:45.6159354 -# File has been updated. -# Successfully updated. +out/dtb.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/temp.S: -# Implicit rule search has been done. -# Last modified 2022-04-25 21:18:46.4848545 -# File has been updated. -# Successfully updated. +.SUFFIXES: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/exceptions.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 21:39:09.5247972 -# File has been updated. -# Successfully updated. +out/mini_uart.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/cpio.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 02:52:42.2459354 -# File has been updated. -# Successfully updated. - -out/mini_uart.o: src/mini_uart.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'mini_uart' -# Last modified 2022-05-10 02:47:44.4622048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -out/reboot.o: src/reboot.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'reboot' -# Last modified 2022-05-10 02:47:44.7322048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +out/reboot.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -user/src/system.S: -# Implicit rule search has been done. -# Last modified 2022-04-24 03:48:05.7304718 -# File has been updated. -# Successfully updated. - -out/mailbox.o: src/mailbox.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'mailbox' -# Last modified 2022-05-10 02:47:44.3522048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +out/mailbox.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -debug: +debug: all # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. # File does not exist. # File has not been updated. -# recipe to execute (from 'makefile', line 64): +# recipe to execute (from 'makefile', line 63): $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -S -s -initrd initramfs.cpio -d int -dtb bcm2710-rpi-3-b-plus.dtb -# Not a target: -src/buffer.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - user/out: # Implicit rule search has not been done. -# Last modified 2022-05-10 03:06:05.7222048 -# File has been updated. -# Successfully updated. +# Modification time never checked. +# File has not been updated. # recipe to execute (from 'makefile', line 51): mkdir -p $(USER_DUM_DIR) # Not a target: src/linker.ld: -# Implicit rule search has been done. -# Last modified 2022-04-22 19:53:58.2814963 -# File has been updated. -# Successfully updated. - -# Not a target: -src/timer.S: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - -# Not a target: -src/getopt.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 22:56:18.1668043 -# File has been updated. -# Successfully updated. - -# Not a target: -src/start.S: -# Implicit rule search has been done. -# Last modified 2022-05-05 21:50:40.6147972 -# File has been updated. -# Successfully updated. +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: makefile: # Implicit rule search has been done. -# Last modified 2022-05-05 00:29:39.4059354 -# File has been updated. -# Successfully updated. - -# Not a target: -src/irq2.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 +# Last modified 2022-05-18 17:41:18.5034772 # File has been updated. # Successfully updated. usercode.img: user/out user/out/main.o user/out/system.o # Implicit rule search has not been done. -# Last modified 2022-05-10 03:06:27.5922048 -# File has been updated. -# Successfully updated. +# Modification time never checked. +# File has not been updated. # recipe to execute (from 'makefile', line 42): $(tool_chain)$(CC) -o usercode.img $(USER_OBJS) $(USER_OBJSS) out: # Implicit rule search has not been done. -# Last modified 2022-05-10 03:06:05.6422048 +# Implicit/static pattern stem: '' +# File does not exist. # File has been updated. -# Successfully updated. +# Needs to be updated (-q is set). +# automatic +# @ := out +# automatic +# % := +# automatic +# * := +# automatic +# + := +# automatic +# | := +# automatic +# < := +# automatic +# ^ := +# automatic +# ? := +# variable set hash-table stats: +# Load=8/32=25%, Rehash=0, Collisions=1/12=8% # recipe to execute (from 'makefile', line 36): mkdir -p $(DUM_DIR) # Not a target: -src/core_timer.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 00:16:56.4959354 -# File has been updated. -# Successfully updated. - -out/panic.o: src/panic.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'panic' -# Last modified 2022-05-10 02:47:44.2322048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -out/queue.o: src/queue.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'queue' -# Last modified 2022-05-10 02:47:44.3722048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -out/allocator.o: src/allocator.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'allocator' -# Last modified 2022-05-10 02:47:44.5222048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -# Not a target: -src/main.c: - -# Implicit rule search has been done. -# Last modified 2022-05-05 17:13:56.6847972 -# File has been updated. -# Successfully updated. - -# Not a target: -src/task.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 21:45:52.8647972 -# File has been updated. -# Successfully updated. +out/panic.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/scheduler.S: -# Implicit rule search has been done. -# Last modified 2022-05-05 21:42:51.9347972 -# File has been updated. -# Successfully updated. +out/queue.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/math.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - -out/irq.o: src/irq.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'irq' -# Last modified 2022-05-10 02:47:44.8922048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +out/allocator.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/priority_queue.c: -# Implicit rule search has been done. -# Last modified 2022-05-05 00:16:25.1059354 -# File has been updated. -# Successfully updated. - -user/out/system.o: user/src/system.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'system' -# Last modified 2022-04-24 03:51:39.7004718 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 45): - $(tool_chain)$(CC) -g -Wall -I user/include -c $< -o $@ +out/irq.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/dtb.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. +user/out/system.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -dev: +dev: all # Implicit rule search has not been done. # Modification time never checked. # File has not been updated. -# recipe to execute (from 'makefile', line 66): +# recipe to execute (from 'makefile', line 65): $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb # Not a target: @@ -631,37 +435,20 @@ dev: # Modification time never checked. # File has not been updated. -out/signal.o: src/signal.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'signal' -# Last modified 2022-05-10 02:47:44.5922048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - # Not a target: -src/mini_uart.c: -# Implicit rule search has been done. -# Last modified 2022-04-28 01:09:08.6429406 -# File has been updated. -# Successfully updated. +out/signal.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. run: all # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. # File does not exist. # File has not been updated. -# recipe to execute (from 'makefile', line 60): +# recipe to execute (from 'makefile', line 59): $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -# Not a target: -src/reboot.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - clean: # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. @@ -671,246 +458,163 @@ clean: rm -rf kernel8.* rm -rf out rm sender - rm usercode.img - -# Not a target: -src/mailbox.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. # Not a target: sendfile.cpp: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/excep_handler.o: src/excep_handler.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'excep_handler' -# Last modified 2022-05-10 02:47:44.9322048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +# Not a target: +out/excep_handler.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/interrupt_queue.o: src/interrupt_queue.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'interrupt_queue' -# Last modified 2022-05-10 02:47:44.8422048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/interrupt_queue.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. super: all # Implicit rule search has not been done. # Modification time never checked. # File has not been updated. -# recipe to execute (from 'makefile', line 69): +# recipe to execute (from 'makefile', line 68): $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -d int -S -s -out/local_timer.o: src/local_timer.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'local_timer' -# Last modified 2022-05-10 02:47:44.5722048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -out/loadimg.o: src/loadimg.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'loadimg' -# Last modified 2022-05-10 02:47:44.7522048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - -out/shell.o: src/shell.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'shell' -# Last modified 2022-05-10 02:47:44.6522048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/local_timer.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -user/src/main.c: -# Implicit rule search has been done. -# Last modified 2022-04-23 17:59:54.0704718 -# File has been updated. -# Successfully updated. +out/mmu_asm.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/thread.o: src/thread.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'thread' -# Last modified 2022-05-10 02:47:44.7822048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/loadimg.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/jump.o: src/jump.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'jump' -# Last modified 2022-05-10 02:47:44.8822048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +# Not a target: +out/shell.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/exceptions.o: src/exceptions.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'exceptions' -# Last modified 2022-05-10 02:47:44.4022048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/mmu.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/cpio.o: src/cpio.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'cpio' -# Last modified 2022-05-10 02:47:44.5522048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/thread.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/temp.o: src/temp.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'temp' -# Last modified 2022-05-10 02:47:44.9222048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +# Not a target: +out/jump.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/panic.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. +out/exceptions.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/queue.c: -# Implicit rule search has been done. -# Last modified 2022-04-30 00:14:56.6991518 -# File has been updated. -# Successfully updated. +out/cpio.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # Not a target: -src/allocator.c: -# Implicit rule search has been done. -# Last modified 2022-05-03 23:47:48.682419 -# File has been updated. -# Successfully updated. +out/temp.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -kernel8.img: out out/panic.o out/core_timer.o out/getopt.o out/dtb.o out/mailbox.o out/queue.o out/exceptions.o out/task.o out/mini_uart.o out/math.o out/allocator.o out/cpio.o out/local_timer.o out/signal.o out/main.o out/shell.o out/buffer.o out/irq2.o out/priority_queue.o out/reboot.o out/loadimg.o out/thread.o out/string.o out/interrupt_queue.o out/start.o out/timer.o out/jump.o out/irq.o out/scheduler.o out/temp.o out/excep_handler.o src/linker.ld +kernel8.img: out out/panic.o out/mmu.o out/getopt.o out/core_timer.o out/dtb.o out/mailbox.o out/queue.o out/exceptions.o out/task.o out/mini_uart.o out/math.o out/allocator.o out/cpio.o out/local_timer.o out/signal.o out/main.o out/shell.o out/buffer.o out/irq2.o out/priority_queue.o out/reboot.o out/loadimg.o out/thread.o out/string.o out/interrupt_queue.o out/start.o out/timer.o out/jump.o out/irq.o out/scheduler.o out/temp.o out/mmu_asm.o out/excep_handler.o src/linker.ld # Implicit rule search has not been done. -# Last modified 2022-05-10 03:06:27.5322048 +# File does not exist. # File has been updated. -# Successfully updated. +# Needs to be updated (-q is set). +# variable set hash-table stats: +# Load=0/32=0%, Rehash=0, Collisions=0/4=0% # recipe to execute (from 'makefile', line 26): $(tool_chain)ld -T $(SRC_DIR)/linker.ld -o kernel8.elf $(OBJS) $(OBJSS) $(tool_chain)objcopy -O binary kernel8.elf kernel8.img # Not a target: -src/irq.S: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. - -out/buffer.o: src/buffer.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'buffer' -# Last modified 2022-05-10 02:47:44.6722048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align - - -# Not a target: -src/string.c: -# Implicit rule search has been done. -# Last modified 2022-04-17 18:21:43.6768043 -# File has been updated. -# Successfully updated. +out/buffer.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -tty: +tty: all # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. # File does not exist. # File has not been updated. -# recipe to execute (from 'makefile', line 62): +# recipe to execute (from 'makefile', line 61): $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial pty -out/getopt.o: src/getopt.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'getopt' -# Last modified 2022-05-10 02:47:44.2822048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/getopt.o: +# Implicit rule search has not been done. + +# Modification time never checked. +# File has not been updated. -out/timer.o: src/timer.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'timer' -# Last modified 2022-05-10 02:47:44.8622048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +# Not a target: +out/timer.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. sender: sendfile.cpp # Implicit rule search has not been done. -# Last modified 2022-05-10 02:47:45.3022048 -# File has been updated. -# Successfully updated. +# Modification time never checked. +# File has not been updated. # recipe to execute (from 'makefile', line 39): $(CPP) sendfile.cpp -o sender -out/start.o: src/start.S -# Implicit rule search has been done. -# Implicit/static pattern stem: 'start' -# Last modified 2022-05-10 02:47:44.8522048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 30): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ +# Not a target: +out/start.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. -out/irq2.o: src/irq2.c -# Implicit rule search has been done. -# Implicit/static pattern stem: 'irq2' -# Last modified 2022-05-10 02:47:44.6922048 -# File has been updated. -# Successfully updated. -# recipe to execute (from 'makefile', line 33): - $(tool_chain)$(CC) -g -Wall -I include -c $< -o $@ -fno-stack-protector -mstrict-align +# Not a target: +out/irq2.o: +# Implicit rule search has not been done. +# Modification time never checked. +# File has not been updated. # files hash-table stats: -# Load=85/1024=8%, Rehash=0, Collisions=10/277=4% +# Load=54/1024=5%, Rehash=0, Collisions=6/126=5% # VPATH Search Paths # No 'vpath' search paths. # No general ('VPATH' variable) search path. -# strcache buffers: 1 (0) / strings = 196 / storage = 2198 B / avg = 11 B -# current buf: size = 8162 B / used = 2198 B / count = 196 / avg = 11 B +# strcache buffers: 1 (0) / strings = 108 / storage = 1161 B / avg = 10 B +# current buf: size = 8162 B / used = 1161 B / count = 108 / avg = 10 B -# strcache performance: lookups = 275 / hit rate = 28% +# strcache performance: lookups = 152 / hit rate = 28% # hash-table stats: -# Load=196/8192=2%, Rehash=0, Collisions=5/275=2% -# Finished Make data base on Tue May 10 03:08:34 2022 +# Load=108/8192=1%, Rehash=0, Collisions=3/152=2% +# Finished Make data base on Wed May 18 17:42:47 2022 diff --git a/lab6/bootloader/initramfs.cpio b/lab6/bootloader/initramfs.cpio index 0676fb158..46c1fdf15 100644 Binary files a/lab6/bootloader/initramfs.cpio and b/lab6/bootloader/initramfs.cpio differ diff --git a/lab6/include/allocator.h b/lab6/include/allocator.h index fb94f57d4..9616cbdc4 100644 --- a/lab6/include/allocator.h +++ b/lab6/include/allocator.h @@ -7,7 +7,7 @@ void init_allocator(); void free(void* address); void pool_status(); void clear_pool(); -void memory_reserve(uint32 start,uint32 end); +void memory_reserve(uint64 start,uint64 end); struct FrameArray{ int val, index; diff --git a/lab6/include/aux.h b/lab6/include/aux.h index daba29618..312308d57 100644 --- a/lab6/include/aux.h +++ b/lab6/include/aux.h @@ -1,4 +1,4 @@ -#include "mmio.h" +#include "peripheral/mmio.h" #define AUX_BASE (MMIO_BASE + 0x215000) diff --git a/lab6/include/cpio.h b/lab6/include/cpio.h index 384173451..3d9bf1670 100644 --- a/lab6/include/cpio.h +++ b/lab6/include/cpio.h @@ -1,4 +1,3 @@ -void list(unsigned int addr); -void print_content(char *file, unsigned int addr); -void execute(char *file_name,char *const argv[]); -void exec(char *file_name,char *const argv[]); \ No newline at end of file +void list(uint64_t addr); +void print_content(char *file, uint64_t addr); +void copy_content(char *file,void **addr, uint64_t *size); \ No newline at end of file diff --git a/lab6/include/gpio.h b/lab6/include/gpio.h index b1b2c11dc..31a3b6e9e 100644 --- a/lab6/include/gpio.h +++ b/lab6/include/gpio.h @@ -1,4 +1,4 @@ -#include "mmio.h" +#include "peripheral/mmio.h" #define GPIO_BASE (MMIO_BASE + 0x200000) diff --git a/lab6/include/mailbox.h b/lab6/include/mailbox.h index cdb9f62d4..0b560b264 100644 --- a/lab6/include/mailbox.h +++ b/lab6/include/mailbox.h @@ -1,2 +1,2 @@ void get_board_revision(); -void get_arm_memory(); \ No newline at end of file +void get_arm_memory(); diff --git a/lab6/include/math.h b/lab6/include/math.h index 31b2595a0..c2aaae31a 100644 --- a/lab6/include/math.h +++ b/lab6/include/math.h @@ -1,4 +1,6 @@ int log(int base, int logarithm); int exp(int base, int exponent); int log2(int logarithm); -int exp2(int exponent); \ No newline at end of file +int exp2(int exponent); +long long upper_bound(long long dividend, long long divisor); +unsigned long long min(unsigned long long a,unsigned long long b); \ No newline at end of file diff --git a/lab6/include/mmu.h b/lab6/include/mmu.h index 70d68868e..3bd2dcee3 100644 --- a/lab6/include/mmu.h +++ b/lab6/include/mmu.h @@ -1,2 +1,19 @@ +#ifndef __mmu__ +#define __mmu__ +#define pte_t unsigned long long +#define size_t unsigned int +typedef struct{pte_t entries[512];} pagetable_t; void disable_mmu(); -void setup_mmu(); \ No newline at end of file +void setup_mmu(); +void set_ttbr0_el1(pagetable_t* pt); +pagetable_t* allocate_page(); +void SetTaskStackPagetable(pagetable_t *pt, void* stack_addr); +void SetTaskCodePagetable(pagetable_t *pt, void* code_addr, unsigned long long size); +void SetPeripherialPagetable(pagetable_t *pt); +void* mmap_set(void* addr, size_t len, int prot, int flags); +unsigned char mmap_check(unsigned long long FAR); +void map_pages(unsigned long long des, unsigned long long src); +void cow_init(); +unsigned long long get_ttbr0_el1(); + +#endif diff --git a/lab6/include/mmio.h b/lab6/include/peripheral/mmio.h similarity index 100% rename from lab6/include/mmio.h rename to lab6/include/peripheral/mmio.h diff --git a/lab6/include/peripheral/mmu.h b/lab6/include/peripheral/mmu.h index eafeccf7b..c9870d501 100644 --- a/lab6/include/peripheral/mmu.h +++ b/lab6/include/peripheral/mmu.h @@ -15,3 +15,21 @@ #define BOOT_PUD1_ATTR (PD_ACCESS | (MAIR_IDX_DEVICE_nGnRnE << 2) | PD_BLOCK) #define BOOT_PMD0_ATTR_MMIO (PD_ACCESS | (MAIR_IDX_DEVICE_nGnRnE << 2) | PD_BLOCK) #define BOOT_PMD0_ATTR_RAM (PD_ACCESS | (MAIR_IDX_NORMAL_NOCACHE << 2) | PD_BLOCK) + +#define RO_BIT (1 << 7) +#define RW_BIT (0 << 7) +#define USR_EXE_NEVER_BIT (1 << 54) +#define KERNEL_EXE_NEVER_BIT (1 << 53) //if set RW_BIT and USER_KERNEL_BIT, then KERNEL_EXE_BIT will be ineffective +#define ONLY_KERNEL_BIT (0 << 6) +#define USER_KERNEL_BIT (1 << 6) +#define PGD_ATTR PD_TABLE +#define PUD_ATTR PD_TABLE +#define PMD_ATTR PD_TABLE +#define PTE_ATTR_CODE (PD_ACCESS | USER_KERNEL_BIT | RO_BIT | (MAIR_IDX_NORMAL_NOCACHE << 2) | PD_TABLE) +#define PTE_ATTR_STACK (PD_ACCESS | USER_KERNEL_BIT | RW_BIT | (MAIR_IDX_NORMAL_NOCACHE << 2) | PD_TABLE) +#define PTE_ATTR_BASE (USER_KERNEL_BIT | (MAIR_IDX_NORMAL_NOCACHE << 2) | PD_TABLE) + +#define PROT_NONE (0) +#define PROT_READ (1 << 0) +#define PROT_WRITE (1 << 1) +#define PROT_EXEC (1 << 2) \ No newline at end of file diff --git a/lab6/include/string.h b/lab6/include/string.h index 12397f3b2..4c2d27d05 100644 --- a/lab6/include/string.h +++ b/lab6/include/string.h @@ -4,7 +4,7 @@ void i16toa(int value, char *s, int digits); int strcmp(char *string1, char *string2); int strncmp(char *string1, char *string2, int length); void strcpy(char *string1, char* string2, int length); -unsigned int letobe(unsigned int o); +unsigned long long letobe(unsigned long long o); void strccat(char *string1, char* string2, char *string_out); int atoi(char *s); int a16toi(char *s); \ No newline at end of file diff --git a/lab6/include/task.h b/lab6/include/task.h index f8c210620..bc2f26d6b 100644 --- a/lab6/include/task.h +++ b/lab6/include/task.h @@ -4,6 +4,9 @@ void UserExit(); void PushToReadyList(unsigned int tid); void InitUserTaskScheduler(); int UserThread(void* func, void* arg); +void execute(char *file_name,char *const argv[]); +void exec(char *file_name,char *const argv[]); + struct trapframe { uint64 x[31]; // general register from x0 ~ x30 diff --git a/lab6/include/thread.h b/lab6/include/thread.h index 3f9ce7d52..65ff2340d 100644 --- a/lab6/include/thread.h +++ b/lab6/include/thread.h @@ -14,7 +14,7 @@ void record_mem(void* addr); int getpid(); int set_fork(void* sp); int kill(pid_t pid); -void move_last_mem(tid_t tid); +int move_last_mem(tid_t tid); #define thread_numbers 65536 @@ -38,7 +38,9 @@ struct thread{ dead } status; struct thread_sibling *childs; - unsigned char stack[0x10000]; + unsigned char *ustack; unsigned char *kstack; + void *page_table; }; +typedef struct thread thread_t; \ No newline at end of file diff --git a/lab6/include/uint.h b/lab6/include/uint.h index 83dce4196..c6c89b19e 100644 --- a/lab6/include/uint.h +++ b/lab6/include/uint.h @@ -12,5 +12,9 @@ #define true 1 #define tid_t uint32 #define pid_t uint32 +#define uint64_t uint64 +#define uint32_t uint32 +#define uint16_t uint16 +#define byte_t byte #endif \ No newline at end of file diff --git a/lab6/initramfs.cpio b/lab6/initramfs.cpio index 0676fb158..46c1fdf15 100644 Binary files a/lab6/initramfs.cpio and b/lab6/initramfs.cpio differ diff --git a/lab6/makefile b/lab6/makefile index 5b798c932..b91d4e896 100644 --- a/lab6/makefile +++ b/lab6/makefile @@ -57,14 +57,16 @@ clean: run: all $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -tty: +tty: all $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial pty -debug: +debug: all $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -S -s -initrd initramfs.cpio -d int -dtb bcm2710-rpi-3-b-plus.dtb -dev: +dev: all $(SIMU_ENV) -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb super: all $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -d int -S -s + screen: all - $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -d int + $(SIMU_ENV) -M raspi3 -kernel kernel8.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb + diff --git a/lab6/rootfs/vm.img b/lab6/rootfs/vm.img new file mode 100644 index 000000000..8ba674e6c Binary files /dev/null and b/lab6/rootfs/vm.img differ diff --git a/lab6/shell.s b/lab6/shell.s deleted file mode 100644 index 8b1af05e7..000000000 --- a/lab6/shell.s +++ /dev/null @@ -1,1430 +0,0 @@ - .arch armv8-a - .file "shell.c" - .text - .global cpio_start - .bss - .align 2 - .type cpio_start, %object - .size cpio_start, 4 -cpio_start: - .zero 4 - .global cpio_end - .align 2 - .type cpio_end, %object - .size cpio_end, 4 -cpio_end: - .zero 4 - .global cmd_buffer - .align 3 - .type cmd_buffer, %object - .size cmd_buffer, 1024 -cmd_buffer: - .zero 1024 - .global cmd_index - .align 2 - .type cmd_index, %object - .size cmd_index, 4 -cmd_index: - .zero 4 - .global cmd_flag - .align 2 - .type cmd_flag, %object - .size cmd_flag, 4 -cmd_flag: - .zero 4 - .section .rodata - .align 3 -.LC0: - .string "\n\n\nHello From RPI3\n" - .align 3 -.LC1: - .string "linux,initrd-start" - .string "" - .align 3 -.LC2: - .string "/chosen" - .string "" - .align 3 -.LC3: - .string "linux,initrd-end" - .string "" - .align 3 -.LC4: - .string "Ramf start: 0x%x\n" - .align 3 -.LC5: - .string "Ramf end: 0x%x\n" - .text - .align 2 - .global shell_init - .type shell_init, %function -shell_init: -.LFB0: - .cfi_startproc - stp x29, x30, [sp, -48]! - .cfi_def_cfa_offset 48 - .cfi_offset 29, -48 - .cfi_offset 30, -40 - mov x29, sp - adrp x0, :got:__heap_start - ldr x0, [x0, #:got_lo12:__heap_start] - sub x0, x0, #8 - str x0, [sp, 16] - ldr x0, [sp, 16] - str wzr, [x0] - bl uart_init - adrp x0, .LC0 - add x0, x0, :lo12:.LC0 - bl uart_printf - bl uart_init_buffer - bl uart_flush - bl core_timer_init - bl init_allocator - adrp x0, .LC1 - add x1, x0, :lo12:.LC1 - adrp x0, .LC2 - add x0, x0, :lo12:.LC2 - bl find_property_value - str x0, [sp, 24] - adrp x0, .LC3 - add x1, x0, :lo12:.LC3 - adrp x0, .LC2 - add x0, x0, :lo12:.LC2 - bl find_property_value - str x0, [sp, 32] - ldr x0, [sp, 24] - cmp x0, 0 - beq .L2 - ldr x0, [sp, 24] - ldr w0, [x0] - bl letobe - mov w1, w0 - adrp x0, .LC4 - add x0, x0, :lo12:.LC4 - bl uart_printf - ldr x0, [sp, 24] - ldr w0, [x0] - bl letobe - mov w1, w0 - adrp x0, cpio_start - add x0, x0, :lo12:cpio_start - str w1, [x0] -.L2: - ldr x0, [sp, 32] - cmp x0, 0 - beq .L3 - ldr x0, [sp, 32] - ldr w0, [x0] - bl letobe - mov w1, w0 - adrp x0, .LC5 - add x0, x0, :lo12:.LC5 - bl uart_printf - ldr x0, [sp, 32] - ldr w0, [x0] - bl letobe - mov w1, w0 - adrp x0, cpio_end - add x0, x0, :lo12:cpio_end - str w1, [x0] -.L3: - mov w1, 4096 - mov w0, 0 - bl memory_reserve - adrp x0, cpio_start - add x0, x0, :lo12:cpio_start - ldr w2, [x0] - adrp x0, cpio_end - add x0, x0, :lo12:cpio_end - ldr w0, [x0] - mov w1, w0 - mov w0, w2 - bl memory_reserve - adrp x0, :got:_begin_ - ldr x0, [x0, #:got_lo12:_begin_] - mov w2, w0 - adrp x0, :got:_end_ - ldr x0, [x0, #:got_lo12:_end_] - mov w1, w0 - mov w0, w2 - bl memory_reserve - adrp x0, :got:__dtb_addr - ldr x0, [x0, #:got_lo12:__dtb_addr] - str x0, [sp, 40] - ldr x0, [sp, 40] - ldr w2, [x0] - ldr x0, [sp, 40] - ldr w0, [x0] - add w0, w0, 1048576 - mov w1, w0 - mov w0, w2 - bl memory_reserve - mov w1, 524288 - mov w0, 0 - bl memory_reserve - bl init_thread - nop - ldp x29, x30, [sp], 48 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE0: - .size shell_init, .-shell_init - .align 2 - .global reset_flag - .type reset_flag, %function -reset_flag: -.LFB1: - .cfi_startproc - stp x29, x30, [sp, -16]! - .cfi_def_cfa_offset 16 - .cfi_offset 29, -16 - .cfi_offset 30, -8 - mov x29, sp - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - str wzr, [x0] - mov x0, 20548 - movk x0, 0x3f21, lsl 16 - mov w1, 1 - str w1, [x0] - bl core_timer_disable - bl irq_enable - nop - ldp x29, x30, [sp], 16 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE1: - .size reset_flag, .-reset_flag - .section .rodata - .align 3 -.LC6: - .string "# " - .align 3 -.LC7: - .string "\n" - .text - .align 2 - .global uart_read_line - .type uart_read_line, %function -uart_read_line: -.LFB2: - .cfi_startproc - stp x29, x30, [sp, -48]! - .cfi_def_cfa_offset 48 - .cfi_offset 29, -48 - .cfi_offset 30, -40 - mov x29, sp - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [x0] - str x1, [sp, 40] - mov x1, 0 - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - ldr w0, [x0] - cmp w0, 0 - bne .L9 - adrp x0, .LC6 - add x0, x0, :lo12:.LC6 - bl uart_printf - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - mov w1, 1 - str w1, [x0] - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - str wzr, [x0] - str wzr, [sp, 24] - b .L7 -.L8: - adrp x0, cmd_buffer - add x1, x0, :lo12:cmd_buffer - ldrsw x0, [sp, 24] - strb wzr, [x1, x0] - ldr w0, [sp, 24] - add w0, w0, 1 - str w0, [sp, 24] -.L7: - ldr w0, [sp, 24] - cmp w0, 1023 - ble .L8 - b .L9 -.L17: - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - ldr w0, [x0] - cmp w0, 0 - bne .L10 - adrp x0, .LC6 - add x0, x0, :lo12:.LC6 - bl uart_printf - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - mov w1, 1 - str w1, [x0] - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - str wzr, [x0] - str wzr, [sp, 28] - b .L11 -.L12: - adrp x0, cmd_buffer - add x1, x0, :lo12:cmd_buffer - ldrsw x0, [sp, 28] - strb wzr, [x1, x0] - ldr w0, [sp, 28] - add w0, w0, 1 - str w0, [sp, 28] -.L11: - ldr w0, [sp, 28] - cmp w0, 1023 - ble .L12 -.L10: - ldrb w0, [sp, 23] - cmp w0, 13 - bne .L13 - adrp x0, .LC7 - add x0, x0, :lo12:.LC7 - bl uart_printf - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - ldr w0, [x0] - add w2, w0, 1 - adrp x1, cmd_index - add x1, x1, :lo12:cmd_index - str w2, [x1] - adrp x1, cmd_buffer - add x1, x1, :lo12:cmd_buffer - uxtw x0, w0 - strb wzr, [x1, x0] - adrp x0, cmd_flag - add x0, x0, :lo12:cmd_flag - str wzr, [x0] - adrp x0, cmd_buffer - add x0, x0, :lo12:cmd_buffer - bl check - b .L9 -.L13: - ldrb w0, [sp, 23] - cmp w0, 8 - beq .L14 - ldrb w0, [sp, 23] - cmp w0, 127 - bne .L15 -.L14: - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - ldr w0, [x0] - cmp w0, 0 - beq .L9 - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - ldr w0, [x0] - sub w1, w0, #1 - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - str w1, [x0] - mov w0, 8 - strb w0, [sp, 32] - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - ldr w2, [x0] - adrp x0, cmd_buffer - add x1, x0, :lo12:cmd_buffer - uxtw x0, w2 - strb wzr, [x1, x0] - mov w0, 8 - bl uart_write - mov w0, 32 - bl uart_write - mov w0, 8 - bl uart_write - b .L9 -.L15: - ldrb w0, [sp, 23] - cmp w0, 31 - bls .L9 - ldrb w0, [sp, 23] - cmp w0, 126 - bhi .L9 - adrp x0, cmd_index - add x0, x0, :lo12:cmd_index - ldr w0, [x0] - add w2, w0, 1 - adrp x1, cmd_index - add x1, x1, :lo12:cmd_index - str w2, [x1] - ldrb w2, [sp, 23] - adrp x1, cmd_buffer - add x1, x1, :lo12:cmd_buffer - uxtw x0, w0 - strb w2, [x1, x0] - ldrb w0, [sp, 23] - bl uart_push - mov x0, 20548 - movk x0, 0x3f21, lsl 16 - ldr w1, [x0] - mov x0, 20548 - movk x0, 0x3f21, lsl 16 - orr w1, w1, 2 - str w1, [x0] -.L9: - add x0, sp, 23 - bl uart_pop - cmp w0, 0 - bne .L17 - nop - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [sp, 40] - ldr x2, [x0] - subs x1, x1, x2 - mov x2, 0 - beq .L18 - bl __stack_chk_fail -.L18: - ldp x29, x30, [sp], 48 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE2: - .size uart_read_line, .-uart_read_line - .global m - .bss - .align 3 - .type m, %object - .size m, 80 -m: - .zero 80 - .text - .align 2 - .global parse_command - .type parse_command, %function -parse_command: -.LFB3: - .cfi_startproc - stp x29, x30, [sp, -80]! - .cfi_def_cfa_offset 80 - .cfi_offset 29, -80 - .cfi_offset 30, -72 - mov x29, sp - str x0, [sp, 24] - mov w0, 128 - bl malloc - str x0, [sp, 56] - str wzr, [sp, 44] - ldr x0, [sp, 24] - ldrb w0, [x0] - cmp w0, 0 - bne .L20 - mov x0, 0 - b .L21 -.L20: - str wzr, [sp, 48] - b .L22 -.L29: - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 32 - beq .L30 - mov w0, 128 - bl malloc - str x0, [sp, 64] - str wzr, [sp, 52] - b .L25 -.L27: - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x1, x1, x0 - ldr w0, [sp, 52] - add w2, w0, 1 - str w2, [sp, 52] - sxtw x0, w0 - ldr x2, [sp, 64] - add x0, x2, x0 - ldrb w1, [x1] - strb w1, [x0] - ldr w0, [sp, 48] - add w0, w0, 1 - str w0, [sp, 48] -.L25: - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 0 - beq .L26 - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 32 - beq .L26 - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 31 - bls .L26 - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - sxtb w0, w0 - cmp w0, 0 - bge .L27 -.L26: - ldrsw x0, [sp, 52] - ldr x1, [sp, 64] - add x0, x1, x0 - strb wzr, [x0] - ldr w0, [sp, 44] - add w1, w0, 1 - str w1, [sp, 44] - sxtw x0, w0 - lsl x0, x0, 3 - ldr x1, [sp, 56] - add x0, x1, x0 - ldr x1, [sp, 64] - str x1, [x0] - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 0 - beq .L31 - b .L24 -.L30: - nop -.L24: - ldr w0, [sp, 48] - add w0, w0, 1 - str w0, [sp, 48] -.L22: - ldrsw x0, [sp, 48] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 0 - bne .L29 - b .L28 -.L31: - nop -.L28: - mov w0, 16 - bl malloc - str x0, [sp, 72] - ldr x0, [sp, 72] - ldr w1, [sp, 44] - str w1, [x0, 8] - ldr x0, [sp, 72] - ldr x1, [sp, 56] - str x1, [x0] - ldr x0, [sp, 72] -.L21: - ldp x29, x30, [sp], 80 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE3: - .size parse_command, .-parse_command - .section .rodata - .align 3 -.LC8: - .string "10\n" - .align 3 -.LC9: - .string "20\n" - .text - .align 2 - .global temp_func - .type temp_func, %function -temp_func: -.LFB4: - .cfi_startproc - stp x29, x30, [sp, -16]! - .cfi_def_cfa_offset 16 - .cfi_offset 29, -16 - .cfi_offset 30, -8 - mov x29, sp - adrp x0, .LC8 - add x0, x0, :lo12:.LC8 - bl uart_printf - mov w0, 5000 - bl delay - adrp x0, .LC9 - add x0, x0, :lo12:.LC9 - bl uart_printf - nop - ldp x29, x30, [sp], 16 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE4: - .size temp_func, .-temp_func - .align 2 - .global temp_func2 - .type temp_func2, %function -temp_func2: -.LFB5: - .cfi_startproc - stp x29, x30, [sp, -16]! - .cfi_def_cfa_offset 16 - .cfi_offset 29, -16 - .cfi_offset 30, -8 - mov x29, sp - adrp x0, .LC8 - add x0, x0, :lo12:.LC8 - bl uart_printf - mov w0, 10000 - bl delay - adrp x0, .LC9 - add x0, x0, :lo12:.LC9 - bl uart_printf - nop - ldp x29, x30, [sp], 16 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE5: - .size temp_func2, .-temp_func2 - .section .rodata - .align 3 -.LC10: - .string "\nFork Test, pid %d\n" - .align 3 -.LC11: - .string "first child pid: %d, cnt: %d, ptr: %x, sp : %x\n" - .align 3 -.LC12: - .string "second child pid: %d, cnt: %d, ptr: %x, sp : %x\n" - .align 3 -.LC13: - .string "parent here, pid %d, child %d\n" - .text - .align 2 - .global fork_test - .type fork_test, %function -fork_test: -.LFB6: - .cfi_startproc - stp x29, x30, [sp, -48]! - .cfi_def_cfa_offset 48 - .cfi_offset 29, -48 - .cfi_offset 30, -40 - mov x29, sp - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [x0] - str x1, [sp, 40] - mov x1, 0 - bl getpid1 - mov w1, w0 - adrp x0, .LC10 - add x0, x0, :lo12:.LC10 - bl uart_printf - mov w0, 1 - str w0, [sp, 24] - str wzr, [sp, 28] - bl fork1 - str w0, [sp, 28] - ldr w0, [sp, 28] - cmp w0, 0 - bne .L35 -#APP -// 150 "src/shell.c" 1 - mov x0, sp -// 0 "" 2 -#NO_APP - str x0, [sp, 32] - bl getpid1 - mov w5, w0 - ldr w0, [sp, 24] - add x1, sp, 24 - ldr x4, [sp, 32] - mov x3, x1 - mov w2, w0 - mov w1, w5 - adrp x0, .LC11 - add x0, x0, :lo12:.LC11 - bl uart_printf - ldr w0, [sp, 24] - add w0, w0, 1 - str w0, [sp, 24] - bl fork1 - str w0, [sp, 28] - ldr w0, [sp, 28] - cmp w0, 0 - beq .L38 -#APP -// 155 "src/shell.c" 1 - mov x0, sp -// 0 "" 2 -#NO_APP - str x0, [sp, 32] - bl getpid1 - mov w5, w0 - ldr w0, [sp, 24] - add x1, sp, 24 - ldr x4, [sp, 32] - mov x3, x1 - mov w2, w0 - mov w1, w5 - adrp x0, .LC11 - add x0, x0, :lo12:.LC11 - bl uart_printf - b .L37 -.L39: -#APP -// 160 "src/shell.c" 1 - mov x0, sp -// 0 "" 2 -#NO_APP - str x0, [sp, 32] - bl getpid1 - mov w5, w0 - ldr w0, [sp, 24] - add x1, sp, 24 - ldr x4, [sp, 32] - mov x3, x1 - mov w2, w0 - mov w1, w5 - adrp x0, .LC12 - add x0, x0, :lo12:.LC12 - bl uart_printf - mov w0, 5000 - bl delay - ldr w0, [sp, 24] - add w0, w0, 1 - str w0, [sp, 24] -.L38: - ldr w0, [sp, 24] - cmp w0, 4 - ble .L39 -.L37: - bl exit1 - b .L42 -.L35: - bl getpid1 - ldr w2, [sp, 28] - mov w1, w0 - adrp x0, .LC13 - add x0, x0, :lo12:.LC13 - bl uart_printf -.L42: - nop - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [sp, 40] - ldr x2, [x0] - subs x1, x1, x2 - mov x2, 0 - beq .L41 - bl __stack_chk_fail -.L41: - ldp x29, x30, [sp], 48 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE6: - .size fork_test, .-fork_test - .section .rodata - .align 3 -.LC14: - .string "123" - .align 3 -.LC16: - .string "How are you\n" - .align 3 -.LC17: - .string "%s\n" - .align 3 -.LC18: - .string "%d\n" - .text - .align 2 - .global foo - .type foo, %function -foo: -.LFB7: - .cfi_startproc - stp x29, x30, [sp, -160]! - .cfi_def_cfa_offset 160 - .cfi_offset 29, -160 - .cfi_offset 30, -152 - mov x29, sp - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [x0] - str x1, [sp, 152] - mov x1, 0 - adrp x0, .LC14 - add x0, x0, :lo12:.LC14 - bl uart_printf - adrp x0, .LC15 - add x1, x0, :lo12:.LC15 - add x0, sp, 24 - ldr x2, [x1] - str x2, [x0] - ldr x1, [x1, 5] - str x1, [x0, 5] - add x0, sp, 5 - stp xzr, xzr, [x0, 32] - add x0, sp, 5 - stp xzr, xzr, [x0, 48] - add x0, sp, 5 - stp xzr, xzr, [x0, 64] - add x0, sp, 5 - stp xzr, xzr, [x0, 80] - add x0, sp, 5 - stp xzr, xzr, [x0, 96] - add x0, sp, 5 - stp xzr, xzr, [x0, 112] - add x0, sp, 5 - stp xzr, xzr, [x0, 128] - strh wzr, [sp, 149] - strb wzr, [sp, 151] - adrp x0, .LC16 - add x0, x0, :lo12:.LC16 - bl uart_printf - add x0, sp, 24 - mov x1, x0 - adrp x0, .LC17 - add x0, x0, :lo12:.LC17 - bl uart_printf - mov x1, 128 - adrp x0, .LC18 - add x0, x0, :lo12:.LC18 - bl uart_printf - add x0, sp, 24 - mov x1, 128 - bl uart_write1 - bl exit1 - nop - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [sp, 152] - ldr x2, [x0] - subs x1, x1, x2 - mov x2, 0 - beq .L44 - bl __stack_chk_fail -.L44: - ldp x29, x30, [sp], 160 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE7: - .size foo, .-foo - .section .rodata - .align 3 -.LC15: - .string "How are you\n" - .zero 115 - .text - .section .rodata - .align 3 -.LC19: - .string "help" - .align 3 -.LC20: - .string "help : print the help menu\n" - .align 3 -.LC21: - .string "hello : print Hello World!\n" - .align 3 -.LC22: - .string "reboot : reboot the device\n" - .align 3 -.LC23: - .string "hello" - .align 3 -.LC24: - .string "Hello World!\n" - .align 3 -.LC25: - .string "reboot" - .align 3 -.LC26: - .string "Rebooting...\n" - .align 3 -.LC27: - .string "ls" - .align 3 -.LC28: - .string "cat " - .align 3 -.LC29: - .string "./" - .align 3 -.LC30: - .string "timer" - .align 3 -.LC31: - .string "sleep" - .align 3 -.LC32: - .string "thread" - .align 3 -.LC33: - .string ":a:r" - .align 3 -.LC34: - .string "mem" - .align 3 -.LC35: - .string ":s:a:p" - .align 3 -.LC36: - .string "lp" - .align 3 -.LC37: - .string "test" - .align 3 -.LC38: - .string "tet" - .align 3 -.LC39: - .string "command not found: %s\n" - .text - .align 2 - .global check - .type check, %function -check: -.LFB8: - .cfi_startproc - stp x29, x30, [sp, -240]! - .cfi_def_cfa_offset 240 - .cfi_offset 29, -240 - .cfi_offset 30, -232 - mov x29, sp - str x0, [sp, 24] - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [x0] - str x1, [sp, 232] - mov x1, 0 - ldr x0, [sp, 24] - bl parse_command - str x0, [sp, 88] - ldr x0, [sp, 24] - ldrb w0, [x0] - cmp w0, 0 - beq .L93 - ldr x0, [sp, 24] - ldrb w0, [x0] - cmp w0, 10 - beq .L93 - adrp x0, .LC19 - add x1, x0, :lo12:.LC19 - ldr x0, [sp, 24] - bl strcmp - cmp w0, 1 - bne .L49 - adrp x0, .LC20 - add x0, x0, :lo12:.LC20 - bl uart_printf - adrp x0, .LC21 - add x0, x0, :lo12:.LC21 - bl uart_printf - adrp x0, .LC22 - add x0, x0, :lo12:.LC22 - bl uart_printf - b .L45 -.L49: - adrp x0, .LC23 - add x1, x0, :lo12:.LC23 - ldr x0, [sp, 24] - bl strcmp - cmp w0, 1 - bne .L50 - adrp x0, .LC24 - add x0, x0, :lo12:.LC24 - bl uart_printf - b .L45 -.L50: - mov w2, 6 - adrp x0, .LC25 - add x1, x0, :lo12:.LC25 - ldr x0, [sp, 24] - bl strncmp - cmp w0, 1 - bne .L51 - adrp x0, .LC26 - add x0, x0, :lo12:.LC26 - bl uart_printf - ldr x0, [sp, 24] - add x0, x0, 6 - ldrb w0, [x0] - cmp w0, 32 - beq .L52 - mov w0, 50 - bl reset -.L53: - b .L53 -.L52: - str wzr, [sp, 40] - mov w0, 7 - str w0, [sp, 44] - b .L54 -.L56: - ldr w1, [sp, 40] - mov w0, w1 - lsl w0, w0, 2 - add w0, w0, w1 - lsl w0, w0, 1 - str w0, [sp, 40] - ldrsw x0, [sp, 44] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - sub w0, w0, #48 - ldr w1, [sp, 40] - add w0, w1, w0 - str w0, [sp, 40] - ldr w0, [sp, 44] - add w0, w0, 1 - str w0, [sp, 44] -.L54: - ldrsw x0, [sp, 44] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 57 - bhi .L55 - ldrsw x0, [sp, 44] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 47 - bhi .L56 -.L55: - ldr w2, [sp, 40] - ldr w1, [sp, 40] - mov w0, 50 - cmp w2, 50 - csel w0, w1, w0, ge - bl reset -.L57: - b .L57 -.L51: - adrp x0, .LC27 - add x1, x0, :lo12:.LC27 - ldr x0, [sp, 24] - bl strcmp - cmp w0, 0 - beq .L58 - adrp x0, cpio_start - add x0, x0, :lo12:cpio_start - ldr w0, [x0] - bl list - b .L45 -.L58: - mov w2, 4 - adrp x0, .LC28 - add x1, x0, :lo12:.LC28 - ldr x0, [sp, 24] - bl strncmp - cmp w0, 0 - beq .L59 - str wzr, [sp, 48] - b .L60 -.L61: - ldrsw x0, [sp, 48] - add x1, sp, 104 - strb wzr, [x1, x0] - ldr w0, [sp, 48] - add w0, w0, 1 - str w0, [sp, 48] -.L60: - ldr w0, [sp, 48] - cmp w0, 127 - ble .L61 - mov w0, 4 - str w0, [sp, 52] - mov w0, 4 - str w0, [sp, 52] - b .L62 -.L64: - ldrsw x0, [sp, 52] - ldr x1, [sp, 24] - add x0, x1, x0 - ldr w1, [sp, 52] - sub w1, w1, #4 - ldrb w2, [x0] - sxtw x0, w1 - add x1, sp, 104 - strb w2, [x1, x0] - ldr w0, [sp, 52] - add w0, w0, 1 - str w0, [sp, 52] -.L62: - ldrsw x0, [sp, 52] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 45 - bls .L63 - ldrsw x0, [sp, 52] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 122 - bhi .L63 - ldr w0, [sp, 52] - cmp w0, 127 - bgt .L63 - ldrsw x0, [sp, 52] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 0 - bne .L64 -.L63: - ldrsw x0, [sp, 52] - add x1, sp, 104 - strb wzr, [x1, x0] - adrp x0, cpio_start - add x0, x0, :lo12:cpio_start - ldr w1, [x0] - add x0, sp, 104 - bl print_content - b .L45 -.L59: - mov w2, 2 - adrp x0, .LC29 - add x1, x0, :lo12:.LC29 - ldr x0, [sp, 24] - bl strncmp - cmp w0, 0 - beq .L65 - str wzr, [sp, 56] - b .L66 -.L67: - ldrsw x0, [sp, 56] - add x1, sp, 104 - strb wzr, [x1, x0] - ldr w0, [sp, 56] - add w0, w0, 1 - str w0, [sp, 56] -.L66: - ldr w0, [sp, 56] - cmp w0, 127 - ble .L67 - mov w0, 2 - str w0, [sp, 60] - b .L68 -.L70: - ldrsw x0, [sp, 60] - ldr x1, [sp, 24] - add x0, x1, x0 - ldr w1, [sp, 60] - sub w1, w1, #2 - ldrb w2, [x0] - sxtw x0, w1 - add x1, sp, 104 - strb w2, [x1, x0] - ldr w0, [sp, 60] - add w0, w0, 1 - str w0, [sp, 60] -.L68: - ldrsw x0, [sp, 60] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 45 - bls .L69 - ldrsw x0, [sp, 60] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 122 - bhi .L69 - ldr w0, [sp, 60] - cmp w0, 127 - bgt .L69 - ldrsw x0, [sp, 60] - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 0 - bne .L70 -.L69: - add x0, sp, 104 - str x0, [sp, 96] - add x1, sp, 96 - add x0, sp, 104 - bl execute - b .L45 -.L65: - adrp x0, .LC30 - add x1, x0, :lo12:.LC30 - ldr x0, [sp, 24] - bl strcmp - cmp w0, 0 - beq .L71 -#APP -// 233 "src/shell.c" 1 - mrs x1, cntfrq_el0 -mrs x0, cntp_tval_el0 - -// 0 "" 2 -#NO_APP - str w1, [sp, 80] - str w0, [sp, 84] - ldr w1, [sp, 84] - ldr w0, [sp, 80] - sdiv w0, w1, w0 - mov w1, w0 - adrp x0, .LC18 - add x0, x0, :lo12:.LC18 - bl uart_printf - b .L45 -.L71: - mov w2, 5 - adrp x0, .LC31 - add x1, x0, :lo12:.LC31 - ldr x0, [sp, 24] - bl strncmp - cmp w0, 0 - beq .L72 - str wzr, [sp, 64] - b .L73 -.L75: - ldrsw x0, [sp, 64] - add x0, x0, 6 - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w2, [x0] - ldrsw x0, [sp, 64] - add x1, sp, 104 - strb w2, [x1, x0] - ldr w0, [sp, 64] - add w0, w0, 1 - str w0, [sp, 64] -.L73: - ldr w0, [sp, 64] - cmp w0, 4 - bgt .L74 - ldrsw x0, [sp, 64] - add x0, x0, 6 - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - cmp w0, 31 - bls .L74 - ldrsw x0, [sp, 64] - add x0, x0, 6 - ldr x1, [sp, 24] - add x0, x1, x0 - ldrb w0, [x0] - sxtb w0, w0 - cmp w0, 0 - bge .L75 -.L74: - add x0, sp, 104 - bl atoi - str w0, [sp, 76] - ldr w0, [sp, 76] - bl sleep - b .L45 -.L72: - ldr x0, [sp, 88] - ldr x0, [x0] - ldr x2, [x0] - adrp x0, .LC32 - add x1, x0, :lo12:.LC32 - mov x0, x2 - bl strcmp - cmp w0, 0 - beq .L76 - mov w0, 1 - str w0, [sp, 68] - adrp x0, :got:optind - ldr x0, [x0, #:got_lo12:optind] - mov w1, 1 - str w1, [x0] - b .L77 -.L80: - ldr x0, [sp, 88] - ldr w3, [x0, 8] - ldr x0, [sp, 88] - ldr x1, [x0] - adrp x0, .LC33 - add x2, x0, :lo12:.LC33 - mov w0, w3 - bl getopt - strb w0, [sp, 39] - ldrb w0, [sp, 39] - cmp w0, 114 - beq .L77 - cmp w0, 114 - bgt .L77 - cmp w0, 0 - beq .L79 - cmp w0, 97 - bne .L77 - adrp x0, temp_func - add x0, x0, :lo12:temp_func - bl Thread - adrp x0, temp_func2 - add x0, x0, :lo12:temp_func2 - bl Thread - b .L77 -.L79: - str wzr, [sp, 68] - nop -.L77: - ldr w0, [sp, 68] - cmp w0, 0 - bne .L80 - b .L45 -.L76: - ldr x0, [sp, 88] - ldr x0, [x0] - ldr x2, [x0] - adrp x0, .LC34 - add x1, x0, :lo12:.LC34 - mov x0, x2 - bl strcmp - cmp w0, 0 - beq .L81 - mov w0, 1 - str w0, [sp, 72] - adrp x0, :got:optind - ldr x0, [x0, #:got_lo12:optind] - mov w1, 1 - str w1, [x0] - b .L82 -.L88: - ldr x0, [sp, 88] - ldr w3, [x0, 8] - ldr x0, [sp, 88] - ldr x1, [x0] - adrp x0, .LC35 - add x2, x0, :lo12:.LC35 - mov w0, w3 - bl getopt - strb w0, [sp, 38] - ldrb w0, [sp, 38] - cmp w0, 115 - beq .L83 - cmp w0, 115 - bgt .L84 - cmp w0, 112 - beq .L85 - cmp w0, 112 - bgt .L84 - cmp w0, 0 - beq .L86 - cmp w0, 97 - beq .L87 - b .L84 -.L83: - bl pool_status - b .L82 -.L87: - bl printf_thread - b .L82 -.L85: - bl print_node - b .L82 -.L86: - str wzr, [sp, 72] - b .L82 -.L84: - bl show_status - nop -.L82: - ldr w0, [sp, 72] - cmp w0, 0 - bne .L88 - b .L45 -.L81: - ldr x0, [sp, 88] - ldr x0, [x0] - ldr x2, [x0] - adrp x0, .LC36 - add x1, x0, :lo12:.LC36 - mov x0, x2 - bl strcmp - cmp w0, 0 - beq .L89 - bl loadimg - b .L45 -.L89: - ldr x0, [sp, 88] - ldr x0, [x0] - ldr x2, [x0] - adrp x0, .LC37 - add x1, x0, :lo12:.LC37 - mov x0, x2 - bl strcmp - cmp w0, 0 - beq .L90 - adrp x0, fork_test - add x0, x0, :lo12:fork_test - bl Thread - b .L45 -.L90: - ldr x0, [sp, 88] - ldr x0, [x0] - ldr x2, [x0] - adrp x0, .LC38 - add x1, x0, :lo12:.LC38 - mov x0, x2 - bl strcmp - cmp w0, 0 - beq .L91 - adrp x0, foo - add x0, x0, :lo12:foo - bl Thread - b .L45 -.L91: - ldr x1, [sp, 24] - adrp x0, .LC39 - add x0, x0, :lo12:.LC39 - bl uart_printf - b .L45 -.L93: - nop -.L45: - adrp x0, :got:__stack_chk_guard - ldr x0, [x0, #:got_lo12:__stack_chk_guard] - ldr x1, [sp, 232] - ldr x2, [x0] - subs x1, x1, x2 - mov x2, 0 - beq .L92 - bl __stack_chk_fail -.L92: - ldp x29, x30, [sp], 240 - .cfi_restore 30 - .cfi_restore 29 - .cfi_def_cfa_offset 0 - ret - .cfi_endproc -.LFE8: - .size check, .-check - .ident "GCC: (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0" - .section .note.GNU-stack,"",@progbits diff --git a/lab6/src/allocator.c b/lab6/src/allocator.c index cad20f55a..3b4a9fa69 100644 --- a/lab6/src/allocator.c +++ b/lab6/src/allocator.c @@ -7,10 +7,10 @@ #define page_size 4096 //4KB extern unsigned char __heap_start; -uint32 base_addr; -uint32 end_addr; +uint64_t base_addr; +uint64_t end_addr; -uint32 frame_num; +uint64_t frame_num; struct FrameArray** frame_list; struct FrameArray* frame_array; @@ -21,8 +21,8 @@ struct mem_reserved_pool *MR_pool; void* simple_malloc(unsigned int size) { - uint32 *temp=(uint32*)(&__heap_start-8); - uint32 addr = ((uint32) &__heap_start) + *temp; + uint64_t *temp=(uint64_t*)(&__heap_start-8); + uint64_t addr = ((uint64_t) &__heap_start) + *temp; if(size%16 != 0){ size /= 16; size *= 16; @@ -33,12 +33,12 @@ void* simple_malloc(unsigned int size) { } void init_allocator(){ - uint32 *b,*e; + uint32_t *b,*e; b = find_property_value("/memory@0\0","reg\0"); base_addr = letobe(*b); end_addr = letobe(*(b+1)); - //base_addr = 0; - //end_addr = 0x3b400000; + base_addr |= 0xffff000000000000; + end_addr |= 0xffff000000000000; frame_num = (end_addr - base_addr)/page_size; frame_array = simple_malloc(frame_num * sizeof(struct FrameArray)); frame_array[0].val = log2(frame_num); @@ -224,7 +224,8 @@ void* malloc(size_t size){ tmp->status[0] = 0; void* addr = tmp->start; record_mem(addr); - return addr; + uint64_t res = (uint64_t)addr | 0xffff000000000000; + return res; } void pool_status(){ @@ -263,7 +264,7 @@ void clear_pool(){ } } -void memory_reserve(uint32 start,uint32 end){ +void memory_reserve(uint64 start,uint64 end){ if(end < start) return; struct mem_reserved_pool *tmp; tmp = MR_pool; diff --git a/lab6/src/cpio.c b/lab6/src/cpio.c index b3554f72a..ca221a34e 100644 --- a/lab6/src/cpio.c +++ b/lab6/src/cpio.c @@ -6,7 +6,8 @@ #include "queue.h" #include "scheduler.h" #include "task.h" -extern unsigned int cpio_start; +#include "mmu.h" +extern uint64_t cpio_start; typedef struct cpio_newc_header { //cpio new ascii struct char c_magic[6]; @@ -26,7 +27,7 @@ typedef struct cpio_newc_header { //cpio new ascii struct }CPIO_H ; -void list(uint32 addr){ // proceed ls +void list(uint64_t addr){ // proceed ls CPIO_H *cpio=(CPIO_H*) addr; while(strncmp(cpio->c_magic,"070701\0",6)==1){ //c_magic is always "070701" int namesize=a16ntoi(cpio->c_namesize, 8); @@ -52,7 +53,7 @@ void list(uint32 addr){ // proceed ls } } -uint32 find_file_addr(char *file_name, uint32 addr){ +uint64_t find_file_addr(char *file_name, uint64_t addr){ CPIO_H *cpio=(CPIO_H*) addr; while(strncmp(cpio->c_magic,"070701\0",6)==1){ int namesize=a16ntoi(cpio->c_namesize, 8); @@ -79,7 +80,7 @@ uint32 find_file_addr(char *file_name, uint32 addr){ return NULL; } -void* getContent(uint32 addr,int *length){ +void* getContent(uint64_t addr,int *length){ CPIO_H *cpio=(CPIO_H*) addr; int namesize=a16ntoi(cpio->c_namesize, 8); int filesize=a16ntoi(cpio->c_filesize, 8); @@ -88,8 +89,8 @@ void* getContent(uint32 addr,int *length){ return addr; } -void print_content(char *file, uint32 addr){ - uint32 f_addr=find_file_addr(file,addr); +void print_content(char *file, uint64_t addr){ + uint64_t f_addr=find_file_addr(file,addr); if(f_addr != NULL){ int length; char *content_addr = getContent(f_addr, &length); @@ -104,57 +105,29 @@ void print_content(char *file, uint32 addr){ } } -void execute(char *file,char *const argv[]){ - uint32 f_addr=find_file_addr(file,cpio_start); +void copy_content(char *file,void **addr, uint64_t *size){ + uint64_t f_addr=find_file_addr(file,cpio_start); if(f_addr != NULL){ int length; - uint32 address = getContent(f_addr, &length); + uint64_t address = getContent(f_addr, &length); char *content_addr = address; if(address%4 != 0){ address /= 4; address *= 4; address += 4; } - void * start = malloc(length + 0x20000); - byte *ucode = (uint64)start + 0x10000; + void * start = malloc(length); + move_last_mem(0); + byte *ucode = (uint64)start; byte *file = address; for(int i=0;istack + 65535); - return; - }else{ - uart_printf("Not found file \"%s\"\n",file); - return; - } -} \ No newline at end of file diff --git a/lab6/src/exceptions.c b/lab6/src/exceptions.c index 8e37cd47c..1c3b53cbb 100644 --- a/lab6/src/exceptions.c +++ b/lab6/src/exceptions.c @@ -9,6 +9,7 @@ #include "mailbox.h" #include "queue.h" #include "task.h" +#include "mmu.h" #define uart_puts uart_printf @@ -60,17 +61,28 @@ void exception_entry(unsigned long type, unsigned long esr, unsigned long elr, u break; case 4: irq_disable(); - tf->x[0] = set_fork(tf); + tf->x[0] = set_fork(sp_addr); irq_enable(); return; break; case 5: UserExit(); break; - case 6: - tf->x[0] = mailbox_call(tf->x[1],tf->x[0]); + case 6:{ + uint32_t* mbox = malloc(*(uint32_t*)(tf->x[1])); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + uint32_t tr = *((uint32_t*)(tf->x[1]) + i); + mbox[i] = tr; + } + unsigned char channel = tf->x[0]; + mailbox_call(mbox,channel); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + *((uint32_t*)(tf->x[1]) + i) = mbox[i]; + } + free(mbox); return; break; + } case 7: UserKill(tf->x[0]); return; @@ -83,13 +95,30 @@ void exception_entry(unsigned long type, unsigned long esr, unsigned long elr, u sentSignal(tf->x[0],tf->x[1]); return; break; + case 10: + tf->x[0] = mmap_set(tf->x[0],tf->x[1],tf->x[2],tf->x[3]); + return; + break; case 20: - ret_to_sig_han(sp_addr); + ret_to_sig_han(sp_addr + 0x110); return; break; default: break; } + }else if(esr>>26==0b100100 || esr>>26==0b100101){ + uint64_t far; + asm volatile("mrs %[input0],far_el1\n" + : [input0] "=r" (far)); + // For Translation fault + uart_printf("[Translation fault]: 0x%x %x\n", far>>32, far); + if(!mmap_check(far)){ + // For Segmentation fault + uart_printf("[Segmentation fault]: Kill Process\n"); + asm volatile("msr DAIFClr, 0xf\n"); + UserExit(); + } + return; } uart_puts("Synchronous"); break; diff --git a/lab6/src/irq2.c b/lab6/src/irq2.c index 290f60469..428973bec 100644 --- a/lab6/src/irq2.c +++ b/lab6/src/irq2.c @@ -18,7 +18,7 @@ void enable_interrupt_controller() { } int handle_irq() { - uint32 *core_irq=0x40000060; + uint64 *core_irq=0xFFFF000040000060; uint32 *irq; irq = irq0_pending_1; if (*irq & (1 << 29)) { @@ -27,7 +27,7 @@ int handle_irq() { push_queue(handle_uart_irq); return 1; } - if (*core_irq & 2) { + if ((*core_irq) & 2) { *irq &= ~2; core_timer_disable(); push_queue(arm_core_timer_intr_handler); diff --git a/lab6/src/mailbox.c b/lab6/src/mailbox.c index c4f7957b7..2702e6027 100644 --- a/lab6/src/mailbox.c +++ b/lab6/src/mailbox.c @@ -1,5 +1,5 @@ #include "mini_uart.h" -#include "mmio.h" +#include "peripheral/mmio.h" #include "string.h" typedef unsigned int uint32; typedef unsigned char byte; @@ -73,13 +73,6 @@ void get_arm_memory() { mailbox[7] = 0x0; // end tag // tags end mailbox_call(mailbox, 8); - uart_printf("ARM memory base addr: 0x"); - char a[11]; - i16toa(mailbox[5],a,8); - uart_printf(a); - uart_printf(" size: 0x"); - char b[11]; - i16toa(mailbox[6],b,8); - uart_printf(b); - uart_printf("\n"); + uart_printf("ARM memory base addr: 0x%x size: 0x%x\n",mailbox[5],mailbox[6]); + } diff --git a/lab6/src/math.c b/lab6/src/math.c index d9b176926..a018bef5d 100644 --- a/lab6/src/math.c +++ b/lab6/src/math.c @@ -21,4 +21,12 @@ int log2(int logarithm){ } int exp2(int exponent){ return exp(2,exponent); +} + +long long upper_bound(long long dividend, long long divisor){ + return dividend%divisor == 0 ? dividend/divisor : dividend/divisor+1; +} + +unsigned long long min(unsigned long long a,unsigned long long b){ + return a>=b ? b:a; } \ No newline at end of file diff --git a/lab6/src/mmu.c b/lab6/src/mmu.c new file mode 100644 index 000000000..77b91a9fa --- /dev/null +++ b/lab6/src/mmu.c @@ -0,0 +1,176 @@ +#include "mmu.h" +#include "peripheral/mmu.h" +#include "uint.h" +#include "allocator.h" +#include "math.h" +#include "thread.h" +#include "scheduler.h" + +struct pte_manage +{ + byte prot,num; +}*pm; + +void cow_init(){ + pm = malloc(sizeof(struct pte_manage) * (0x40000000/0x1000)); + delete_last_mem(pm); + for(int i=0;i<(0x40000000/0x1000);i++){ + pm[i].prot = 0; + pm[i].num = 0; + } +} + +uint64_t vm_decode(uint64_t va, pagetable_t *p){ + pagetable_t *pt = ((uint64_t) p & 0xfffff000) | 0xffff000000000000; + uint64_t blocksize = 0x8000000000; + for(int i=0;i<4;i++){ + pt = ((uint64_t)pt->entries[va/blocksize] & 0xfffff000) | 0xffff000000000000; + va %= blocksize; + blocksize >>= 9; + if(pt == 0xffff000000000000){ + return NULL; + } + } + uint64_t re = ((uint64_t)pt&0xfffffffff000) + va; + return re; +} + +pagetable_t* allocate_page(){ + pagetable_t* pt = malloc(sizeof(pagetable_t)); + for(int i=0;i<512;i++) pt->entries[i] = NULL; + return pt; +} + +pte_t walk(pagetable_t *pt, uint64_t va, uint64_t end, uint64_t pa, uint64_t blocksize, byte prot){ + if(blocksize < 1<<12){ + uint32_t idx = (pa & 0xfffff000) >> 12; + uint64_t label = PTE_ATTR_BASE; + pm[idx].num=1; + pm[idx].prot = prot; + if(prot == 0) return (pa & 0xfffff000); + if(prot & PROT_WRITE == 0) label |= RO_BIT | PD_ACCESS; + else label |= PD_ACCESS; + if(prot & PROT_EXEC == 0) label |= USR_EXE_NEVER_BIT; + return (pa & 0xfffff000) | label; + }else{ + uint64_t start = va / blocksize; + uint64_t num = upper_bound(end,blocksize) - va/blocksize; + if(pt == NULL){ + pt = allocate_page(); + move_last_mem(0); + }else{ + pt = ((uint64_t)pt & ~(uint64_t)0x3) | 0xffff000000000000; + } + for(int i=0;ientries[start + i] = walk(pt->entries[start + i], va2 - gap,min(end,(va2/blocksize + 1) * blocksize) - gap,pa + va2 - va,blocksize >> (uint64_t)9,prot); + } + return ((uint64_t)pt & (uint64_t)0xffffffff) | 0b11; + } +} + +void mappages(pagetable_t* pagetable, uint64_t va, uint64_t size, uint64_t pa, byte prot){ + uint64_t end_addr = va + size; + walk(pagetable, va, end_addr, pa, (uint64_t)1 << 39, prot); +} + +void SetTaskStackPagetable(pagetable_t *pt, void* stack_addr){ + int stack_size = 0x4000; + mappages(pt,0xffffffffb000,stack_size, (uint64_t)stack_addr & 0xfffffffc,PROT_READ | PROT_WRITE); +} + +void SetTaskCodePagetable(pagetable_t *pt, void* code_addr, uint64_t size){ + mappages(pt,0x0, size, (uint64_t)code_addr & 0xfffffffc, PROT_READ | PROT_EXEC); +} + +void SetPeripherialPagetable(pagetable_t *pt){ + mappages(pt,0x3c000000, 0x4000000, 0x3c000000, PROT_READ | PROT_WRITE); +} + +void* mmap_set(void* addr, size_t len, int prot, int flags){ + uint64_t align_addr = (uint64_t)addr & ~(uint64_t)0xfff; + thread_t *t = get_current(); + while(vm_decode(align_addr,t->page_table) != NULL){ + align_addr += 0x1000; + if(align_addr >= 0xffffffffb000) return NULL; + } + for(int i=0;i>12;i++) mappages(t->page_table,align_addr + i * 0x1000,0x1000,(uint64_t)prot<<12,0); + + return align_addr; +} + +bool mmap_check(uint64_t FAR){ + thread_t *t = get_current(); + if(FAR >= 0xFFFFFFFFB000 && FAR < 0xFFFFFFFFF000){ + uint64_t pa = vm_decode(FAR & ~(uint64_t)0xfff,t->page_table); + if(pa == NULL){ + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, (uint64_t)malloc(0x1000),PROT_READ | PROT_WRITE); + }else{ + byte *stack = (pa & ~(uint64_t)0xfff) | 0xffff000000000000; + byte *new_stack = malloc(0x1000); + for (int i=0;i<0x1000;i++) new_stack[i] = stack[i]; + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, new_stack,PROT_READ | PROT_WRITE); + } + set_ttbr0_el1(t->page_table); + return true; + } + if(FAR >= 0x3c000000 && FAR < 0x40000000){ + SetPeripherialPagetable(t->page_table); + set_ttbr0_el1(t->page_table); + return true; + } + uint64_t align_addr = (uint64_t)FAR & ~(uint64_t)0xfff; + uint64_t addr = vm_decode(align_addr,t->page_table)>>12; + if(addr != 0){ + if(addr < 0x10000){ + uint64_t *pa = malloc(0x1000); + for(int i=0;i<200;i++) pa[i] = 0; + mappages(t->page_table,align_addr,0x1000,pa,addr); + }else{ + if((pm[addr].prot&PROT_WRITE) == 0) return false; + uint64_t *space = (addr<<12) | 0xffff000000000000; + uint64_t *new_space = malloc(0x1000); + for(int i=0;i<0x200;i++) new_space[i] = space[i]; + mappages(t->page_table,align_addr,0x1000,new_space,pm[addr].prot); + } + set_ttbr0_el1(t->page_table); + return true; + } + return false; +} + + +void map_pages(uint64_t des, uint64_t src){ + pagetable_t* pt_des = (des&~(uint64_t)0xfff) | 0xffff000000000000; + pagetable_t* pt_src = (src&~(uint64_t)0xfff) | 0xffff000000000000; + for(int i=0;i<512;i++){ + if(pt_src->entries[i] == NULL) continue; + pagetable_t* pt_des_l2 = allocate_page(); + pt_des->entries[i] = ((uint64_t)pt_des_l2 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l2 = ((uint64_t)pt_src->entries[i] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int j=0;j<512;j++){ + if(pt_src_l2->entries[j] == NULL) continue; + pagetable_t* pt_des_l1 = allocate_page(); + pt_des_l2->entries[i] = ((uint64_t)pt_des_l1 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l1 = ((uint64_t)pt_src_l2->entries[j] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int k=0;k<512;k++){ + if(pt_src_l1->entries[k] == NULL) continue; + pagetable_t* pt_des_l0 = allocate_page(); + pt_des_l1->entries[i] = ((uint64_t)pt_des_l0 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l0 = ((uint64_t)pt_src_l1->entries[k] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int l=0;l<512;l++){ + if(pt_src_l0->entries[l] == NULL) continue; + pm[((uint32_t)(pt_src_l0->entries[l]))>>12].num++; + pt_src_l0->entries[l] |= RO_BIT; + pt_des_l0->entries[l] = pt_src_l0->entries[l]; + } + } + } + } +} \ No newline at end of file diff --git a/lab6/src/mmu_asm.S b/lab6/src/mmu_asm.S index abb5c2551..1579a5980 100644 --- a/lab6/src/mmu_asm.S +++ b/lab6/src/mmu_asm.S @@ -5,6 +5,7 @@ .global identity_paging .global page_table_set .global setup_mmu +.global set_ttbr0_el1 disable_mmu: ldr x1, =0 //close MMU @@ -93,4 +94,16 @@ setup_mmu: bl set_tcr bl set_mair bl identity_paging + ret + +set_ttbr0_el1: + dsb ish // ensure write has completed + msr ttbr0_el1, x0 // switch translation based address. + tlbi vmalle1is // invalidate all TLB entries + dsb ish // ensure completion of TLB invalidatation + isb // clear pipeline + ret +.global get_ttbr0_el1 +get_ttbr0_el1: + mrs x0, ttbr0_el1 ret \ No newline at end of file diff --git a/lab6/src/queue.c b/lab6/src/queue.c index 5f39c9b82..2512d2073 100644 --- a/lab6/src/queue.c +++ b/lab6/src/queue.c @@ -34,7 +34,6 @@ int schedule(){ void push2run_queue(struct thread* thread){ if(run_queue != NULL){ - struct thread *tmp = run_queue; while(tmp->next != NULL){ tmp = tmp->next; diff --git a/lab6/src/reboot.c b/lab6/src/reboot.c index a6de4e65a..867cabdf7 100644 --- a/lab6/src/reboot.c +++ b/lab6/src/reboot.c @@ -1,6 +1,6 @@ #define PM_PASSWORD 0x5a000000 -#define PM_RSTC ((volatile unsigned int*)0x3F10001c) -#define PM_WDOG ((volatile unsigned int*)0x3F100024) +#define PM_RSTC ((volatile unsigned int*)0xFFFF00003F10001c) +#define PM_WDOG ((volatile unsigned int*)0xFFFF00003F100024) void reset(int tick){ // reboot after watchdog timer expire *PM_RSTC = PM_PASSWORD | 0x20; // full reset diff --git a/lab6/src/scheduler.S b/lab6/src/scheduler.S index a4bed99f1..1460e5df0 100644 --- a/lab6/src/scheduler.S +++ b/lab6/src/scheduler.S @@ -111,7 +111,6 @@ sig_handler_assembly: .global ret_to_sig_han ret_to_sig_han: msr daifclr, 0x0 - add x0, x0, #0x110 mov sp, x0 ldr lr, [sp, 0 * 16] add sp, sp, #16 @@ -148,8 +147,9 @@ from_el1_to_el0_forsig: .global get_el get_el: mrs x0, CurrentEL - asr x0, x0, #2 + lsr x0, x0, #2 and x0, x0, #3 + ret .global call_exit call_exit: diff --git a/lab6/src/shell.c b/lab6/src/shell.c index 728628490..d447f3dbb 100644 --- a/lab6/src/shell.c +++ b/lab6/src/shell.c @@ -9,6 +9,8 @@ #include "getopt.h" #include "scheduler.h" #include "loadimg.h" +#include "mailbox.h" +#include "mmu.h" struct ARGS{ char** argv; @@ -18,14 +20,14 @@ struct ARGS{ extern unsigned char __heap_start, _end_, _begin_; extern byte __dtb_addr; -uint32 cpio_start,cpio_end; +uint64_t cpio_start,cpio_end; char cmd_buffer[1024]; unsigned int cmd_index = 0; unsigned int cmd_flag = 0; void shell_init(){ - uint32 *heap = (uint32*)(&__heap_start-8); + uint64 *heap = (uint64*)(&__heap_start-8); *heap &= 0x00000000; uart_init(); uart_printf("\n\n\nHello From RPI3\n"); @@ -33,7 +35,7 @@ void shell_init(){ uart_flush(); core_timer_init(); init_allocator(); - uint32 *ramf_start,*ramf_end; + uint64 *ramf_start,*ramf_end; ramf_start=find_property_value("/chosen\0","linux,initrd-start\0"); //get ramf start addr from dtb ramf_end=find_property_value("/chosen\0","linux,initrd-end\0"); //get ramf end addr from dtb if(ramf_start != 0){ @@ -43,20 +45,25 @@ void shell_init(){ uart_printf("Ramf end: 0x%x\n",letobe(*ramf_end)); cpio_end=letobe(*ramf_end); } - memory_reserve(0x0,0x1000); //Spin tables for multicore boot + cpio_start |= 0xFFFF000000000000; + cpio_end |= 0xFFFF000000000000; + memory_reserve(0xffff000000000000,0xffff000000080000); //Spin tables for multicore boot + + memory_reserve(0xFFFF000000001000,0xFFFF000000003000); //Spin tables for multicore boot memory_reserve(cpio_start,cpio_end); //Initramfs memory_reserve(&_begin_,&_end_); //Kernel image in the physical memory and simple allocator - uint32 *addr = &__dtb_addr; + uint64 *addr = &__dtb_addr; memory_reserve(*addr,*addr + 0x100000); //Device tree - memory_reserve(0x0,0x80000); //Kernel stack + memory_reserve(0xFFFF000000000000,0xFFFF000000080000); //Kernel stack init_thread(); + cow_init(); } void reset_flag(){ @@ -269,7 +276,8 @@ void check(char *input){ }else if(strcmp(cmd->argv[0],"lp")){ loadimg(); }else if(strcmp(cmd->argv[0],"test")){ - Thread(fork_test); + get_board_revision(); + get_arm_memory(); }else{ uart_printf("command not found: %s\n",input); } diff --git a/lab6/src/signal.c b/lab6/src/signal.c index c02e41bb6..5f885130c 100644 --- a/lab6/src/signal.c +++ b/lab6/src/signal.c @@ -4,7 +4,7 @@ #include "uint.h" #include "queue.h" #include "excep.h" - +#include "mmu.h" extern struct thread *threads[thread_numbers]; int signal(int SIGNAL, void (*handler)()){ @@ -20,9 +20,17 @@ void* sig_handler_kernel(struct thread *t){ for(int i=0;i<32;i++){ if((t->signal & 1<sig_handler[i] != NULL){ t->signal &= !(1<sig_handler[i], (uint64)sp + 0x10000, NULL); + pagetable_t *pt = ((uint64_t)t->page_table & ~(uint64_t) 0b11) | 0xffff000000000000; + void *sp = malloc(0x4000); + pagetable_t *tmp_pt = allocate_page(); + t->page_table = ((uint64_t)tmp_pt & ~0xffff000000000000) | 0b11; + SetTaskStackPagetable(t->page_table, sp); + for(int j=0;j<0x1f0;j++) tmp_pt->entries[j] = pt->entries[j]; + set_ttbr0_el1(t->page_table); + sig_handler_assembly(t->sig_handler[i], 0xfffffffff000, NULL); free(sp); + t->page_table = pt; + set_ttbr0_el1(t->page_table); } } return t; diff --git a/lab6/src/start.S b/lab6/src/start.S index 5cc34a86d..6d5d695a6 100644 --- a/lab6/src/start.S +++ b/lab6/src/start.S @@ -67,7 +67,7 @@ from_el2_to_el1: eret from_el1_to_el0: - msr elr_el1, x22 + msr elr_el1, x19 msr sp_el0, x20 @@ -77,9 +77,3 @@ from_el1_to_el0: eret - -user_process: - mov x0, x22 - blr x19 - mov x8, #5 - svc #0 diff --git a/lab6/src/string.c b/lab6/src/string.c index 20f29a02e..643c0b45a 100644 --- a/lab6/src/string.c +++ b/lab6/src/string.c @@ -85,13 +85,14 @@ void strcpy(char *string1, char* string2, int length){ string2[length]='\0'; } -uint32 letobe(uint32 o){ +uint64 letobe(uint64 o){ byte *temp = (byte*) &o; - uint32 result=0; + uint64 result=0; for(int i=0;i<4;i++){ result *= 256; result += temp[i]; } + return result; } diff --git a/lab6/src/task.c b/lab6/src/task.c index 35239cfd7..7846e3638 100644 --- a/lab6/src/task.c +++ b/lab6/src/task.c @@ -5,6 +5,8 @@ #include "scheduler.h" #include "allocator.h" #include "excep.h" +#include "mmu.h" +#include "cpio.h" struct thread* ReadyList = NULL; extern struct thread *threads[thread_numbers]; @@ -15,6 +17,7 @@ void UserScheduler(){ exit(); }else{ struct thread *t = ReadyListPop(); + set_ttbr0_el1(t->page_table); SwitchTo(t); } } @@ -32,7 +35,7 @@ void* ReadyListPop(){ } void InitUserTaskScheduler(){ - thread_timer(); + //thread_timer(); struct thread *t = get_current(); t->status = dead; UserScheduler(); @@ -73,28 +76,41 @@ int UserKill(pid_t pid){ int UserThread(void* func,void* arg){ struct thread *t; t = malloc(sizeof(struct thread)); - unsigned char* kstack = malloc(0x10000); + for(int i=0;itid = i; + break; + } + } delete_last_mem(); + unsigned char* kstack = malloc(0x10000); t->next = NULL; for(int i=0;i<32;i++) t->sig_handler[i] = NULL; t->sig_handler[9] = call_exit; t->sig_handler[10] = UserKill; + t->page_table = ((uint64_t)allocate_page() | 0b11) & ~0xffff000000000000; t->signal = 0; t->childs = NULL; + //t->ustack = malloc(0x4000); t->kstack = kstack; - t->registers[0] = func; - t->registers[1] = ( (uint64)(t->stack + 0x10000) & 0xfffffff0); + t->registers[0] = 0x0; + t->registers[1] = 0xfffffffff000; t->registers[2] = arg; - t->registers[3] = user_process; - t->registers[10] = (unsigned long long)(kstack + 0x10000) & 0xfffffff0; + t->registers[10] = ( (uint64)(t->kstack + 0x10000) & 0xfffffffffffffff0); t->registers[11] = from_el1_to_el0; t->registers[12] = t->registers[10]; + //SetTaskStackPagetable(t->page_table, t->ustack); + struct thread *temp = get_current(); t->ptid = temp->tid; t->malloc_table[0] = NULL; struct thread_sibling *temp2 = temp->childs; struct thread_sibling *new_child = malloc(sizeof(struct thread_sibling)); - delete_last_mem(); + //move_last_mem(t->tid); + move_last_mem(t->tid); + move_last_mem(t->tid); + move_last_mem(t->tid); void *a; new_child->self = t; new_child->next = NULL; @@ -106,13 +122,6 @@ int UserThread(void* func,void* arg){ } temp2->next = new_child; } - for(int i=0;itid = i; - break; - } - } PushToReadyList(t->tid); return t->tid; } @@ -120,13 +129,15 @@ int UserThread(void* func,void* arg){ int set_fork(void* sp){ byte *t = get_current(); tid_t tid = UserThread(return_to_child,NULL); - free(threads[tid]->kstack); + pagetable_t* pagetable = threads[tid]->page_table; + unsigned char* kstack = threads[tid]->kstack; + byte *child = threads[tid]; uint64 gap = (uint64)child - (uint64)t; for(int i=0;ikstack; threads[tid]->tid = tid; @@ -136,10 +147,31 @@ int set_fork(void* sp){ threads[tid]->registers[12] = tf; threads[tid]->next = NULL; threads[tid]->kstack = kstack; + threads[tid]->page_table = pagetable; for(int i=0;i<0x10000;i++) kstack[i] = tmp->kstack[i]; - tf->sp_el0 += gap; + map_pages(threads[tid]->page_table,tmp->page_table); + set_ttbr0_el1(tmp->page_table); tf->spsr_el1 = 0; tf->x[0] = 0; - tf->x[29] += gap; return tid; } + +void execute(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0) return; + int tid = UserThread(code,NULL); + SetTaskCodePagetable(threads[tid]->page_table,code,length); + InitUserTaskScheduler(); +} + +void exec(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0) return; + struct thread *t = get_current(); + SetTaskCodePagetable(t->page_table,code,length); + from_el1_to_el0(code, 0xfffffffff000); +} \ No newline at end of file diff --git a/lab6/src/thread.c b/lab6/src/thread.c index 8725ab3ae..543e3455c 100644 --- a/lab6/src/thread.c +++ b/lab6/src/thread.c @@ -24,10 +24,10 @@ int Thread(void *func(void),...){ t->signal = 0; t->status = starting; t->childs = NULL; + t->ustack = malloc(0x10000); t->registers[0] = func; - t->registers[1] = ( (uint64)(t->stack + 0x10000) & 0xfffffff0); + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); t->registers[2] = arg; - t->registers[4] = user_process; struct thread *temp = get_current(); t->ptid = temp->tid; t->malloc_table[0] = NULL; @@ -52,6 +52,7 @@ int Thread(void *func(void),...){ break; } } + move_last_mem(t->tid); push2run_queue(t); return t->tid; } @@ -69,8 +70,10 @@ void set_first_thread(){ threads[0] = t; t->malloc_table[0] = NULL; t->next = NULL; + t->ustack = malloc(0x10000); + delete_last_mem(); t->registers[0] = idle; - t->registers[1] = ( (uint64)(t->stack + 0x10000) & 0xfffffff0); + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); for(int i=0;i<32;i++) t->sig_handler[i] = NULL; push2run_queue(t); } @@ -100,6 +103,7 @@ void idle(){ while(1){ handle_child(0); kill_zombies(); + free_mem_table(threads[0]); Thread(uart_read_line); schedule(); } @@ -177,7 +181,7 @@ void printf_thread(){ uart_printf("addr: 0x%x\n",threads[i]); uart_printf("status: %d\n",threads[i]->status); uart_printf("ptid: %d\n",threads[i]->ptid); - uart_printf("stack: 0x%x ~ 0x%x\n",threads[i]->stack,threads[i]->stack+0x10000); + uart_printf("stack: 0x%x ~ 0x%x\n",threads[i]->ustack,threads[i]->ustack+0x10000); } } } @@ -189,18 +193,17 @@ int getpid(){ int kill(pid_t pid){ free_mem_table(threads[pid]); - //free(threads[pid]); threads[pid]->status = dead; threads[pid] = NULL; remove_from_queue(pid); } -void move_last_mem(tid_t tid){ +int move_last_mem(tid_t tid){ struct thread *now = get_current(); void* addr; for(int i=0;i<256;i++){ if(now->malloc_table[i] == NULL){ - if(i == 0) return; + if(i == 0) return -1; addr = now->malloc_table[i-1]; now->malloc_table[i-1] = NULL; break; @@ -213,7 +216,7 @@ void move_last_mem(tid_t tid){ if(t->malloc_table[i] == NULL){ t->malloc_table[i] = addr; if(i<255) t->malloc_table[i+1] = NULL; - break; + return 0; } } } \ No newline at end of file diff --git a/lab6/src/timer.S b/lab6/src/timer.S index c13c76aad..c995ff31b 100644 --- a/lab6/src/timer.S +++ b/lab6/src/timer.S @@ -1,4 +1,4 @@ -#define CORE0_TIMER_IRQ_CTRL 0x40000040 +#define CORE0_TIMER_IRQ_CTRL 0xFFFF000040000040 .global core_timer_enable .global core_timer_disable diff --git a/lab7/.vscode/c_cpp_properties.json b/lab7/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..9b3b8cfad --- /dev/null +++ b/lab7/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/lab7/.vscode/configurationCache.log b/lab7/.vscode/configurationCache.log new file mode 100644 index 000000000..87d835e71 --- /dev/null +++ b/lab7/.vscode/configurationCache.log @@ -0,0 +1 @@ +{"buildTargets":["all","clean","debug","dev","kernel8.img","out","out/allocator.o","out/buffer.o","out/core_timer.o","out/cpio.o","out/dtb.o","out/excep_handler.o","out/exceptions.o","out/framebuffer.o","out/getopt.o","out/interrupt_queue.o","out/irq.o","out/irq2.o","out/jump.o","out/loadimg.o","out/local_timer.o","out/mailbox.o","out/main.o","out/math.o","out/mini_uart.o","out/mmu.o","out/mmu_asm.o","out/panic.o","out/priority_queue.o","out/queue.o","out/reboot.o","out/scheduler.o","out/shell.o","out/signal.o","out/start.o","out/string.o","out/task.o","out/temp.o","out/thread.o","out/timer.o","out/tmpfs.o","out/vfs.o","run","screen","sender","super","tty","user/out","usercode.img"],"launchTargets":["/home/yuhu/osc2022/lab7>kernel8.elf()","/home/yuhu/osc2022/lab7>sender()"],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":["/home/yuhu/osc2022/lab7","/home/yuhu/osc2022/lab7/include","/home/yuhu/osc2022/lab7/src"],"compilerArgs":["-o","sender"],"compilerPath":"/usr/bin/g++-11","windowsSdkVersion":""},"fileIndex":[["/home/yuhu/osc2022/lab7/src/panic.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/panic.c","path":"/home/yuhu/osc2022/lab7/src/panic.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/panic.c","-o","out/panic.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/panic.c"}}],["/home/yuhu/osc2022/lab7/src/mmu.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/mmu.c","path":"/home/yuhu/osc2022/lab7/src/mmu.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mmu.c","-o","out/mmu.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/mmu.c"}}],["/home/yuhu/osc2022/lab7/src/getopt.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/getopt.c","path":"/home/yuhu/osc2022/lab7/src/getopt.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/getopt.c","-o","out/getopt.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/getopt.c"}}],["/home/yuhu/osc2022/lab7/src/tmpfs.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/tmpfs.c","path":"/home/yuhu/osc2022/lab7/src/tmpfs.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/tmpfs.c","-o","out/tmpfs.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/tmpfs.c -o out/tmpfs.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/tmpfs.c"}}],["/home/yuhu/osc2022/lab7/src/core_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/core_timer.c","path":"/home/yuhu/osc2022/lab7/src/core_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/core_timer.c","-o","out/core_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/core_timer.c"}}],["/home/yuhu/osc2022/lab7/src/dtb.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/dtb.c","path":"/home/yuhu/osc2022/lab7/src/dtb.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/dtb.c","-o","out/dtb.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/dtb.c"}}],["/home/yuhu/osc2022/lab7/src/mailbox.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/mailbox.c","path":"/home/yuhu/osc2022/lab7/src/mailbox.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mailbox.c","-o","out/mailbox.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/mailbox.c"}}],["/home/yuhu/osc2022/lab7/src/framebuffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/framebuffer.c","path":"/home/yuhu/osc2022/lab7/src/framebuffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/framebuffer.c","-o","out/framebuffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/framebuffer.c -o out/framebuffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/framebuffer.c"}}],["/home/yuhu/osc2022/lab7/src/queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/queue.c","path":"/home/yuhu/osc2022/lab7/src/queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/queue.c","-o","out/queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/queue.c"}}],["/home/yuhu/osc2022/lab7/src/exceptions.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/exceptions.c","path":"/home/yuhu/osc2022/lab7/src/exceptions.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/exceptions.c","-o","out/exceptions.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/exceptions.c"}}],["/home/yuhu/osc2022/lab7/src/task.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/task.c","path":"/home/yuhu/osc2022/lab7/src/task.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/task.c","-o","out/task.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/task.c"}}],["/home/yuhu/osc2022/lab7/src/mini_uart.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/mini_uart.c","path":"/home/yuhu/osc2022/lab7/src/mini_uart.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mini_uart.c","-o","out/mini_uart.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/mini_uart.c"}}],["/home/yuhu/osc2022/lab7/src/math.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/math.c","path":"/home/yuhu/osc2022/lab7/src/math.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/math.c","-o","out/math.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/math.c"}}],["/home/yuhu/osc2022/lab7/src/allocator.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/allocator.c","path":"/home/yuhu/osc2022/lab7/src/allocator.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/allocator.c","-o","out/allocator.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/allocator.c"}}],["/home/yuhu/osc2022/lab7/src/cpio.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/cpio.c","path":"/home/yuhu/osc2022/lab7/src/cpio.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/cpio.c","-o","out/cpio.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/cpio.c"}}],["/home/yuhu/osc2022/lab7/src/local_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/local_timer.c","path":"/home/yuhu/osc2022/lab7/src/local_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/local_timer.c","-o","out/local_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/local_timer.c"}}],["/home/yuhu/osc2022/lab7/src/signal.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/signal.c","path":"/home/yuhu/osc2022/lab7/src/signal.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/signal.c","-o","out/signal.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/signal.c"}}],["/home/yuhu/osc2022/lab7/src/main.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/main.c","path":"/home/yuhu/osc2022/lab7/src/main.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/main.c","-o","out/main.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/main.c"}}],["/home/yuhu/osc2022/lab7/src/shell.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/shell.c","path":"/home/yuhu/osc2022/lab7/src/shell.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/shell.c","-o","out/shell.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/shell.c"}}],["/home/yuhu/osc2022/lab7/src/buffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/buffer.c","path":"/home/yuhu/osc2022/lab7/src/buffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/buffer.c","-o","out/buffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/buffer.c"}}],["/home/yuhu/osc2022/lab7/src/irq2.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/irq2.c","path":"/home/yuhu/osc2022/lab7/src/irq2.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/irq2.c","-o","out/irq2.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/irq2.c"}}],["/home/yuhu/osc2022/lab7/src/priority_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/priority_queue.c","path":"/home/yuhu/osc2022/lab7/src/priority_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/priority_queue.c","-o","out/priority_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/priority_queue.c"}}],["/home/yuhu/osc2022/lab7/src/reboot.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/reboot.c","path":"/home/yuhu/osc2022/lab7/src/reboot.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/reboot.c","-o","out/reboot.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/reboot.c"}}],["/home/yuhu/osc2022/lab7/src/loadimg.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/loadimg.c","path":"/home/yuhu/osc2022/lab7/src/loadimg.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/loadimg.c","-o","out/loadimg.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/loadimg.c"}}],["/home/yuhu/osc2022/lab7/src/thread.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/thread.c","path":"/home/yuhu/osc2022/lab7/src/thread.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/thread.c","-o","out/thread.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/thread.c"}}],["/home/yuhu/osc2022/lab7/src/string.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/string.c","path":"/home/yuhu/osc2022/lab7/src/string.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/string.c","-o","out/string.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/string.c"}}],["/home/yuhu/osc2022/lab7/src/vfs.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/vfs.c","path":"/home/yuhu/osc2022/lab7/src/vfs.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/vfs.c","-o","out/vfs.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/vfs.c -o out/vfs.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/vfs.c"}}],["/home/yuhu/osc2022/lab7/src/interrupt_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/src/interrupt_queue.c","path":"/home/yuhu/osc2022/lab7/src/interrupt_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab7/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/interrupt_queue.c","-o","out/interrupt_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/src/interrupt_queue.c"}}],["/home/yuhu/osc2022/lab7/sendfile.cpp",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab7/sendfile.cpp","path":"/home/yuhu/osc2022/lab7/sendfile.cpp","scheme":"file"},"configuration":{"defines":[],"includePath":[],"forcedInclude":[],"compilerPath":"/usr/bin/g++-11","compilerArgs":["-o","sender"],"windowsSdkVersion":""},"compileCommand":{"command":"g++-11 sendfile.cpp -o sender","directory":"/home/yuhu/osc2022/lab7","file":"/home/yuhu/osc2022/lab7/sendfile.cpp"}}]]}} \ No newline at end of file diff --git a/lab7/.vscode/dryrun.log b/lab7/.vscode/dryrun.log new file mode 100644 index 000000000..dbc7a5444 --- /dev/null +++ b/lab7/.vscode/dryrun.log @@ -0,0 +1,44 @@ +make --dry-run --always-make --keep-going --print-directory +make: Entering directory '/home/yuhu/osc2022/lab7' +mkdir -p out +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/tmpfs.c -o out/tmpfs.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/framebuffer.c -o out/framebuffer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/vfs.c -o out/vfs.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/start.S -o out/start.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/timer.S -o out/timer.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq.S -o out/irq.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/scheduler.S -o out/scheduler.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/temp.S -o out/temp.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu_asm.S -o out/mmu_asm.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/excep_handler.S -o out/excep_handler.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/jump.S -o out/jump.o +aarch64-linux-gnu-ld -T src/linker.ld -o kernel8.elf out/panic.o out/mini_uart.o out/core_timer.o out/queue.o out/dtb.o out/task.o out/allocator.o out/framebuffer.o out/buffer.o out/exceptions.o out/math.o out/main.o out/priority_queue.o out/reboot.o out/thread.o out/string.o out/vfs.o out/mailbox.o out/mmu.o out/getopt.o out/loadimg.o out/cpio.o out/local_timer.o out/signal.o out/shell.o out/tmpfs.o out/irq2.o out/interrupt_queue.o out/timer.o out/temp.o out/start.o out/jump.o out/irq.o out/scheduler.o out/mmu_asm.o out/excep_handler.o +aarch64-linux-gnu-objcopy -O binary kernel8.elf kernel8.img +g++-11 sendfile.cpp -o sender +make: Leaving directory '/home/yuhu/osc2022/lab7' + diff --git a/lab7/.vscode/settings.json b/lab7/.vscode/settings.json new file mode 100644 index 000000000..cbf848651 --- /dev/null +++ b/lab7/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "uint.h": "c", + "mmu.h": "c", + "mini_uart.h": "c", + "queue.h": "c", + "task.h": "c", + "vfs.h": "c", + "device.h": "c" + }, + "C_Cpp.errorSquiggles": "Disabled" +} \ No newline at end of file diff --git a/lab7/.vscode/targets.log b/lab7/.vscode/targets.log new file mode 100644 index 000000000..6ddc91c3c --- /dev/null +++ b/lab7/.vscode/targets.log @@ -0,0 +1,973 @@ +make all --print-data-base --no-builtin-variables --no-builtin-rules --question +# GNU Make 4.2.1 +# Built for x86_64-pc-linux-gnu +# Copyright (C) 1988-2016 Free Software Foundation, Inc. +# License GPLv3+: GNU GPL version 3 or later +# This is free software: you are free to change and redistribute it. +# There is NO WARRANTY, to the extent permitted by law. + +# Make data base, printed on Mon May 30 23:30:12 2022 + +# Variables + +# automatic +> 3; +__relocation = 0x01080000; +__dtb_addr = 0x02080000; diff --git a/lab7/bootloader/src/loadimg.c b/lab7/bootloader/src/loadimg.c new file mode 100644 index 000000000..14a3b150f --- /dev/null +++ b/lab7/bootloader/src/loadimg.c @@ -0,0 +1,60 @@ +#include "mini_uart.h" +#include "string.h" + +#define byte unsigned char +#define uint32 unsigned int +#define block_size 128 + + +void loadimg(){ + uint32 addr=0x80000; // load to 0x80000 + uart_printf("Start receiving.\n"); + byte SIZE[5]; + byte par=0; + for(int i=0;i<5;i++){ //receive file size + byte temp=uart_read_raw(); + SIZE[i]=temp; + if(i!=4) par ^= temp; + } + if(par != SIZE[4]){ + uart_printf("Receiving error\n"); + return; + } + uint32 size=0; + for(int i=0;i<4;i++){ + size <<= 8; + size += SIZE[i]; + } + byte *kernel = (byte*) addr; + byte check_byte=0; + int j=0; + for(int i=0;i=5){ + uart_printf("Error! Please try again later.\n"); + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(2); + return; + } + uart_printf("Something went wrong. Trying to fix it. %d\n",i/8); + i-=8; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(1); + }else{ + j=0; + check_byte &= 0; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(0); + } + } + } + void (*start_os)(void) = (void *)kernel; //set start_os's addr to the loaded image's addr + uart_printf("Loading Complete.\n"); + uart_printf("Redirecting to 0x%x\n",addr); + start_os(); +} \ No newline at end of file diff --git a/lab7/bootloader/src/mailbox.c b/lab7/bootloader/src/mailbox.c new file mode 100644 index 000000000..c4f7957b7 --- /dev/null +++ b/lab7/bootloader/src/mailbox.c @@ -0,0 +1,85 @@ +#include "mini_uart.h" +#include "mmio.h" +#include "string.h" +typedef unsigned int uint32; +typedef unsigned char byte; + +#define MAILBOX_BASE MMIO_BASE + 0xb880 + +#define MAILBOX_READ (uint32*)(MAILBOX_BASE) +#define MAILBOX_STATUS (uint32*)(MAILBOX_BASE+0x18) +#define MAILBOX_WRITE (uint32*)(MAILBOX_BASE+0x20) + +#define MAILBOX_EMPTY 0x40000000 +#define MAILBOX_FULL 0x80000000 +#define MAILBOX_CODE_BUF_RES_SUCC 0x80000000 +#define MAILBOX_CODE_BUF_REQ 0x00000000 +#define MAILBOX_CODE_TAG_REQ 0x00000000 + +#define GET_ARM_MEMORY 0x00010005 +#define GET_BOARD_REVISION 0x00010002 +#define REQUEST_CODE 0x00000000 +#define REQUEST_SUCCEED 0x80000000 +#define REQUEST_FAILED 0x80000001 +#define TAG_REQUEST_CODE 0x00000000 +#define END_TAG 0x00000000 + +void mailbox_call(uint32 *mailbox,byte channel){ + uint32 r = (uint32)(((unsigned long)mailbox) & (~0xF)) | (channel & 0xF); + while (*MAILBOX_STATUS & MAILBOX_FULL) { + } + *MAILBOX_WRITE = r; + while(1){ + while(*MAILBOX_STATUS & MAILBOX_EMPTY){ + } + + if (r == *MAILBOX_READ){ + return mailbox[1] == MAILBOX_CODE_BUF_RES_SUCC; + } + } + return 0; +} + +void get_board_revision(){ + uint32 __attribute__((aligned(16))) mailbox[7]; + mailbox[0] = 7 * 4; // buffer size in bytes + mailbox[1] = REQUEST_CODE; + // tags begin + mailbox[2] = GET_BOARD_REVISION; // tag identifier + mailbox[3] = 4; // maximum of request and response value buffer's length. + mailbox[4] = TAG_REQUEST_CODE; + mailbox[5] = 0; // value buffer + // tags end + mailbox[6] = END_TAG; + + mailbox_call(mailbox,8); // message passing procedure call, you should implement it following the 6 steps provided above. + char s[11]; + i16toa(mailbox[5],s,8); + uart_printf("Board Revision: 0x"); // it should be 0xa020d3 for rpi3 b+ + uart_printf(s); + uart_printf("\n"); +} + +void get_arm_memory() { + unsigned int __attribute__((aligned(16))) mailbox[8]; + mailbox[0] = 8 * 4; // buffer size in bytes + mailbox[1] = MAILBOX_CODE_BUF_REQ; + // tags begin + mailbox[2] = GET_ARM_MEMORY; // tag identifier + mailbox[3] = 8; // maximum of request and response value buffer's length. + mailbox[4] = MAILBOX_CODE_TAG_REQ; // tag code + mailbox[5] = 0; // base address + mailbox[6] = 0; // size in bytes + mailbox[7] = 0x0; // end tag + // tags end + mailbox_call(mailbox, 8); + uart_printf("ARM memory base addr: 0x"); + char a[11]; + i16toa(mailbox[5],a,8); + uart_printf(a); + uart_printf(" size: 0x"); + char b[11]; + i16toa(mailbox[6],b,8); + uart_printf(b); + uart_printf("\n"); +} diff --git a/lab7/bootloader/src/main.c b/lab7/bootloader/src/main.c new file mode 100644 index 000000000..aea11d56e --- /dev/null +++ b/lab7/bootloader/src/main.c @@ -0,0 +1,18 @@ +#include "mini_uart.h" +#include "shell.h" +#include "mailbox.h" +#include "loadimg.h" +#define max_length 128 + + +int main() { + shell_init(); + uart_printf("Initial completed\n"); + get_board_revision(); + get_arm_memory(); + while (1) { + char input[max_length]; + uart_read_line(input); + check(input); + } +} diff --git a/lab7/bootloader/src/mini_uart.c b/lab7/bootloader/src/mini_uart.c new file mode 100644 index 000000000..17f755b4b --- /dev/null +++ b/lab7/bootloader/src/mini_uart.c @@ -0,0 +1,125 @@ +#include "aux.h" +#include "gpio.h" + +void uart_init() { + /* Initialize UART */ + *AUX_ENABLES |= 1; // Enable mini UART + *AUX_MU_CNTL = 0; // Disable TX, RX during configuration + *AUX_MU_IER = 0; // Disable interrupt + *AUX_MU_LCR = 3; // Set the data size to 8 bit + *AUX_MU_MCR = 0; // Don't need auto flow control + *AUX_MU_BAUD = 270; // Set baud rate to 115200 + *AUX_MU_IIR = 6; // No FIFO + + /* Map UART to GPIO Pins */ + + // 1. Change GPIO 14, 15 to alternate function + register unsigned int r = *GPFSEL1; //gpio10~19 is located GPSEL1 + r &= ~((7 << 12) | (7 << 15)); // Reset GPIO 14, 15 + r |= (2 << 12) | (2 << 15); // Set ALT5 + *GPFSEL1 = r; + + // 2. Disable GPIO pull up/down (Because these GPIO pins use alternate functions, not basic input-output) + // Set control signal to disable + *GPPUD = 0; + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Clock the control signal into the GPIO pads + *GPPUDCLK0 = (1 << 14) | (1 << 15); + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Remove the clock + *GPPUDCLK0 = 0; + + // 3. Enable TX, RX + *AUX_MU_CNTL = 3; +} + +char uart_read() { + // Check data ready field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + // Read + char r = (char)(*AUX_MU_IO); + // Convert carrige return to newline + return r == '\r' ? '\n' : r; +} + +char uart_read_raw() { + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + return (char)(*AUX_MU_IO); +} + +void uart_write(unsigned int c) { + // Check transmitter idle field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x20)); + // Write + *AUX_MU_IO = c; +} + +void uart_printf(char* fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + + while (*fmt) { + if (*fmt == '\n') uart_write('\r'); + else if(*fmt == '%'){ + fmt++; + if(*fmt == 'd'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + itoa(arg,temp); + uart_printf(temp); + }else if(*fmt == 's'){ + char *arg = __builtin_va_arg(args, char*); + uart_printf(arg); + }else if(*fmt == 'x'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + i16toa(arg,temp,8); + uart_printf(temp); + }else if(*fmt == 'c'){ + char *arg = __builtin_va_arg(args, char*); + uart_write(*arg); + } + else if(*fmt++ == 'l'){ + if(*fmt == 'e'){ + unsigned int arg = __builtin_va_arg(args, unsigned int); + unsigned char *t = (unsigned char *) &arg; + for(int i=0;i<4;i++){ + unsigned char temp[3]; + temp[2]='\0'; + i16toa(t[i],temp,2); + uart_printf(temp); + } + }else if(*fmt == 'l'){ + unsigned long long arg = __builtin_va_arg(args, unsigned long long); + unsigned char temp[24]; + itoa(arg, temp); + uart_printf("%s",temp); + } + } + fmt++; + continue; + } + else if(*fmt == '\0') break; + uart_write(*fmt++); + } +} + +void uart_flush() { + while (*AUX_MU_LSR & 0x01) { + *AUX_MU_IO; + } +} \ No newline at end of file diff --git a/lab7/bootloader/src/reboot.c b/lab7/bootloader/src/reboot.c new file mode 100644 index 000000000..a6de4e65a --- /dev/null +++ b/lab7/bootloader/src/reboot.c @@ -0,0 +1,13 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC ((volatile unsigned int*)0x3F10001c) +#define PM_WDOG ((volatile unsigned int*)0x3F100024) + +void reset(int tick){ // reboot after watchdog timer expire + *PM_RSTC = PM_PASSWORD | 0x20; // full reset + *PM_WDOG = PM_PASSWORD | tick; // number of watchdog tick +} + +void cancel_reset() { + *PM_RSTC = PM_PASSWORD | 0; // full reset + *PM_WDOG = PM_PASSWORD | 0; // number of watchdog tick +} \ No newline at end of file diff --git a/lab7/bootloader/src/relocate.c b/lab7/bootloader/src/relocate.c new file mode 100644 index 000000000..ef5e9d6c4 --- /dev/null +++ b/lab7/bootloader/src/relocate.c @@ -0,0 +1,12 @@ +extern unsigned char _begin_, _end_, __relocation; +__attribute__((section(".text.relocator")))void relocate(void){ + unsigned long long length = ( &_end_ - &_begin_); + unsigned char* addr_after = (unsigned char*) &__relocation; + unsigned char* addr_before = (unsigned char*) &_begin_; + for(unsigned int i=0; i0){ + i--; + char t[1]={8}; + fmt[i]='\0'; + uart_printf("%s %s",t,t); + } + continue; + }else if(in == 3){ + for(int j=0;j=32 && in<=126 ){ + fmt[i++]=in; + uart_write(in); + } + } + fmt[i]='\0'; +} + +void check(char *input){ + if(input[0] == '\0' || input[0] == '\n') return; + if(strcmp(input,"help")==1){ + uart_printf("help : print the help menu\n"); + uart_printf("hello : print Hello World!\n"); + uart_printf("reboot : reboot the device\n"); + }else if(strcmp(input,"hello")==1){ + uart_printf("Hello World!\n"); + }else if(strncmp(input,"reboot ",7)==1){ + uart_printf("Rebooting...\n"); + int a=0; + for(int i=7;input[i]<='9' && input[i]>='0';i++){ + a *= 10; + a += (input[i]-'0'); + } + reset(a<50? 50:a); + while(1); + }else if(strcmp(input,"loadimg")){ + uart_printf("loading...\n"); + loadimg(); + }else{ + uart_printf("command not found: %s\n",input); + } +} \ No newline at end of file diff --git a/lab7/bootloader/src/start.S b/lab7/bootloader/src/start.S new file mode 100644 index 000000000..099e3f29d --- /dev/null +++ b/lab7/bootloader/src/start.S @@ -0,0 +1,46 @@ +.section ".text.relocate" + +.global _relocate + +_relocate: + // get cpu id + mrs x1, MPIDR_EL1 + and x1, x1, #3 + cbz x1, 2f + // if cpu_id > 0, stop +1: + wfe + b 1b + // if cpu_id == 0 +2: + // save dtb location + ldr x1, =__dtb_addr + str x0, [x1] + + // set stack pointer + ldr x1, =__relocation + mov sp, x1 + + + // clear bss + ldr x1, =__bss_start + ldr x2, =__bss_size +3: cbz x2, 4f + str xzr, [x1], #8 + sub x2, x2, #1 + cbnz x2, 3b + +4: bl relocate + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl main + // halt this core if return +1: + wfe + b 1b \ No newline at end of file diff --git a/lab7/bootloader/src/string.c b/lab7/bootloader/src/string.c new file mode 100644 index 000000000..4d6e92609 --- /dev/null +++ b/lab7/bootloader/src/string.c @@ -0,0 +1,85 @@ +#include "uint.h" +void itoa(unsigned long long value,char *s) { + int idx = 0; + char tmp[24]; + int tidx = 0; + do { + tmp[tidx++] = '0' + value % 10; + value /= 10; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for (i = tidx - 1; i >= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +void i16toa(unsigned int value, char *s, int digits) { + int idx = 0; + char tmp[11]; + int tidx = 0; + do { + if((value % 16) < 10) + tmp[tidx++] = '0' + value % 16; + else + tmp[tidx++] = 'A' + value % 16 - 10; + value /= 16; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for(int j=0;j= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +int strcmp(char *string1, char *string2){ + while(*string1 && *string2){ + if(*string1!=*string2) return 0; + else{ + string1++; + string2++; + } + } + if(*string1){ + if((*string1>='a' && *string1<='z') || (*string1>='A' && *string1<='Z') || (*string1>='0' && *string1<='9')) + return 0; + else + return 1; + } + if(*string2){ + if((*string2>='a' && *string2<='z') || (*string2>='A' || *string2<='Z') || (*string2>=0 && *string2<=9)) + return 0; + else + return 1; + } + return 1; +} + +int strncmp(char *string1, char *string2, int length){ + char temp1[128],temp2[128]; + for(int i=0;i +#include +#include +#include +#include + +using namespace std; +// Linux headers +#include +#include // Contains file controls like O_RDWR +#include // Error integer and strerror() function +#include // Contains POSIX terminal control definitions +#include // write(), read(), close() + +#define block_size 128 + +void port_setting(int serial_port, struct termios tty){ + + //general setting + tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity + tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication + tty.c_cflag &= ~CSIZE; // Clear all the size bits, then use one of the statements below + tty.c_cflag |= CS8; // 8 bits per byte + tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) + tty.c_lflag &= ~ICANON; //Disable canonial mode. Canonial mode is sending message line by line. + tty.c_lflag &= ~ECHO; // Disable echo + tty.c_lflag &= ~ECHOE; // Disable erasure + tty.c_lflag &= ~ECHONL; // Disable new-line echo + tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP + + //setting input + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes + + //setting output + tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) + tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed + tty.c_cc[VTIME] = 10; // Wait for up to 1s (10 deciseconds), returning as soon as any data is received. + tty.c_cc[VMIN] = 0; + + cfsetspeed(&tty, B115200); //Set baud rate + + if (tcsetattr(serial_port, TCSANOW, &tty) != 0) { + printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); + exit(errno); + } +} + +int main(int argc, char* argv[]){ + if(argc!=3){ + cout<<"Error! Need the port number and file name!"< buffer(std::istreambuf_iterator(file), {}); + uint32_t size=buffer.size(); + unsigned char par_bit=0; + unsigned char SIZE[5]; + //unsigned char command[]={'l','o','a','d','i','m','g','\n'}; + //write(serial_port,command,sizeof(command)); + + for(int i=0;i<4;i++){ + SIZE[3-i] = size%256; + size/=256; + par_bit ^= SIZE[3-i]; + } + SIZE[4]=par_bit; + size=buffer.size(); + write(serial_port, SIZE, sizeof(SIZE)); + + uint32_t now=0; + char check_byte=0; + for(int i=0;i= f1->start && addr <= f1->end){ + break; + } + f1 = f1->next; + } + if(f1 == NULL) return addr; + } +} + +void* getbestfit(int ind){ + int i; + for(i=0;i+ind<=log2(frame_num);i++) + if(frame_list[(int)log2(frame_num)-ind-i] != NULL) + break; + while(i != 0){ + struct FrameArray* tmp=frame_list[(int)log2(frame_num)-ind-i]; + frame_list[(int)log2(frame_num)-ind-i] = (frame_list[(int)log2(frame_num)-ind-i])->next; + unsigned int n= exp2(tmp->val-1); + struct FrameArray* tmp2=&frame_array[tmp->index + n]; + tmp->next = tmp2; + tmp->val -= 1; + tmp2->next = NULL; + tmp2->val = tmp->val; + i--; + frame_list[(int)log2(frame_num)-ind-i] = tmp; + } + + struct FrameArray* tmp = frame_list[(int)log2(frame_num)-ind]; + frame_list[(int)log2(frame_num)-ind] = (frame_list[(int)log2(frame_num)-ind])->next; + tmp->allocatable = 0; + tmp->next = NULL; + return (void*)(base_addr + page_size*tmp->index); +} + +void show_status(){ + int i=0; + uart_printf("0x%x: ",base_addr); + while(i < frame_num){ + if(i != 0) uart_write('|'); + int length = exp2(frame_array[i].val); + char a = frame_array[i].allocatable + '0'; + for(int j=0;j length){ + front = index; + back = index + (int)exp2(length); + }else{ + front = index - (int)exp2(length); + back = index; + } + } + if(frame_array[front].val == frame_array[back].val && frame_array[front].allocatable && frame_array[back].allocatable){ + struct FrameArray *tmp = frame_list[(int)log2(frame_num) - length]; + if(tmp->index == index + (int)exp2(length)){ + frame_list[(int)log2(frame_num) - length] = frame_list[(int)log2(frame_num) - length]->next; + } + else { + int the_removed = index == front? back:front; + while(tmp->next != NULL){ + if(tmp->next->index == the_removed){ + tmp->next = tmp->next->next; + break; + } + } + } + frame_array[front].val += 1; + frame_array[back].val = -1; + merge(front); + }else{ + struct FrameArray *tmp = frame_list[(int)log2(frame_num) - length]; + if(tmp == NULL || tmp->index > index) + frame_list[(int)log2(frame_num) - length] = &(frame_array[index]); + else{ + while(tmp != NULL && tmp->next != NULL){ + if(tmp->next->index > index){ + frame_array[index].next = tmp->next; + tmp->next = &(frame_array[index]); + break; + } + } + if(tmp->next == NULL){ + tmp->next = &(frame_array[index]); + frame_array[index].next =NULL; + } + } + } +} + +void insert_pool(struct mem_frag* f){ + struct mem_frag* tmp = pool; + if(tmp == NULL){ + pool = f; + return; + } + while(tmp->next != NULL) tmp = tmp->next; + tmp->next = f; +} + + +void* malloc(size_t size){ + struct mem_frag* tmp = pool; + if(size != exp2(log2(size))) size = exp2(log2(size) + 1); + while(tmp != NULL){ + if(tmp->size == size && tmp->leave > 0){ + for(int i=0;inum;i++){ + if(tmp->status[i] == 1){ + tmp->status[i] = 0; + void* addr = tmp->start + tmp->size*i; + tmp->leave--; + record_mem(addr); + return addr; + } + } + + } + tmp = tmp->next; + } + int req_page_num; + req_page_num = size%page_size != 0? size/page_size+1 : size/page_size; + req_page_num = exp2(log2(req_page_num)) != req_page_num? exp2(log2(req_page_num) + 1) : req_page_num; + + tmp = simple_malloc(sizeof(struct mem_frag)); + tmp->size = size; + tmp->start = page_alloc(req_page_num); + tmp->num = req_page_num * 4096 / size; + tmp->end = tmp->start + req_page_num * 4096; + tmp->status = simple_malloc(tmp->num); + tmp->leave = tmp->num - 1; + tmp->next = NULL; + insert_pool(tmp); + for(int i=0;inum;i++){ + tmp->status[i] = 1; + } + tmp->status[0] = 0; + void* addr = tmp->start; + record_mem(addr); + uint64_t res = (uint64_t)addr | 0xffff000000000000; + return res; +} + +void pool_status(){ + struct mem_frag* f = pool; + uart_printf("Available pool:\n"); + for(int i=1;f!=NULL;i++){ + uart_printf(" %d: addr: 0x%x size: %d num: %d leave: %d\n",i,f->start,f->size,f->num,f->leave); + f = f->next; + } + struct mem_reserved_pool* f1 = MR_pool; + uart_printf("Reserved pool:\n"); + for(int i=1;f1!=NULL;i++){ + uart_printf(" %d: addr: 0x%x to 0x%x\n",i,f1->start,f1->end); + f1 = f1->next; + } +} + +void free(void* addr){ + struct mem_frag* tmp = pool; + while(tmp != NULL){ + if((uint64)addr < (uint64)tmp->end && (uint64)tmp->start <= (uint64)addr){ + if(tmp->status[(addr-tmp->start)/tmp->size] == 0){ + tmp->leave++; + tmp->status[(addr-tmp->start)/tmp->size] = 1; + } + return; + } + tmp = tmp->next; + } +} + +void clear_pool(){ + while(pool!=NULL){ + page_free(pool->start); + pool = pool->next; + } +} + +void memory_reserve(uint64 start,uint64 end){ + if(end < start) return; + struct mem_reserved_pool *tmp; + tmp = MR_pool; + if(tmp != NULL){ + if(start >= tmp->start && start <= tmp->end){ + if(end > tmp->end){tmp->end = end; + MR_pool = MR_pool->next; + return memory_reserve(tmp->start,tmp->end); + } + return; + }else if(end >= tmp->start && end <= tmp->end){ + tmp->start = start; + MR_pool = MR_pool->next; + return memory_reserve(tmp->start,tmp->end); + } + } + while(tmp != NULL && tmp->next != NULL){ + if(start >= tmp->next->start && start <= tmp->next->end){ + if(end > tmp->next->end){ + tmp->next->end = end; + struct mem_reserved_pool *tmp2 = tmp->next; + tmp->next = tmp2->next; + return memory_reserve(tmp2->start,tmp2->end); + } + return; + }else if(end >= tmp->next->start && end <= tmp->next->end){ + tmp->next->start = start; + struct mem_reserved_pool *tmp2 = tmp->next; + tmp->next = tmp2->next; + return memory_reserve(tmp2->start,tmp2->end); + } + tmp = tmp->next; + } + tmp = simple_malloc(sizeof(struct mem_reserved_pool)); + tmp->start = start; + tmp->end = end; + tmp->next = MR_pool; + MR_pool = tmp; +} \ No newline at end of file diff --git a/lab7/src/buffer.c b/lab7/src/buffer.c new file mode 100644 index 000000000..f07679dce --- /dev/null +++ b/lab7/src/buffer.c @@ -0,0 +1,19 @@ +#include "allocator.h" +#include "buffer.h" + + +int write_buffer(struct buffer *b, unsigned char c){ + if(b->start-1 == b->end || (b->start == buffer_size-1 && b->end == 0)) return 0; + b->buf[b->end++] = c; + if(b->end == buffer_size) b->end=0; + return 1; +} + +int read_buffer(struct buffer *b, unsigned char* output){ + if(b->start == b->end) return 0; + *output = b->buf[b->start]; + b->buf[b->start++] = 0; + if(b->start == buffer_size) b->start=0; + return 1; +} + diff --git a/lab7/src/core_timer.c b/lab7/src/core_timer.c new file mode 100644 index 000000000..315cbb815 --- /dev/null +++ b/lab7/src/core_timer.c @@ -0,0 +1,80 @@ +#include "mini_uart.h" +#include "uint.h" +#include "priority_queue.h" +#include "queue.h" +#include "scheduler.h" +#include "task.h" + +uint64 freq_thread = 31; + +void core_timer_init(){ + uint64 tmp; + asm volatile("mrs %0, cntkctl_el1" : "=r"(tmp)); + tmp |= 1; + asm volatile("msr cntkctl_el1, %0" : : "r"(tmp)); + core_timer_disable(); +} + +void arm_core_timer_intr_handler() { + core_timer_handler(); +} + +void core_timer_handler(){ + struct node* node = delete_first_node(); + if(node->next == NULL){ + asm volatile("mrs x0, cntfrq_el0\n" + "ldr x1, =10\n" + "mul x0, x0, x1\n" + "msr cntp_tval_el0, x0\n"); + core_timer_disable(); + }else{ + core_timer_enable(); + uint64 interval = node->next->time_to_ring; + asm volatile("msr cntp_tval_el0, %[output0]\n" + ::[output0] "r" (interval)); + } + free(node); + node->todo(node->arguments); +} + +void add_timer(void (*callback_f)(void*),void *argu_for_call,int times){ + uint64 clock_hz,now_time,interval; + asm volatile("mrs %[input0], cntfrq_el0\n" + "mrs %[input2], cntp_tval_el0\n" + :[input0] "=r" (clock_hz), + [input2] "=r" (interval)); + uint64 time_to_ring = add_node(callback_f, argu_for_call, clock_hz / 1000 * times, interval); + core_timer_enable(); + asm volatile("msr cntp_tval_el0, %[output0]\n" + ::[output0] "r" (time_to_ring)); +} + +void *wakeup(void *p){ + uart_printf("Timeout!!\n"); +} + +void sleep(int duration){ + add_timer(wakeup,NULL,duration); + uart_printf("Timer is set...\n"); +} + +void delay(int duration){ + irq_disable(); + void *argu = get_current(); + add_timer(wakeup_queue,argu,duration); + irq_enable(); + schedule(); +} + +void thread_timer_handler(){ + void *t = get_current(); + struct thread *s = t; + PushToReadyList(s->tid); + thread_timer(); + task_schedule(t); +} + +void thread_timer(){ + while(delete_first_node() != NULL); + add_timer(thread_timer_handler,NULL,freq_thread); +} diff --git a/lab7/src/cpio.c b/lab7/src/cpio.c new file mode 100644 index 000000000..17d93b7fd --- /dev/null +++ b/lab7/src/cpio.c @@ -0,0 +1,332 @@ +#include "uint.h" +#include "mini_uart.h" +#include "string.h" +#include "excep.h" +#include "thread.h" +#include "queue.h" +#include "scheduler.h" +#include "task.h" +#include "mmu.h" +#include "vfs.h" +#include "cpio.h" +#include "list.h" +extern uint64_t cpio_start; +struct file_operations *cpio_fops; +struct vnode_operations *cpio_vops; +struct vnode* cpio_root = NULL; + +typedef struct cpio_newc_header { //cpio new ascii struct + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}CPIO_H ; + +struct vnode* cpio_create_node(const char *name,const char mode, size_t size,const char *internal){ + struct vnode* new_node = allo_vnode(); + strcpy(name,new_node->dt,32); + new_node->f_ops = cpio_fops; + new_node->v_ops = cpio_vops; + new_node->size = size; + new_node->internal = internal; + + new_node->dt->vnode = new_node; + if(mode == '4'){ + new_node->dt->type = directory; + new_node->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + new_node->dt->childs->next = NULL; + struct dentry *tmpchild = allo_dentry(); + tmpchild->name[0] = '.'; + tmpchild->name[1] = 0; + tmpchild->type = directory; + tmpchild->vnode = new_node; + tmpchild->childs = new_node->dt->childs; + new_node->dt->childs->entry = tmpchild; + }else{ + new_node->dt->type = file; + new_node->dt->vnode = new_node; + } + return new_node; +} + +void traverse_cpio(struct vnode* root){ // proceed ls + uint64_t addr = cpio_start; + CPIO_H *cpio=(CPIO_H*) addr; + while(strncmp(cpio->c_magic,"070701\0",6)==1){ //c_magic is always "070701" + struct vnode* parent = root; + int namesize=a16ntoi(cpio->c_namesize, 8); + char *name=(char*)(cpio+1); + char temp[128]; + memset(temp,0,128); + for(int i=0,j=0;ic_filesize, 8); + + + if(temp[0]!='.'){ + struct vnode* new_node = cpio_create_node(temp,cpio->c_mode[4],filesize,addr+110+namesize); + if(cpio->c_mode[4] == '4'){ + new_node->dt->parent = parent->dt; + struct link_list* parent_list = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_list->next = new_node->dt->childs->next; + new_node->dt->childs->next = parent_list; + struct dentry* parent_dentry = allo_dentry(); + strcpy("..\0",parent_dentry->name,32); + parent_dentry->type = directory; + parent_dentry->vnode = parent; + parent_dentry->parent = parent->dt->parent; + parent_dentry->childs = parent->dt->childs; + parent_list->entry = parent_dentry; + } + struct link_list* ll = parent->dt->childs; + //uart_printf("%s\n%s\n",parent->dt->name,new_node->dt->name); + while(ll->next != NULL) ll = ll->next; + ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + ll->next->entry = new_node->dt; + ll->next->next = NULL; + //uart_printf("13"); + } + int sum=110+namesize+filesize; + if(sum%4 != 0){ + sum/=4; + sum*=4; + sum+=4; + } + addr+=sum; // padding is included in namesize and filesize + + cpio=(CPIO_H*) addr; + } +} + +uint64_t find_file_addr(char *file_name){ + uint64_t addr = cpio_start; + CPIO_H *cpio=(CPIO_H*) addr; + while(strncmp(cpio->c_magic,"070701\0",6)==1){ + int namesize=a16ntoi(cpio->c_namesize, 8); + char *name=(char*)(cpio+1); + char temp[128]; + for(int i=0;ic_filesize, 8); + if(strcmp(file_name, temp)){ + return addr; + } + int sum=110+namesize+filesize; + if(sum%4 != 0){ + sum/=4; + sum*=4; + sum+=4; + } + addr+=sum; // padding is included in namesize and filesize + cpio=(CPIO_H*) addr; + } + return NULL; +} + +void* getContent(uint64_t addr,int *length){ + CPIO_H *cpio=(CPIO_H*) addr; + int namesize=a16ntoi(cpio->c_namesize, 8); + int filesize=a16ntoi(cpio->c_filesize, 8); + addr += (110+namesize); + *length = filesize; + return addr; +} + +void print_content(char *file){ + uint64_t f_addr=find_file_addr(file); + if(f_addr != NULL){ + int length; + char *content_addr = getContent(f_addr, &length); + while(length--){ + if(*content_addr == '\n') uart_write('\r'); + uart_write(*content_addr++); + } + return; + }else{ + uart_printf("Not found file \"%s\"\n",file); + return; + } +} + +void copy_content(char *file,void **addr, uint64_t *size){ + struct vnode *tmp; + vfs_lookup(file,&tmp); + if(tmp != NULL){ + if(tmp->dt->type == directory){ + *addr = NULL; + return; + } + int length = tmp->size; + uint64_t address = tmp->internal; + if(address%4 != 0){ + address /= 4; + address *= 4; + address += 4; + } + void * start = malloc(length); + move_last_mem(0); + byte *ucode = (uint64)start; + byte *file = address; + for(int i=0;icreate = cpio_perm_denied; + cpio_vops->mkdir = cpio_perm_denied; + cpio_vops->lookup = cpio_lookup; + cpio_vops->mknod = cpio_perm_denied; + cpio_fops->write = cpio_perm_denied; + cpio_fops->close = cpio_close; + cpio_fops->lseek64 = cpio_lseek64; + cpio_fops->open = cpio_open; + cpio_fops->read = cpio_read; + + struct filesystem *fs = malloc(sizeof(struct filesystem)); + delete_last_mem(); + fs->name = malloc(16); + delete_last_mem(); + memset(fs->name,0,16); + strcpy("initramfs\0",fs->name,10); + fs->setup_mount = cpio_mount; + register_filesystem(fs); + vfs_mount("/initramfs\0","initramfs\0"); + struct vnode* tmp; + vfs_lookup("/initramfs\0",&tmp); +} + +int cpio_mount(struct filesystem* fs, struct mount* mount){ + if(cpio_root == NULL){ + cpio_root = allo_vnode(); + cpio_root->mount = NULL; + cpio_root->size = 0x400; + cpio_root->f_ops = cpio_fops;; + cpio_root->v_ops = cpio_vops; + cpio_root->internal = NULL; + + struct dentry *tmp_child = allo_dentry(); + struct dentry *tmp_parent = mount->root->dt->childs->next->entry; + + strcpy(mount->root->dt->name[0],cpio_root->dt->name,256); + cpio_root->dt->type = directory; + cpio_root->dt->vnode = cpio_root; + cpio_root->dt->parent = cpio_root->dt; + cpio_root->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + cpio_root->dt->childs->entry = tmp_child; + cpio_root->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + cpio_root->dt->childs->next->entry = tmp_parent; + cpio_root->dt->childs->next->next= NULL; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->parent = cpio_root->dt; + tmp_child->childs = cpio_root->dt->childs; + tmp_child->type = directory; + tmp_child->vnode = cpio_root; + + } + mount->root = cpio_root; + traverse_cpio(cpio_root); + struct link_list* ll = cpio_root->dt->childs; +} + +int cpio_perm_denied(){ + uart_printf("Error: Read only file\n"); + return -1; +} + +int cpio_lookup(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct link_list* tmp = dir_node->dt->childs; + while(tmp != NULL){ + struct dentry* den_tmp = tmp->entry; + if(strcmp(den_tmp->name,component_name)){ + *target = den_tmp->vnode; + return 0; + } + tmp = tmp->next; + } + *target = NULL; + return -1; +} + +int cpio_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +int cpio_read(struct file* file, void* buf, size_t len){ + uint64_t address = file->vnode->internal; + char *internal, *tmp = buf; + if(address%4 != 0){ + address /= 4; + address *= 4; + address += 4; + } + internal = address; + for(int i=0;if_pos++]; + } + return len; +} + +int cpio_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = cpio_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +long cpio_lseek64(struct file* file, long offset, int whence){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} \ No newline at end of file diff --git a/lab7/src/dtb.c b/lab7/src/dtb.c new file mode 100644 index 000000000..4d1b20516 --- /dev/null +++ b/lab7/src/dtb.c @@ -0,0 +1,347 @@ +#include "uint.h" +#include "dtb.h" +#include "fdt.h" +#include "mini_uart.h" +#include "string.h" +#include "allocator.h" + +extern byte __dtb_addr; + +int acceptable_word(char con){ + if(((con >= 'A' && con<='Z') || (con >= 'a' && con <= 'z') || (con >= '0' || con <= '9') || con == '.' || con == '/')) return 1; + else return 0; +} + +void *find_property_value(char* device_name, char* property_name){ + device_tree_node *node; + node = initramfs_callback(device_name); + device_prop *prop = node->property; + uint32 *p = prop->prop_content.prop_name; + while( *p != 0){ + if(strcmp(property_name, prop->prop_content.prop_name)==1){ + return prop->prop_content.prop_value; + } + prop= prop->next; + p=prop->prop_content.prop_name; + } + uart_printf("Error! Device or Property not found.\n"); + return (void*)0; +} + +void print_properties(device_prop* node, int level){ + uint32 *p = (uint32*) (node->prop_content).prop_name; + for(int i=0;iprop_content).prop_name); + if(strcmp(node->prop_content.prop_name,"compatible\0")){ + uart_write(34); + int is_bottom=0; + for(int i=0;ilen;i++){ + if(node->prop_content.prop_value[i]!='\0'){ + if(is_bottom==1){ + uart_printf(",\""); + is_bottom=0; + } + uart_write(node->prop_content.prop_value[i]); + }else{ + uart_printf("\""); + is_bottom=1; + } + } + uart_printf("\n"); + }else if(strcmp(node->prop_content.prop_name,"model\0") || + strcmp(node->prop_content.prop_name,"status\0") || + strcmp(node->prop_content.prop_name,"name\0") || + strcmp(node->prop_content.prop_name,"device_type\0")){ + uart_printf("\"%s\"\n",node->prop_content.prop_value); + }else if(strcmp(node->prop_content.prop_name,"phandle\0") || + strcmp(node->prop_content.prop_name,"#address-cells\0") || + strcmp(node->prop_content.prop_name,"#size-cells\0") || + strcmp(node->prop_content.prop_name,"virtual-reg\0")){ + uint32 *temp = node->prop_content.prop_value; + int value=letobe(*temp); + if(strcmp(node->prop_content.prop_name,"#address-cells\0")) address_cells=value; + else if(strcmp(node->prop_content.prop_name,"#size-cells\0")) size_cells=value; + uart_printf("<%d>\n",value); + }else if(strcmp(node->prop_content.prop_name,"reg\0")){ + uart_printf("<"); + uint32 *temp = node->prop_content.prop_value; + for(int i=0;ilen;){ + if(address_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + i+=4; + }else if(address_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + i+=8; + } + if(i>=node->len) break; + if(size_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + i+=4; + }else if(size_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + i+=8; + } + } + uart_printf(" >\n"); + }else if(strcmp(node->prop_content.prop_name,"ranges\0") || + strcmp(node->prop_content.prop_name,"dma-ranges\0")){ + if(node->len != 0){ + uart_printf("<"); + uint32 *temp = node->prop_content.prop_value; + if(address_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x 0x%x", letobe(*temp2),letobe(*(temp2+1))); + temp+=2; + }else if(address_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x 0x%x %x", letobe(temp2[0]),letobe(temp2[1]),letobe(temp2[3]),letobe(temp2[4])); + temp+=4; + } + + if(size_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + }else if(size_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x%x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + } + uart_printf(" >\n"); + }else uart_printf("\n"); + }else if(strcmp(node->prop_content.prop_name,"interrupts\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<0x%x %d>\n",letobe(temp[0]),letobe(temp[1])); + }else if(strcmp(node->prop_content.prop_name,"interrupt-parent\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"interrupts-extended\0")){ + uint32 *temp=node->prop_content.prop_value; + //uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"interrupt-cells\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"linux,initrd-end\0") || + strcmp(node->prop_content.prop_name,"linux,serial\0") || + strcmp(node->prop_content.prop_name,"linux,initrd-start\0") || + strcmp(node->prop_content.prop_name,"linux,revision\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("0x%x\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"size\0") || + strcmp(node->prop_content.prop_name,"clock-frequency\0") || + strcmp(node->prop_content.prop_name,"timebase-frequency\0")){ + uint32 *temp=node->prop_content.prop_value; + if(size_cells == 1) + uart_printf("<0x%x>\n",letobe(temp[0])); + else if(size_cells == 2) + uart_printf("<0x%x %x>\n",letobe(temp[0]),letobe(temp[1])); + }else{ + if(node->len == 0 ){ + char temp[4]={8,8,' ','\0'}; + uart_printf("%s\n",temp); + } + else{ + char *temp2=node->prop_content.prop_value; + if(acceptable_word(temp2[0]) && acceptable_word(temp2[1])){ + uart_printf("\"%s\"\n",temp2); + }else{ + uart_printf("0x"); + uint32 *temp = node->prop_content.prop_value; + int t=node->len%4==0? node->len/4 : node->len/4+1; + for(int j=0;jnext; + p=(uint32*) (node->prop_content).prop_name; + } +} + + +void traverse_tree(char* start,int level){ //print start's properties and its sub_device's properties + device_tree_node *node; + node = initramfs_callback(start); + sub_device *now = node->sd; + + for(int i=0;idevice_name); + print_properties(node->property,level+1); + uint32 *n = (uint32*) now->name; + while(*n!=0){ + char next[128]; + int j; + for(j=0;j<128;j++){ + next[j] = start[j]; + if(start[j] == '\0') break; + } + if(start[j-1] != '/'){ + next[j++]='/'; + next[j]='\0'; + } + for(int k=0;k<128;k++){ + next[k+j] = now->name[k]; + if(now->name[k] == '\0') break; + } + traverse_tree(next, level+1); + now=now->next; + n=(uint32*) now->name; + + } + return; +} + +device_tree_node* initramfs_callback(char* path){ //looking for device + uint32* addr = (uint32*) &__dtb_addr; + device_tree_node *node = simple_malloc(sizeof(device_tree_node)); + sub_device *temp_node=simple_malloc(sizeof(sub_device)); + device_prop* temp_prop=simple_malloc(sizeof(device_prop)); + node->property = temp_prop; + node->sd=temp_node; + for(int i=0;i<4;i++){ + (temp_node->name)[i]=0; + ((temp_prop->prop_content).prop_name)[i]=0; + } + if(path[0] != '/'){ + uart_printf("Device not fount: %s\n", path); + return node; + }else{ + fdt_header *fh=(fdt_header*)(*addr); + uint32* struct_addr = (uint32*) (*addr + letobe(fh->off_dt_struct)); + uint32* string_addr = (uint32*) (*addr + letobe(fh->off_dt_strings)); + int now=0,level=0; + char name[128]; + while(path[now++] != '\0' && path[now] != '\0'){ + int i=0; + for(i=0;path[now+i]!='\0' && path[now+i]!='/';i++){ + name[i]=path[now+i]; + } + now+=i; + name[i]='\0'; + while(1){ + int struct_block=letobe(*struct_addr++); + if(struct_addr >= string_addr){ + uart_printf("Device not found: %s\n",path); + return node; + } + if(struct_block == 1){ + if(level == 1){ + char device_name[128]; + char *temp = (char*) (struct_addr); + int j; + for(j=0;temp[j]!=0;j++){ + device_name[j]=temp[j]; + } + device_name[j]='\0'; + + if(strcmp(device_name, name)){ + break; + }else{ + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + }else{ + char *temp = (char*) (struct_addr); + int j; + for(j=0;temp[j]!=0;j++); + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + level++; + }else if(struct_block == 2){ + level--; + if(level == 0){ + uart_printf("Device not found: %s\n",path); + return node; + } + }else if(struct_block == 3){ + FDT_PROP *pro = (FDT_PROP*) struct_addr; + uint32 len = letobe(pro->len)%4==0? letobe(pro->len)/4 : letobe(pro->len)/4+1; + struct_addr += ( 2 + len); + }else if(struct_block == 9){ + uart_printf("Device not found: %s\n",path); + return node; + } + } + } + if(now-1<=1) strcpy("/\0", node->device_name, 1); + else strcpy(path,node->device_name,now-1); + level=0; + struct_addr--; + while(1){ + if(struct_addr >= string_addr) return node; + int struct_block=letobe(*struct_addr++); + if(struct_block == 1){ + if(level == 1){ + char device_name[128]; + char *temp = (char*) (struct_addr); + int j=0; + for(j=0;temp[j]!=0;j++){ + device_name[j]=temp[j]; + } + device_name[j]='\0'; + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + strcpy(device_name,temp_node->name,j); + sub_device *node_t=simple_malloc(sizeof(sub_device)); + for(int l=0;l<4;l++){ + node_t->name[l]=0; + } + temp_node->next=node_t; + temp_node=node_t; + + }else{ + char *temp = (char*) (struct_addr); + int j=0; + for(;temp[j]!=0;j++); + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + level++; + }else if(struct_block == 2){ + level--; + if(level == 0){ + return node; + } + }else if(struct_block == 3){ + if(level == 1){ + char* name = (char*)string_addr + letobe(struct_addr[1]); + device_prop *prop = simple_malloc(sizeof(device_prop)); + int l=0; + for(l=0;name[l] != 0; l++){ + (temp_prop->prop_content).prop_name[l]=name[l]; + } + (temp_prop->prop_content).prop_name[l]='\0'; + char *t=&(struct_addr[2]); + for(l=0;lprop_content).prop_value[l]=t[l]; + } + (temp_prop->prop_content).prop_value[l]='\0'; + temp_prop->len=letobe(struct_addr[0]); + for(l=0;l<4;l++) (prop->prop_content).prop_name[l]='\0'; + temp_prop->next=prop; + temp_prop=prop; + } + uint32 len = letobe(struct_addr[0])%4==0? letobe(struct_addr[0])/4 : letobe(struct_addr[0])/4+1; + struct_addr += ( 2 + len); + }else if(struct_block == 9){ + return node; + } + } + + } + +} + diff --git a/lab7/src/excep_handler.S b/lab7/src/excep_handler.S new file mode 100644 index 000000000..7fdb9ba36 --- /dev/null +++ b/lab7/src/excep_handler.S @@ -0,0 +1,151 @@ +// save general registers to stack +.macro save_all + sub sp, sp, #0x110 + stp x0, x1, [sp ,16 * 0] + stp x2, x3, [sp ,16 * 1] + stp x4, x5, [sp ,16 * 2] + stp x6, x7, [sp ,16 * 3] + stp x8, x9, [sp ,16 * 4] + stp x10, x11, [sp ,16 * 5] + stp x12, x13, [sp ,16 * 6] + stp x14, x15, [sp ,16 * 7] + stp x16, x17, [sp ,16 * 8] + stp x18, x19, [sp ,16 * 9] + stp x20, x21, [sp ,16 * 10] + stp x22, x23, [sp ,16 * 11] + stp x24, x25, [sp ,16 * 12] + stp x26, x27, [sp ,16 * 13] + stp x28, x29, [sp ,16 * 14] + str x30, [sp, 16 * 15] + + mrs x0, sp_el0 + str x0, [sp, 16 * 15 + 8] + mrs x0, spsr_el1 + mrs x1, elr_el1 + stp x0, x1, [sp ,16 * 16] +.endm + +// load general registers from stack +.macro load_all + + ldp x0, x1, [sp ,16 * 16] + msr spsr_el1, x0 + msr elr_el1, x1 + + ldr x0, [sp, 16 * 15 + 8] + msr sp_el0, x0 + + ldp x0, x1, [sp ,16 * 0] + ldp x2, x3, [sp ,16 * 1] + ldp x4, x5, [sp ,16 * 2] + ldp x6, x7, [sp ,16 * 3] + ldp x8, x9, [sp ,16 * 4] + ldp x10, x11, [sp ,16 * 5] + ldp x12, x13, [sp ,16 * 6] + ldp x14, x15, [sp ,16 * 7] + ldp x16, x17, [sp ,16 * 8] + ldp x18, x19, [sp ,16 * 9] + ldp x20, x21, [sp ,16 * 10] + ldp x22, x23, [sp ,16 * 11] + ldp x24, x25, [sp ,16 * 12] + ldp x26, x27, [sp ,16 * 13] + ldp x28, x29, [sp ,16 * 14] + ldr x30, [sp, 16 * 15] + + add sp, sp, #0x110 +.endm + +.macro exception_handler type + save_all + mov x0, #\type + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mov x4, sp + bl exception_entry + load_all + eret +.endm + +.align 11 // vector table should be aligned to 0x800 +.global exception_table +exception_table: + b sync_1// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_1 + .align 7 + b fir_1 + .align 7 + b serror_1 + .align 7 + + b sync_2// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_2 + .align 7 + b fir_2 + .align 7 + b serror_2 + .align 7 + + b sync_3// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_3 + .align 7 + b fir_3 + .align 7 + b serror_3 + .align 7 + + b sync_4// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_4 + .align 7 + b fir_4 + .align 7 + b serror_4 + .align 7 + +sync_1: + exception_handler 0 +irq_1: + exception_handler 1 +fir_1: + exception_handler 2 +serror_1: + exception_handler 3 + +sync_2: + exception_handler 4 +irq_2: + exception_handler 5 +fir_2: + exception_handler 6 +serror_2: + exception_handler 7 + +sync_3: + exception_handler 8 +irq_3: + exception_handler 9 +fir_3: + exception_handler 10 +serror_3: + exception_handler 11 + +sync_4: + exception_handler 12 +irq_4: + exception_handler 13 +fir_4: + exception_handler 14 +serror_4: + exception_handler 15 + +.global err_han +err_han: b err_han + +.global return_to_child +return_to_child: + load_all + eret diff --git a/lab7/src/exceptions.c b/lab7/src/exceptions.c new file mode 100644 index 000000000..1bff90ecd --- /dev/null +++ b/lab7/src/exceptions.c @@ -0,0 +1,285 @@ +#include "mini_uart.h" +#include "irq.h" +#include "peripheral/irq.h" +#include "timer.h" +#include "interrupt_queue.h" +#include "reboot.h" +#include "thread.h" +#include "cpio.h" +#include "mailbox.h" +#include "queue.h" +#include "task.h" +#include "mmu.h" +#include "vfs.h" +#include "scheduler.h" + +#define uart_puts uart_printf + + +void exception_entry(unsigned long type, unsigned long esr, unsigned long elr, unsigned long spsr, void* sp_addr) +{ + // print out interruption type + switch(type%4) { + case 0: + { + if(esr>>26 == 0b010101){ + asm volatile("msr DAIFClr, 0xf\n"); + struct trapframe *tf = sp_addr; + switch(tf->x[8]){ + case 0: + tf->x[0] = getpid(); + return; + break; + case 1:{ + char *buf = tf->x[0], temp[256]; + int rn = 0; + while(1){ + temp[0] = 0; + uart_pop(temp); + for(int i=0;i<256;i++){ + if(temp[i] == 0) break; + buf[rn++] = temp[i]; + if(rn >= tf->x[1]){ + tf->x[0] = tf->x[1]; + return; + } + } + } + return; + break; + } + case 2:{ + char *buf = tf->x[0]; + for(int i=0;ix[1];i++){ + uart_write(buf[i]); + } + tf->x[0] = tf->x[1]; + return; + break; + } + case 3: + exec(tf->x[0],tf->x[1]); + return; + break; + case 4: + irq_disable(); + tf->x[0] = set_fork(sp_addr); + irq_enable(); + return; + break; + case 5: + UserExit(); + break; + case 6:{ + uint32_t* mbox = malloc(*(uint32_t*)(tf->x[1])); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + uint32_t tr = *((uint32_t*)(tf->x[1]) + i); + mbox[i] = tr; + } + unsigned char channel = tf->x[0]; + mailbox_call(mbox,channel); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + *((uint32_t*)(tf->x[1]) + i) = mbox[i]; + } + free(mbox); + return; + break; + } + case 7: + UserKill(tf->x[0]); + return; + break; + case 8: + signal(tf->x[0],tf->x[1]); + return; + break; + case 9: + sentSignal(tf->x[0],tf->x[1]); + return; + break; + case 10: + tf->x[0] = mmap_set(tf->x[0],tf->x[1],tf->x[2],tf->x[3]); + return; + break; + case 11:{ //file open + //uart_printf("11\n"); + void* vnode; + int errno; + if((errno = vfs_open(tf->x[0],tf->x[1],&vnode)) < 0){ + uart_printf("File not found: %s\n",tf->x[0]); + tf->x[0] = errno; + return; + } + struct thread *t = get_current(); + for(int i=0;i<65536;i++){ + if(t->fd[i] == NULL){ + t->fd[i] = vnode; + tf->x[0] = i; + return; + } + } + tf->x[0] = -1; + return; + break; + }case 12:{ //file close + //uart_printf("12\n"); + struct thread *t = get_current(); + int fd = tf->x[0]; + tf->x[0] = vfs_close(t->fd[tf->x[0]]); + if(tf->x[0]>=0) t->fd[fd] = NULL; + return; + break; + }case 13:{ //file write + //uart_printf("13\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_write(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + break; + }case 14:{ //file read + //uart_printf("14\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_read(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + break; + }case 15:{ //mkdir + //uart_printf("15\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_mkdir(tf->x[0]); + return; + break; + }case 16:{ //mount + //uart_printf("16\n"); + tf->x[0] = vfs_mount(tf->x[1],tf->x[2]); + return; + break; + }case 17:{ //chdir + //uart_printf("17\n"); + void *vnode; + tf->x[0] = vfs_lookup(tf->x[0], &vnode); + if(tf->x[0] >= 0){ + struct thread *t = get_current(); + t->CurWorkDir = vnode; + } + return; + break; + }case 18:{ //long lseek64(int fd, long offset, int whence); + //uart_printf("18\n"); + struct thread *t = get_current(); + vfs_lseek(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + }case 19:{ //int ioctl(int fd, unsigned long request, ...); + //uart_printf("19\n"); + struct thread *t = get_current(); + struct file* file = t->fd[tf->x[0]]; + if(file == NULL){ + tf->x[0] = -1; + return; + } + tf->x[0] = file->vnode->v_ops->ioctl(file,tf->x[1],tf->x[2]); + return; + }case 20: + ret_to_sig_han(sp_addr + 0x110); + return; + break; + default: + uart_printf("%d ",tf->x[8]); + break; + } + }else if(esr>>26==0b100100 || esr>>26==0b100101){ + uint64_t far; + asm volatile("mrs %[input0],far_el1\n" + : [input0] "=r" (far)); + // For Translation fault + uart_printf("[Translation fault]: 0x%x %x\n", far>>32, far); + if(!mmap_check(far)){ + // For Segmentation fault + struct thread *t = get_current(); + uart_printf("[Segmentation fault]: Kill Process %d\n",t->tid); + asm volatile("msr DAIFClr, 0xf\n"); + UserExit(); + } + return; + } + uart_puts("Synchronous"); + break; + } + case 1: + if(handle_irq()){ + asm volatile("msr DAIFClr, 0xf\n"); + exe_first_task(); + return; + } + uart_puts("IRQ"); + break; + case 2: uart_puts("FIQ"); break; + case 3: uart_puts("SError"); break; + } + uart_puts(": "); + // decode exception type (some, not all. See ARM DDI0487B_b chapter D10.2.28) + switch(esr>>26) { + case 0b000000: uart_puts("Unknown"); break; + case 0b000001: uart_puts("Trapped WFI/WFE"); break; + case 0b001110: uart_puts("Illegal execution"); break; + case 0b010101: uart_puts("System call"); break; + case 0b100000: uart_puts("Instruction abort, lower EL"); break; + case 0b100001: uart_puts("Instruction abort, same EL"); break; + case 0b100010: uart_puts("Instruction alignment fault"); break; + case 0b100100: uart_puts("Data abort, lower EL"); break; + case 0b100101: uart_puts("Data abort, same EL"); break; + case 0b100110: uart_puts("Stack alignment fault"); break; + case 0b101100: uart_puts("Floating point"); break; + default: uart_puts("Unknown"); break; + } + // decode data abort cause + if(esr>>26==0b100100 || esr>>26==0b100101) { + uart_puts(", "); + switch((esr>>2)&0x3) { + case 0: uart_puts("Address size fault"); break; + case 1: uart_puts("Translation fault"); break; + case 2: uart_puts("Access flag fault"); break; + case 3: uart_puts("Permission fault"); break; + } + switch(esr&0x3) { + case 0: uart_puts(" at level 0"); break; + case 1: uart_puts(" at level 1"); break; + case 2: uart_puts(" at level 2"); break; + case 3: uart_puts(" at level 3"); break; + } + } + + int ec = (esr >> 26) & 0b111111; + int iss = esr & 0x1FFFFFF; + int cntfrq_el0,cntpct_el0; + // system call + if (ec == 0b010101) { + switch (iss) { + case 1: + uart_printf("Exception return address 0x%x\n", elr); + uart_printf("Exception class (EC) 0x%x\n", ec); + uart_printf("Instruction specific syndrome (ISS) 0x%x\n", iss); + break; + case 2: + core_timer_enable(); + break; + case 3: + core_timer_disable(); + break; + case 4: + asm volatile ("mrs %0, cntfrq_el0" : "=r" (cntfrq_el0)); // get current counter frequency + asm volatile ("mrs %0, cntpct_el0" : "=r" (cntpct_el0)); // read current counter + break; + } + } + // dump registers + uart_puts(":\n ESR_EL1 "); + uart_printf("0x%x ",esr>>32); + uart_printf("0x%x",esr); + uart_puts("\n ELR_EL1 "); + uart_printf("0x%x ",elr>>32); + uart_printf("0x%x",elr); + uart_puts("\n SPSR_EL1 "); + uart_printf("0x%x ",spsr>>32); + uart_printf("0x%x",spsr); + uart_puts("\n"); + //if (type%4 == 0) reset(50); +} diff --git a/lab7/src/framebuffer.c b/lab7/src/framebuffer.c new file mode 100644 index 000000000..124122f28 --- /dev/null +++ b/lab7/src/framebuffer.c @@ -0,0 +1,94 @@ +#include "framebuffer.h" +#include "string.h" +#include "mini_uart.h" +#include "allocator.h" +#include "mailbox.h" +#include "irq.h" +struct file_operations *fb_fops; +struct vnode_operations *fb_vops; + + +int fb_setup(struct device* device, struct vnode* mount){ + mount->f_ops = fb_fops; + mount->v_ops = fb_vops; +} + +int fb_per_denied(){ + uart_printf("Permission denied\n"); + return -1; +} + +int fb_write(struct file* file, const void* buf, size_t len){ + const unsigned char *color = buf; + for(int i=0;if_pos++); + } + return len; +} + +int fb_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = fb_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int fb_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +int fb_lseek64(struct file* file, long offset, int whence){ + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} + +int fb_ioctl(struct file* file, unsigned long request, uint32_t fb_info[4]){ + if(request == 0){ + set_vc(fb_info); + return 0; + } + return -1; +} + +void vfs_fb_init(){ + struct device *dev = malloc(sizeof(struct device)); + delete_last_mem(); + dev->name = malloc(16); + delete_last_mem(); + memset(dev->name,0,16); + + fb_fops = malloc(sizeof(struct file_operations)); + fb_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + delete_last_mem(); + fb_fops->open = fb_open; + fb_fops->read = fb_per_denied; + fb_fops->write = fb_write; + fb_fops->close = fb_close; + fb_fops->lseek64 = fb_lseek64; + fb_vops->create = fb_per_denied; + fb_vops->lookup = fb_per_denied; + fb_vops->mkdir = fb_per_denied; + fb_vops->mknod = fb_per_denied; + fb_vops->ioctl = fb_ioctl; + + + + strcpy("framebuffer\0",dev->name,12); + dev->setup = fb_setup; + register_device(dev); + vfs_mknod("/dev/framebuffer", "framebuffer"); +} \ No newline at end of file diff --git a/lab7/src/getopt.c b/lab7/src/getopt.c new file mode 100644 index 000000000..d4b792118 --- /dev/null +++ b/lab7/src/getopt.c @@ -0,0 +1,25 @@ +#include "uint.h" +#include "mini_uart.h" + +int optind=1; +char* optarg; + +char *getopt(int argc, char* argv[],char* opt){ + char param[16]; + int ind = 0; + for(int i=0;opt[i] != 0;i++){ + if(opt[i] == ':') param[ind++] = opt[i+1]; + } + for(;optindcallback = callback; + tmp->next = NULL; + if(task_controller == NULL){ + task_controller = tmp; + }else{ + struct interrupt_event *tmp2 = task_controller; + while(tmp2->next != NULL) tmp2 = tmp2->next; + tmp2->next = tmp; + } +} + +int task_empty(){ + return task_controller == NULL; +} + +void exe_first_task(){ + if(task_controller == NULL){ return;} + struct interrupt_event* tmp = task_controller; + task_controller = task_controller->next; + tmp->callback(); + *AUX_MU_IER |= 1; + exe_first_task(); +} \ No newline at end of file diff --git a/lab7/src/irq.S b/lab7/src/irq.S new file mode 100644 index 000000000..afb1244e3 --- /dev/null +++ b/lab7/src/irq.S @@ -0,0 +1,9 @@ +.global irq_enable +irq_enable: + msr daifclr, 0xf + ret + +.global irq_disable +irq_disable: + msr daifset, 0xf + ret \ No newline at end of file diff --git a/lab7/src/irq2.c b/lab7/src/irq2.c new file mode 100644 index 000000000..428973bec --- /dev/null +++ b/lab7/src/irq2.c @@ -0,0 +1,37 @@ +#include "uint.h" +#include "mini_uart.h" +#include "peripheral/irq.h" +#include "aux.h" +#include "timer.h" +#include "gpio.h" +#include "interrupt_queue.h" + +void irq_init_vectors(){ + asm volatile("ldr x0, =exception_table\n" + "msr vbar_el1, x0\n"); + return; +} + +void enable_interrupt_controller() { + uint32 *tmp = irq0_enable_1; + *tmp |= (1 << 29); +} + +int handle_irq() { + uint64 *core_irq=0xFFFF000040000060; + uint32 *irq; + irq = irq0_pending_1; + if (*irq & (1 << 29)) { + *irq &= ~(1 << 29); + *AUX_MU_IER = 0; + push_queue(handle_uart_irq); + return 1; + } + if ((*core_irq) & 2) { + *irq &= ~2; + core_timer_disable(); + push_queue(arm_core_timer_intr_handler); + return 1; + } + return 0; +} diff --git a/lab7/src/jump.S b/lab7/src/jump.S new file mode 100644 index 000000000..7dea7e7cb --- /dev/null +++ b/lab7/src/jump.S @@ -0,0 +1,52 @@ +.global setjump +.global longjump +setjump: + stp x1, x2, [x0 ,16 * 0] + stp x3, x4, [x0 ,16 * 1] + stp x5, x6, [x0 ,16 * 2] + stp x7, x8, [x0 ,16 * 3] + stp x9, x10, [x0 ,16 * 4] + stp x11, x12, [x0 ,16 * 5] + stp x13, x14, [x0 ,16 * 6] + stp x15, x16, [x0 ,16 * 7] + stp x17, x18, [x0 ,16 * 8] + stp x19, x20, [x0 ,16 * 9] + stp x21, x22, [x0 ,16 * 10] + stp x23, x24, [x0 ,16 * 11] + stp x25, x26, [x0 ,16 * 12] + stp x27, x28, [x0 ,16 * 13] + stp x29, x30, [x0 ,16 * 14] + mov x1, lr + mov x2, sp + stp x1, x2, [x0 ,16 * 15] + + ldr x0, =0 + ret + +longjump: + ldp x2, x3, [x0,16 * 15] + mov sp, x3 + mov lr, x2 + + ldp x3, x4, [x0 ,16 * 1] + ldp x5, x6, [x0 ,16 * 2] + ldp x7, x8, [x0 ,16 * 3] + ldp x9, x10, [x0 ,16 * 4] + ldp x11, x12, [x0 ,16 * 5] + ldp x13, x14, [x0 ,16 * 6] + ldp x15, x16, [x0 ,16 * 7] + ldp x17, x18, [x0 ,16 * 8] + ldp x19, x20, [x0 ,16 * 9] + ldp x21, x22, [x0 ,16 * 10] + ldp x23, x24, [x0 ,16 * 11] + ldp x25, x26, [x0 ,16 * 12] + ldp x27, x28, [x0 ,16 * 13] + ldp x29, x30, [x0 ,16 * 14] + + mov x2, x0 + mov x0, x1 + ldp x1, x2, [x2 , 16 * 0] + + ret + + diff --git a/lab7/src/linker.ld b/lab7/src/linker.ld new file mode 100644 index 000000000..950540afa --- /dev/null +++ b/lab7/src/linker.ld @@ -0,0 +1,48 @@ +__heap_size = 0x100000; +SECTIONS +{ + . = 0xffff000000000000; + . += 0x80000; + _begin_ = .; + .text : + { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); + + .data : + { + *(.data) + } + . = ALIGN(4096); + + .bss (NOLOAD) : + { + __bss_start = .; + + *(.bss) + + __bss_end = .; + } + . = ALIGN(4096); + + . = . + 0x100000; + + .heap : + { + __heap_start = .; + + *(.heap*) + + __HeapLimit = . + __heap_size; + + . = . + __heap_size; + + } + . = ALIGN(0x20000); + _end_ = .; + +} +__bss_size = (__bss_end - __bss_start) >> 3; +__dtb_addr = 0xffff000002080000; diff --git a/lab7/src/loadimg.c b/lab7/src/loadimg.c new file mode 100644 index 000000000..ddd26cb32 --- /dev/null +++ b/lab7/src/loadimg.c @@ -0,0 +1,65 @@ +#include "mini_uart.h" +#include "string.h" +#include "allocator.h" + +#define byte unsigned char +#define uint32 unsigned int +#define block_size 128 + + +void loadimg(){ + asm volatile("msr DAIFClr, 0x0\n"); + uint32 addr=malloc(0x100000) + 0x20000; // load to 0x80000 + uart_printf("Start receiving.\n"); + byte SIZE[5]; + byte par=0; + for(int i=0;i<5;i++){ //receive file size + byte temp=uart_read_raw(); + SIZE[i]=temp; + par ^= temp; + uart_printf(" ||%d|| \n",(int)temp); + } + if(par != 0){ + uart_printf("Receiving error\n"); + return; + } + uint32 size=0; + for(int i=0;i<4;i++){ + size <<= 8; + size += SIZE[i]; + } + byte *kernel = (byte*) addr; + byte check_byte=0; + int j=0; + for(int i=0;i=5){ + uart_printf("Error! Please try again later.\n"); + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(2); + return; + } + uart_printf("Something went wrong. Trying to fix it.\n"); + i-=8; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(1); + }else{ + j=0; + check_byte &= 0; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(0); + } + } + } + void (*start_os)(void) = (void *)kernel; //set start_os's addr to the loaded image's addr + uart_printf("Loading Complete.\n"); + uart_printf("Redirecting to 0x%x\n",addr); + asm volatile("msr DAIFClr, 0xf\n"); + start_os(); + free(addr); +} \ No newline at end of file diff --git a/lab7/src/local_timer.c b/lab7/src/local_timer.c new file mode 100644 index 000000000..1aee8f458 --- /dev/null +++ b/lab7/src/local_timer.c @@ -0,0 +1,22 @@ +#include "uint.h" +#include "mini_uart.h" +#include "peripheral/irq.h" +#include "aux.h" +#include "peripheral/timer.h" + +uint32 interval_time = CLOCKHZ * 2; +uint32 cur_val_1 = 0; + +void timer_init(){ + cur_val_1 = *SYSTEM_TIMER_COUNTER_L_32; + cur_val_1 += interval_time; + *SYSTEM_TIMER_COMPARE1 = cur_val_1; +} + +void handle_timer_1(){ + cur_val_1 += interval_time; + *SYSTEM_TIMER_COMPARE1 = cur_val_1; + *SYSTEM_TIMER_CONTROL |= 2; + + uart_printf("Timer 1 recceived!\n"); +} \ No newline at end of file diff --git a/lab7/src/mailbox.c b/lab7/src/mailbox.c new file mode 100644 index 000000000..9ea495acf --- /dev/null +++ b/lab7/src/mailbox.c @@ -0,0 +1,174 @@ +#include "mini_uart.h" +#include "peripheral/mmio.h" +#include "string.h" +typedef unsigned int uint32; +typedef unsigned char byte; + +#define MAILBOX_BASE MMIO_BASE + 0xb880 + +#define MAILBOX_READ (uint32*)(MAILBOX_BASE) +#define MAILBOX_STATUS (uint32*)(MAILBOX_BASE+0x18) +#define MAILBOX_WRITE (uint32*)(MAILBOX_BASE+0x20) + +#define MAILBOX_EMPTY 0x40000000 +#define MAILBOX_FULL 0x80000000 +#define MAILBOX_CODE_BUF_RES_SUCC 0x80000000 +#define MAILBOX_CODE_BUF_REQ 0x00000000 +#define MAILBOX_CODE_TAG_REQ 0x00000000 + +#define GET_ARM_MEMORY 0x00010005 +#define GET_BOARD_REVISION 0x00010002 +#define REQUEST_CODE 0x00000000 +#define REQUEST_SUCCEED 0x80000000 +#define REQUEST_FAILED 0x80000001 +#define TAG_REQUEST_CODE 0x00000000 +#define END_TAG 0x00000000 + +#define MBOX_REQUEST 0 +#define MBOX_CH_PROP 8 +#define MBOX_TAG_LAST 0 + +void mailbox_call(uint32 *mailbox,byte channel){ + uint32 r = (uint32)(((unsigned long)mailbox) & (~0xF)) | (channel & 0xF); + while (*MAILBOX_STATUS & MAILBOX_FULL) { + } + *MAILBOX_WRITE = r; + while(1){ + while(*MAILBOX_STATUS & MAILBOX_EMPTY){ + } + + if (r == *MAILBOX_READ){ + return mailbox[1] == MAILBOX_CODE_BUF_RES_SUCC; + } + } + return 0; +} + +void get_board_revision(){ + uint32 __attribute__((aligned(16))) mailbox[7]; + mailbox[0] = 7 * 4; // buffer size in bytes + mailbox[1] = REQUEST_CODE; + // tags begin + mailbox[2] = GET_BOARD_REVISION; // tag identifier + mailbox[3] = 4; // maximum of request and response value buffer's length. + mailbox[4] = TAG_REQUEST_CODE; + mailbox[5] = 0; // value buffer + // tags end + mailbox[6] = END_TAG; + + mailbox_call(mailbox,8); // message passing procedure call, you should implement it following the 6 steps provided above. + char s[11]; + i16toa(mailbox[5],s,8); + uart_printf("Board Revision: 0x"); // it should be 0xa020d3 for rpi3 b+ + uart_printf(s); + uart_printf("\n"); +} + +void get_arm_memory() { + unsigned int __attribute__((aligned(16))) mailbox[8]; + mailbox[0] = 8 * 4; // buffer size in bytes + mailbox[1] = MAILBOX_CODE_BUF_REQ; + // tags begin + mailbox[2] = GET_ARM_MEMORY; // tag identifier + mailbox[3] = 8; // maximum of request and response value buffer's length. + mailbox[4] = MAILBOX_CODE_TAG_REQ; // tag code + mailbox[5] = 0; // base address + mailbox[6] = 0; // size in bytes + mailbox[7] = 0x0; // end tag + // tags end + mailbox_call(mailbox, 8); + uart_printf("ARM memory base addr: 0x%x size: 0x%x\n",mailbox[5],mailbox[6]); + +} + +unsigned int width, height, pitch, isrgb; /* dimensions and channel order */ +unsigned long long lfb; /* raw frame buffer address */ + +int set_vc(unsigned int fb_info[4]){ + unsigned int __attribute__((aligned(16))) mbox[36]; + + mbox[0] = 35 * 4; + mbox[1] = MBOX_REQUEST; + + mbox[2] = 0x48003; // set phy wh + mbox[3] = 8; + mbox[4] = 8; + mbox[5] = fb_info[0]; // FrameBufferInfo.width + mbox[6] = fb_info[1]; // FrameBufferInfo.height + + mbox[7] = 0x48004; // set virt wh + mbox[8] = 8; + mbox[9] = 8; + mbox[10] = fb_info[0]; // FrameBufferInfo.virtual_width + mbox[11] = fb_info[1]; // FrameBufferInfo.virtual_height + + mbox[12] = 0x48009; // set virt offset + mbox[13] = 8; + mbox[14] = 8; + mbox[15] = 0; // FrameBufferInfo.x_offset + mbox[16] = 0; // FrameBufferInfo.y.offset + + mbox[17] = 0x48005; // set depth + mbox[18] = 4; + mbox[19] = 4; + mbox[20] = 32; // FrameBufferInfo.depth + + mbox[21] = 0x48006; // set pixel order + mbox[22] = 4; + mbox[23] = 4; + mbox[24] = fb_info[3]; // RGB, not BGR preferably + + mbox[25] = 0x40001; // get framebuffer, gets alignment on request + mbox[26] = 8; + mbox[27] = 8; + mbox[28] = fb_info[2]; // FrameBufferInfo.pointer + mbox[29] = 0; // FrameBufferInfo.size + + mbox[30] = 0x40008; // get pitch + mbox[31] = 4; + mbox[32] = 4; + mbox[33] = 0; // FrameBufferInfo.pitch + + mbox[34] = MBOX_TAG_LAST; + + // this might not return exactly what we asked for, could be + // the closest supported resolution instead + mailbox_call(mbox, MBOX_CH_PROP); + if ( mbox[20] == 32 && mbox[28] != 0) { + mbox[28] &= 0x3FFFFFFF; // convert GPU address to ARM address + width = mbox[5]; // get actual physical width + height = mbox[6]; // get actual physical height + pitch = mbox[33]; // get number of bytes per line + isrgb = mbox[24]; // get the actual channel order + lfb = ((unsigned long long)mbox[28] | 0xFFFF000000000000); + } else { + uart_printf("Unable to set screen resolution to %dx%dx32\n",fb_info[0],fb_info[1]); + } +} + +void fb_splash(unsigned char color, unsigned long ptr){ + *((unsigned char *)(lfb + ptr)) = color; +} + +void fb_splash2() { + int x, y; + unsigned char *ptr = lfb; + unsigned int white = 255 << 16 | 255 << 8 | 255; // A B G R + unsigned int black = 0; + unsigned int current, start = black, spacing = 40; + unsigned long long tmp = 0; + + for (y = 0; y < height; y++) { + if (y % spacing == 0 && y != 0) { + start = (start == white) ? black : white; + } + current = start; + for (x = 0; x < width; x++) { + if (x % spacing == 0 && x != 0) { + current = (current == white) ? black : white; + } + fb_splash(current,tmp); + tmp+=4; + } + } +} \ No newline at end of file diff --git a/lab7/src/main.c b/lab7/src/main.c new file mode 100644 index 000000000..39bd4d40e --- /dev/null +++ b/lab7/src/main.c @@ -0,0 +1,45 @@ +#include "mini_uart.h" +#include "shell.h" +#include "mailbox.h" +#include "irq.h" +#include "timer.h" +#include "uint.h" +#include "interrupt_queue.h" +#include "aux.h" +#include "jump.h" +#include "thread.h" + +#define max_length 128 + +struct JumpBuf jb; + +int gettime(){ + int time,freq; + asm volatile("mrs %[input0], cntpct_el0\n" + "mrs %[input1], cntfrq_el0\n" + :[input0] "=r" (time), [input1] "=r" (freq)); + float temp=(float)time/freq; + int start_time= temp*1000; + return start_time; +} + +int main() { + + shell_init(); + uart_printf("Initial completed\n"); + get_board_revision(); + get_arm_memory(); + + irq_init_vectors(); + enable_interrupt_controller(); + irq_enable(); + + //core_timer_enable(); + //timer_init(); //local timer + setjump(&jb); + clear_threads(); + set_first_thread(); + schedule(); + while (1){ + } +} diff --git a/lab7/src/math.c b/lab7/src/math.c new file mode 100644 index 000000000..a018bef5d --- /dev/null +++ b/lab7/src/math.c @@ -0,0 +1,32 @@ +int log(int base, int logarithm){ + int tmp = 1; + int exp = 0; + while(tmp <= logarithm){ + tmp *= base; + exp ++; + } + return exp-1; +} + +int exp(int base, int exponent){ + int tmp = 1; + for(int i=0;i=b ? b:a; +} \ No newline at end of file diff --git a/lab7/src/mini_uart.c b/lab7/src/mini_uart.c new file mode 100644 index 000000000..b84929d33 --- /dev/null +++ b/lab7/src/mini_uart.c @@ -0,0 +1,287 @@ +#include "aux.h" +#include "gpio.h" +#include "buffer.h" +#include "allocator.h" +#include "jump.h" +#include "signal.h" +#include "thread.h" +#include "vfs.h" +#include "string.h" + +int transmit_interrupt_open = 0; +char uart_buffer[1024]; +unsigned int wr_buffer_index = 0; +unsigned int rd_buffer_index = 0; +struct buffer wbuffer,rbuffer; +extern struct jumpBuf jb; + + +void uart_init() { + + /* Initialize UART */ + *AUX_IRQ |= 1; // Enable mini UART interrupt pending + *AUX_ENABLES |= 1; // Enable mini UART + *AUX_MU_CNTL = 0; // Disable TX, RX during configuration + *AUX_MU_IER = 1; // enable interrupt + *AUX_MU_LCR = 3; // Set the data size to 8 bit + *AUX_MU_MCR = 0; // Don't need auto flow control + *AUX_MU_BAUD = 270; // Set baud rate to 115200 + *AUX_MU_IIR = 6; // No FIFO + + /* Map UART to GPIO Pins */ + + // 1. Change GPIO 14, 15 to alternate function + register unsigned int r = *GPFSEL1; //gpio10~19 is located GPSEL1 + r &= ~((7 << 12) | (7 << 15)); // Reset GPIO 14, 15 + r |= (2 << 12) | (2 << 15); // Set ALT5 + *GPFSEL1 = r; + + // 2. Disable GPIO pull up/down (Because these GPIO pins use alternate functions, not basic input-output) + // Set control signal to disable + *GPPUD = 0; + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Clock the control signal into the GPIO pads + *GPPUDCLK0 = (1 << 14) | (1 << 15); + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Remove the clock + *GPPUDCLK0 = 0; + + // 3. Enable TX, RX + *AUX_MU_CNTL = 3; + + transmit_interrupt_open = 0; +} + +void uart_init_buffer(){ + wbuffer.start = 0; + wbuffer.end = 0; + rbuffer.start = 0; + rbuffer.end = 0; +} + +char uart_read() { + // Check data ready field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + // Read + char r = (char)(*AUX_MU_IO); + // Convert carrige return to newline + return r == '\r' ? '\n' : r; +} + +char uart_read_raw() { + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + return (char)(*AUX_MU_IO); +} + +void uart_write(unsigned int c) { + // Check transmitter idle field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x20)); + // Write + *AUX_MU_IO = c; +} + +void uart_printf(char* fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + + while (*fmt) { + if (*fmt == '\n') uart_write('\r'); + else if(*fmt == '%'){ + fmt++; + if(*fmt == 'd'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + itoa(arg,temp); + uart_printf(temp); + }else if(*fmt == 's'){ + char *arg = __builtin_va_arg(args, char*); + uart_printf(arg); + }else if(*fmt == 'x'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + i16toa(arg,temp,8); + uart_printf(temp); + }else if(*fmt == 'c'){ + unsigned char arg = __builtin_va_arg(args,int); + uart_write(arg); + }else if(*fmt == '.'){ + int l = *(++fmt)-'0'; + if(*(++fmt) == 'f'){ + float *arg = __builtin_va_arg(args, float*); + char temp[20]; + ftoa(arg,l,temp); + uart_printf(temp); + } + } + else if(*fmt++ == 'l'){ + if(*fmt == 'e'){ + unsigned int arg = __builtin_va_arg(args, unsigned int); + unsigned char *t = (unsigned char *) &arg; + for(int i=0;i<4;i++){ + unsigned char temp[3]; + temp[2]='\0'; + i16toa(t[i],temp,2); + uart_printf(temp); + } + }else if(*fmt == 'l'){ + unsigned long long arg = __builtin_va_arg(args, unsigned long long); + unsigned char temp[24]; + itoa(arg, temp); + uart_printf("%s",temp); + } + } + fmt++; + continue; + } + else if(!(*fmt >=32 && *fmt <= 127)) break; + uart_write(*fmt++); + } +} + +void uart_flush() { + while (*AUX_MU_LSR & 0x01) { + *AUX_MU_IO; + } +} + +int uart_push(char c){ + return write_buffer(&wbuffer,c); +} + +int uart_pop(unsigned char *c){ + return read_buffer(&rbuffer,c); +} + +void *handle_uart_irq() +{ + unsigned int id = *AUX_MU_IIR; + if((id & 0x06) == 0x04) //receive interrupt + { + if( *AUX_MU_LSR & 0x01) { + char c; + c = *AUX_MU_IO & 0xFF; + if(c == 3){ + uart_printf("^C\n"); + reset_flag(); + + longjump(&jb,1); + }else{ + write_buffer(&rbuffer,c); + } + } + } + if((id & 0x06) == 0x02) //transmit interrupt + { + while(*AUX_MU_LSR & 0x20) { + unsigned char c; + if(read_buffer(&wbuffer,&c) == 0) { + // close transmit interrupt + *AUX_MU_IER = 1; + transmit_interrupt_open = 0; + return; + } + *AUX_MU_IO = c; + } + } + *AUX_MU_IER = 1; + return; +} + +struct file_operations *uart_fops; +struct vnode_operations *uart_vops; + + +int uart_setup(struct device* device, struct vnode* mount){ + mount->f_ops = uart_fops; + mount->v_ops = uart_vops; +} + +int device_per_denied(){ + uart_printf("Permission denied\n"); + return -1; +} + +int uart_vfs_write(struct file* file, const void* buf, size_t len){ + char *tmp = buf; + //for(int i=0;i= len){ + return len; + } + } + } +} + +int uart_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = uart_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int uart_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +void vfs_uart_init(){ + struct device *dev = malloc(sizeof(struct device)); + delete_last_mem(); + dev->name = malloc(16); + delete_last_mem(); + memset(dev->name,0,16); + + uart_fops = malloc(sizeof(struct file_operations)); + uart_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + delete_last_mem(); + uart_fops->open = uart_open; + uart_fops->read = uart_vfs_read; + uart_fops->write = uart_vfs_write; + uart_fops->close = uart_close; + uart_fops->lseek64 = device_per_denied; + uart_vops->create = device_per_denied; + uart_vops->lookup = device_per_denied; + uart_vops->mkdir = device_per_denied; + uart_vops->mknod = device_per_denied; + + + + strcpy("uart\0",dev->name,5); + dev->setup = uart_setup; + register_device(dev); + vfs_mknod("/dev/uart", "uart"); +} + diff --git a/lab7/src/mmu.c b/lab7/src/mmu.c new file mode 100644 index 000000000..77b91a9fa --- /dev/null +++ b/lab7/src/mmu.c @@ -0,0 +1,176 @@ +#include "mmu.h" +#include "peripheral/mmu.h" +#include "uint.h" +#include "allocator.h" +#include "math.h" +#include "thread.h" +#include "scheduler.h" + +struct pte_manage +{ + byte prot,num; +}*pm; + +void cow_init(){ + pm = malloc(sizeof(struct pte_manage) * (0x40000000/0x1000)); + delete_last_mem(pm); + for(int i=0;i<(0x40000000/0x1000);i++){ + pm[i].prot = 0; + pm[i].num = 0; + } +} + +uint64_t vm_decode(uint64_t va, pagetable_t *p){ + pagetable_t *pt = ((uint64_t) p & 0xfffff000) | 0xffff000000000000; + uint64_t blocksize = 0x8000000000; + for(int i=0;i<4;i++){ + pt = ((uint64_t)pt->entries[va/blocksize] & 0xfffff000) | 0xffff000000000000; + va %= blocksize; + blocksize >>= 9; + if(pt == 0xffff000000000000){ + return NULL; + } + } + uint64_t re = ((uint64_t)pt&0xfffffffff000) + va; + return re; +} + +pagetable_t* allocate_page(){ + pagetable_t* pt = malloc(sizeof(pagetable_t)); + for(int i=0;i<512;i++) pt->entries[i] = NULL; + return pt; +} + +pte_t walk(pagetable_t *pt, uint64_t va, uint64_t end, uint64_t pa, uint64_t blocksize, byte prot){ + if(blocksize < 1<<12){ + uint32_t idx = (pa & 0xfffff000) >> 12; + uint64_t label = PTE_ATTR_BASE; + pm[idx].num=1; + pm[idx].prot = prot; + if(prot == 0) return (pa & 0xfffff000); + if(prot & PROT_WRITE == 0) label |= RO_BIT | PD_ACCESS; + else label |= PD_ACCESS; + if(prot & PROT_EXEC == 0) label |= USR_EXE_NEVER_BIT; + return (pa & 0xfffff000) | label; + }else{ + uint64_t start = va / blocksize; + uint64_t num = upper_bound(end,blocksize) - va/blocksize; + if(pt == NULL){ + pt = allocate_page(); + move_last_mem(0); + }else{ + pt = ((uint64_t)pt & ~(uint64_t)0x3) | 0xffff000000000000; + } + for(int i=0;ientries[start + i] = walk(pt->entries[start + i], va2 - gap,min(end,(va2/blocksize + 1) * blocksize) - gap,pa + va2 - va,blocksize >> (uint64_t)9,prot); + } + return ((uint64_t)pt & (uint64_t)0xffffffff) | 0b11; + } +} + +void mappages(pagetable_t* pagetable, uint64_t va, uint64_t size, uint64_t pa, byte prot){ + uint64_t end_addr = va + size; + walk(pagetable, va, end_addr, pa, (uint64_t)1 << 39, prot); +} + +void SetTaskStackPagetable(pagetable_t *pt, void* stack_addr){ + int stack_size = 0x4000; + mappages(pt,0xffffffffb000,stack_size, (uint64_t)stack_addr & 0xfffffffc,PROT_READ | PROT_WRITE); +} + +void SetTaskCodePagetable(pagetable_t *pt, void* code_addr, uint64_t size){ + mappages(pt,0x0, size, (uint64_t)code_addr & 0xfffffffc, PROT_READ | PROT_EXEC); +} + +void SetPeripherialPagetable(pagetable_t *pt){ + mappages(pt,0x3c000000, 0x4000000, 0x3c000000, PROT_READ | PROT_WRITE); +} + +void* mmap_set(void* addr, size_t len, int prot, int flags){ + uint64_t align_addr = (uint64_t)addr & ~(uint64_t)0xfff; + thread_t *t = get_current(); + while(vm_decode(align_addr,t->page_table) != NULL){ + align_addr += 0x1000; + if(align_addr >= 0xffffffffb000) return NULL; + } + for(int i=0;i>12;i++) mappages(t->page_table,align_addr + i * 0x1000,0x1000,(uint64_t)prot<<12,0); + + return align_addr; +} + +bool mmap_check(uint64_t FAR){ + thread_t *t = get_current(); + if(FAR >= 0xFFFFFFFFB000 && FAR < 0xFFFFFFFFF000){ + uint64_t pa = vm_decode(FAR & ~(uint64_t)0xfff,t->page_table); + if(pa == NULL){ + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, (uint64_t)malloc(0x1000),PROT_READ | PROT_WRITE); + }else{ + byte *stack = (pa & ~(uint64_t)0xfff) | 0xffff000000000000; + byte *new_stack = malloc(0x1000); + for (int i=0;i<0x1000;i++) new_stack[i] = stack[i]; + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, new_stack,PROT_READ | PROT_WRITE); + } + set_ttbr0_el1(t->page_table); + return true; + } + if(FAR >= 0x3c000000 && FAR < 0x40000000){ + SetPeripherialPagetable(t->page_table); + set_ttbr0_el1(t->page_table); + return true; + } + uint64_t align_addr = (uint64_t)FAR & ~(uint64_t)0xfff; + uint64_t addr = vm_decode(align_addr,t->page_table)>>12; + if(addr != 0){ + if(addr < 0x10000){ + uint64_t *pa = malloc(0x1000); + for(int i=0;i<200;i++) pa[i] = 0; + mappages(t->page_table,align_addr,0x1000,pa,addr); + }else{ + if((pm[addr].prot&PROT_WRITE) == 0) return false; + uint64_t *space = (addr<<12) | 0xffff000000000000; + uint64_t *new_space = malloc(0x1000); + for(int i=0;i<0x200;i++) new_space[i] = space[i]; + mappages(t->page_table,align_addr,0x1000,new_space,pm[addr].prot); + } + set_ttbr0_el1(t->page_table); + return true; + } + return false; +} + + +void map_pages(uint64_t des, uint64_t src){ + pagetable_t* pt_des = (des&~(uint64_t)0xfff) | 0xffff000000000000; + pagetable_t* pt_src = (src&~(uint64_t)0xfff) | 0xffff000000000000; + for(int i=0;i<512;i++){ + if(pt_src->entries[i] == NULL) continue; + pagetable_t* pt_des_l2 = allocate_page(); + pt_des->entries[i] = ((uint64_t)pt_des_l2 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l2 = ((uint64_t)pt_src->entries[i] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int j=0;j<512;j++){ + if(pt_src_l2->entries[j] == NULL) continue; + pagetable_t* pt_des_l1 = allocate_page(); + pt_des_l2->entries[i] = ((uint64_t)pt_des_l1 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l1 = ((uint64_t)pt_src_l2->entries[j] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int k=0;k<512;k++){ + if(pt_src_l1->entries[k] == NULL) continue; + pagetable_t* pt_des_l0 = allocate_page(); + pt_des_l1->entries[i] = ((uint64_t)pt_des_l0 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l0 = ((uint64_t)pt_src_l1->entries[k] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int l=0;l<512;l++){ + if(pt_src_l0->entries[l] == NULL) continue; + pm[((uint32_t)(pt_src_l0->entries[l]))>>12].num++; + pt_src_l0->entries[l] |= RO_BIT; + pt_des_l0->entries[l] = pt_src_l0->entries[l]; + } + } + } + } +} \ No newline at end of file diff --git a/lab7/src/mmu_asm.S b/lab7/src/mmu_asm.S new file mode 100644 index 000000000..1579a5980 --- /dev/null +++ b/lab7/src/mmu_asm.S @@ -0,0 +1,109 @@ +#include "peripheral/mmu.h" +.global disable_mmu +.global set_tcr +.global set_mair +.global identity_paging +.global page_table_set +.global setup_mmu +.global set_ttbr0_el1 + +disable_mmu: + ldr x1, =0 //close MMU + msr sctlr_el1, x1 + ret + +set_tcr: + ldr x0, = TCR_CONFIG_DEFAULT + msr tcr_el1, x0 + ret + +set_mair: + ldr x0, =( \ + (MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE_nGnRnE * 8)) | \ + (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL_NOCACHE * 8)) \ + ) + msr mair_el1, x0 + ret + +identity_paging: + mov x0, 0 // PGD's page frame at 0x0 + mov x1, 0x1000 // PUD's page frame at 0x1000 + + ldr x2, = BOOT_PGD_ATTR + orr x2, x1, x2 // combine the physical address of next level page with attribute. + str x2, [x0] + + ldr x2, = BOOT_PUD0_ATTR + mov x3, 0x2000 + orr x3, x2, x3 + str x3, [x1] // 1st 1GB mapped by the 1st entry of PUD + ldr x2, = BOOT_PUD1_ATTR + mov x3, 0x40000000 + orr x3, x2, x3 + str x3, [x1, 8] // 2nd 1GB mapped by the 2nd entry of PUD + +/* mov x1, 0x2000 + ldr x2, = BOOT_PMD0_ATTR + mov x3, 0x10000 //PTE base + mov x4, xzr + mov x5, 0x200 + mov x6, 8 + +1: mul x7, x4, x6 + lsl x9, x4, 12 + add x9, x3, x9 + orr x9, x2, x9 + add x8, x1, x7 + str x9, [x8] + add x4, x4, #1 + cmp x4, x5 + b.ls 1b*/ + +2: mov x1, 0x2000 + ldr x2, = BOOT_PMD0_ATTR_RAM + mov x3, 0x1f7 + mov x4, xzr + +3: lsl x6, x4, 3 + add x7, x1, x6 + lsl x8, x4, 21 + orr x8, x2, x8 + str x8, [x7] + add x4, x4, #1 + cmp x4, x3 + b.ls 3b + +4: cmp x4, 0x1ff + bge 5f + ldr x2, = BOOT_PMD0_ATTR_MMIO + mov x3, 0x200 + b 3b + +5: msr ttbr0_el1, x0 // load PGD to the bottom translation-based register. + msr ttbr1_el1, x0 + + mrs x2, sctlr_el1 + orr x2 , x2, 1 + msr sctlr_el1, x2 // enable MMU, cache remains disabled + + + ldr x2, = boot_rest // indirect branch to the virtual address + br x2 + +setup_mmu: + bl set_tcr + bl set_mair + bl identity_paging + ret + +set_ttbr0_el1: + dsb ish // ensure write has completed + msr ttbr0_el1, x0 // switch translation based address. + tlbi vmalle1is // invalidate all TLB entries + dsb ish // ensure completion of TLB invalidatation + isb // clear pipeline + ret +.global get_ttbr0_el1 +get_ttbr0_el1: + mrs x0, ttbr0_el1 + ret \ No newline at end of file diff --git a/lab7/src/panic.c b/lab7/src/panic.c new file mode 100644 index 000000000..17942c5b6 --- /dev/null +++ b/lab7/src/panic.c @@ -0,0 +1,33 @@ +#include "mini_uart.h" +const char *entry_error_messages[] = { + "SYNC_INVALID_EL1t", + "IRQ_INVALID_EL1t", + "FIQ_INVALID_EL1t", + "ERROR_INVALID_EL1T", + + "SYNC_INVALID_EL1h", + "IRQ_INVALID_EL1h", + "FIQ_INVALID_EL1h", + "ERROR_INVALID_EL1h", + + "SYNC_INVALID_EL0_64", + "IRQ_INVALID_EL0_64", + "FIQ_INVALID_EL0_64", + "ERROR_INVALID_EL0_64", + + "SYNC_INVALID_EL0_32", + "IRQ_INVALID_EL0_32", + "FIQ_INVALID_EL0_32", + "ERROR_INVALID_EL0_32", +}; + +void not_implemented() { + uart_printf("kenel panic because of not implemented function...\n"); + while (1); +} + +void show_exception_status(int type, unsigned long esr, unsigned long address) { + uart_printf("%s, ESR: 0x%x, address: 0x%x\n", entry_error_messages[type], esr, address); + uart_printf("Exception class (EC) 0x%x\n", (esr >> 26) & 0b111111); + uart_printf("Instruction specific syndrome (ISS) 0x%x\n", esr & 0xFFFFFF); +} \ No newline at end of file diff --git a/lab7/src/priority_queue.c b/lab7/src/priority_queue.c new file mode 100644 index 000000000..183647ef7 --- /dev/null +++ b/lab7/src/priority_queue.c @@ -0,0 +1,79 @@ +#include "allocator.h" +#include "priority_queue.h" +#include "uint.h" +#include "thread.h" + +struct node *nodes = NULL; +int num_of_nodes=0; + +uint64 add_node(void (*callback_f)(),void* arguments,uint64 times,uint64 time_gap){ + + struct node *node = malloc(sizeof(struct node)); + node->time_to_ring = times; + node->todo = callback_f; + node->next = NULL; + node->arguments = arguments; + int a; + if(nodes == NULL){ + nodes = node; + }else if( time_gap >= times){ + time_gap = nodes->time_to_ring-time_gap; + node->next = nodes; + nodes = node; + struct node *temp=nodes->next; + while(temp != NULL){ + temp->time_to_ring -= time_gap; + temp = temp->next; + } + }else{ + struct node* temp = nodes; + time_gap = nodes->time_to_ring-time_gap; + temp->time_to_ring -= time_gap; + while(temp->next != NULL){ + temp->next->time_to_ring -= time_gap; + if(temp->next->time_to_ring >= times){ + node->next = temp->next; + temp->next = node; + temp->next = temp->next->next; + break; + }else{ + temp = temp->next; + } + } + if(temp->next == NULL){ + temp->next = node; + }else{ + while(temp->next != NULL){ + temp->next->time_to_ring -= time_gap; + temp = temp->next; + } + } + } + num_of_nodes++; + return nodes->time_to_ring; +} + +struct node* delete_first_node(){ + if(nodes == NULL) return NULL; + uint64 times=nodes->time_to_ring; + struct node *t = nodes; + nodes = nodes->next; + free(t); + struct node *temp = nodes; + while(temp != NULL){ + temp->time_to_ring -= times; + temp = temp->next; + } + num_of_nodes--; + return t; +} + +void print_node(){ + struct node *temp = nodes; + int i=0; + while(temp != NULL){ + uart_printf("%d: %d\n",i,temp->time_to_ring); + i++; + temp = temp->next; + } +} \ No newline at end of file diff --git a/lab7/src/queue.c b/lab7/src/queue.c new file mode 100644 index 000000000..56798b4ed --- /dev/null +++ b/lab7/src/queue.c @@ -0,0 +1,77 @@ +#include "uint.h" +#include "thread.h" +#include "scheduler.h" + +struct thread* run_queue = NULL; +extern uint64 freq_thread; +void init_queue(){ + run_queue = NULL; +} + +int schedule(){ +start: + if(run_queue == NULL) + push_first_thread(); + struct thread* prev = get_current(); + struct thread* tmp = run_queue; + run_queue = run_queue->next; + + if(tmp->status == running){ + switch_to(prev,tmp); + }else if(tmp->status == dead){ + remove_from_queue(tmp->tid); + goto start; + }else{ + tmp->status = running; + if(tmp->tid == 0){ + set_current(tmp); + }else{ + store_and_jump(prev,tmp); + } + } +} + +void push2run_queue(struct thread* thread){ + if(run_queue != NULL){ + struct thread *tmp = run_queue; + while(tmp->next != NULL){ + tmp = tmp->next; + } + tmp->next = thread; + }else{ + run_queue = thread; + } + thread->next = NULL; +} + +void push2run_queue_top(struct thread* thread){ + thread->next = run_queue; + run_queue = thread; +} + +void wakeup_queue(struct thread *t){ + if(t->status == dead) return; + t->status = running; + push2run_queue(t); +} + +void exit(){ + struct thread *t = get_current(); + free_mem_table(t); + t->status = dead; + schedule(); +} + +void remove_from_queue(pid_t pid){ + struct thread *t = run_queue; + if(t != NULL && t->tid == pid) run_queue = run_queue->next; + else if(t != NULL){ + while(t->next != NULL){ + if(t->next->tid == pid){ + t->next = t->next->next; + return; + } + } + } +} + diff --git a/lab7/src/reboot.c b/lab7/src/reboot.c new file mode 100644 index 000000000..867cabdf7 --- /dev/null +++ b/lab7/src/reboot.c @@ -0,0 +1,13 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC ((volatile unsigned int*)0xFFFF00003F10001c) +#define PM_WDOG ((volatile unsigned int*)0xFFFF00003F100024) + +void reset(int tick){ // reboot after watchdog timer expire + *PM_RSTC = PM_PASSWORD | 0x20; // full reset + *PM_WDOG = PM_PASSWORD | tick; // number of watchdog tick +} + +void cancel_reset() { + *PM_RSTC = PM_PASSWORD | 0; // full reset + *PM_WDOG = PM_PASSWORD | 0; // number of watchdog tick +} \ No newline at end of file diff --git a/lab7/src/scheduler.S b/lab7/src/scheduler.S new file mode 100644 index 000000000..1460e5df0 --- /dev/null +++ b/lab7/src/scheduler.S @@ -0,0 +1,157 @@ +.macro push_registers + stp x19, x20, [x0, 16 * 0] + stp x21, x22, [x0, 16 * 1] + stp x23, x24, [x0, 16 * 2] + stp x25, x26, [x0, 16 * 3] + stp x27, x28, [x0, 16 * 4] + stp fp, lr, [x0, 16 * 5] + mov x9, sp + str x9, [x0, 16 * 6] +.endm + +.macro pop_registers + ldp x19, x20, [x0, 16 * 0] + ldp x21, x22, [x0, 16 * 1] + ldp x23, x24, [x0, 16 * 2] + ldp x25, x26, [x0, 16 * 3] + ldp x27, x28, [x0, 16 * 4] + ldp fp, lr, [x0, 16 * 5] + ldr x9, [x0, 16 * 6] + mov sp, x9 +.endm + +.global switch_to +switch_to: + push_registers + + mov x0, x1 + + pop_registers + msr tpidr_el1, x1 + mov x0, #0 + ret + +.global get_current +get_current: + mrs x0, tpidr_el1 + ret + +.global store_and_jump +store_and_jump: + push_registers + + ldr x0, [x1, 8 * 2] + ldr x2, [x1, 8 * 3] + ldr x3, [x1, 8 * 4] + + mov x29, sp + + ldr x9, [x1, 8 * 1] + mov sp, x9 + + stp x1, x29, [sp, #-16]! + mov fp, sp + + ldr x9, [x1, 8 * 0] + msr tpidr_el1, x1 + mov x1, sp + blr x9 + + ldp x0, x29, [sp, 16 * 0] + mov sp, x29 + + mov w1, 3 + str w1, [x0, 140] + + bl exit + +.global set_current +set_current: + ldr x9, [x0, 8 * 1] + mov sp, x9 + + mov fp, sp + + msr tpidr_el1, x0 + ldr x9, [x0, 8 * 0] + blr x9 + +.global set_proc +set_proc: + msr tpidr_el1, x0 + ret + +.global task_schedule +task_schedule: + msr daifclr, 0x0 + push_registers + + bl UserScheduler + +.global SwitchTo +SwitchTo: + pop_registers + msr tpidr_el1, x0 + b check_signal + ret + +.global sig_handler_assembly +sig_handler_assembly: + mov x19, x0 + mov x0, x2 + sub sp, sp, #16 + str lr, [sp, 0 * 16] + msr daifclr, 0xf + bl from_el1_to_el0_forsig + mov x0, x19 + blr x19 //el0 start + mov x8, #20 + svc #0 + +.global ret_to_sig_han +ret_to_sig_han: + msr daifclr, 0x0 + mov sp, x0 + ldr lr, [sp, 0 * 16] + add sp, sp, #16 + ret + +.global check_signal +check_signal: + mov x1, sp + sub x1, x1, 16 * 7 + mov x2, x0 + mov x0, x1 + push_registers + mov sp, x1 + mov x0, x2 + + bl sig_handler_kernel + + mov x0, sp + pop_registers + msr daifclr, 0xf + ret + +from_el1_to_el0_forsig: + msr elr_el1, lr + + msr sp_el0, x1 + + ldr x1, =0 + msr spsr_el1, x1 + + + eret + +.global get_el +get_el: + mrs x0, CurrentEL + lsr x0, x0, #2 + and x0, x0, #3 + ret + +.global call_exit +call_exit: + mov x8, #5 + svc #0 \ No newline at end of file diff --git a/lab7/src/shell.c b/lab7/src/shell.c new file mode 100644 index 000000000..9a395b12f --- /dev/null +++ b/lab7/src/shell.c @@ -0,0 +1,315 @@ +#include "mini_uart.h" +#include "string.h" +#include "reboot.h" +#include "uint.h" +#include "dtb.h" +#include "allocator.h" +#include "aux.h" +#include "thread.h" +#include "getopt.h" +#include "scheduler.h" +#include "loadimg.h" +#include "mailbox.h" +#include "mmu.h" +#include "vfs.h" +#include "tmpfs.h" +#include "framebuffer.h" + +struct ARGS{ + char** argv; + int argc; +}; + + +extern unsigned char __heap_start, _end_, _begin_; +extern byte __dtb_addr; +uint64_t cpio_start,cpio_end; +char cmd_buffer[1024]; +unsigned int cmd_index = 0; +unsigned int cmd_flag = 0; + + +void shell_init(){ + uint64 *heap = (uint64*)(&__heap_start-8); + *heap &= 0x00000000; + uart_init(); + uart_printf("\n\n\nHello From RPI3\n"); + uart_init_buffer(); + uart_flush(); + core_timer_init(); + init_allocator(); + uint64 *ramf_start,*ramf_end; + ramf_start=find_property_value("/chosen\0","linux,initrd-start\0"); //get ramf start addr from dtb + ramf_end=find_property_value("/chosen\0","linux,initrd-end\0"); //get ramf end addr from dtb + if(ramf_start != 0){ + uart_printf("Ramf start: 0x%x\n",letobe(*ramf_start)); + cpio_start=letobe(*ramf_start); + }if(ramf_end != 0){ + uart_printf("Ramf end: 0x%x\n",letobe(*ramf_end)); + cpio_end=letobe(*ramf_end); + } + cpio_start |= 0xFFFF000000000000; + cpio_end |= 0xFFFF000000000000; + memory_reserve(0xffff000000000000,0xffff000000080000); //Spin tables for multicore boot + + memory_reserve(0xFFFF000000001000,0xFFFF000000003000); //Spin tables for multicore boot + + memory_reserve(cpio_start,cpio_end); //Initramfs + + memory_reserve(&_begin_,&_end_); //Kernel image in the physical memory and simple allocator + + uint64 *addr = &__dtb_addr; + + memory_reserve(*addr,*addr + 0x100000); //Device tree + + memory_reserve(0xFFFF000000000000,0xFFFF000000080000); //Kernel stack + + init_thread(); + + cow_init(); + + vfs_init(); + + tmpfs_init(); + + init_cpio(); + + vfs_uart_init(); + + vfs_fb_init(); + +} + +void reset_flag(){ + cmd_flag=0; + *AUX_MU_IER = 1; + core_timer_disable(); + irq_enable(); +} + +void uart_read_line(){ + //check("./initramfs/vfs1.img"); + char in; + if(cmd_flag == 0){ + uart_printf("# "); + cmd_flag = 1; + cmd_index = 0; + for(int i=0;i<1024;i++) cmd_buffer[i]=0; + } + while( uart_pop(&in) ){ + if(cmd_flag == 0){ + uart_printf("# "); + cmd_flag = 1; + cmd_index = 0; + for(int i=0;i<1024;i++) cmd_buffer[i]=0; + } + if(in == 13){ + uart_printf("\n"); + cmd_buffer[cmd_index++] = '\0'; + cmd_flag = 0; + check(cmd_buffer); + }else if((in==8 || in==127)){ + if(cmd_index>0){ + cmd_index--; + char t[1]={8}; + cmd_buffer[cmd_index]='\0'; + uart_write(8); + uart_write(' '); + uart_write(8); + } + }else if( in>=32 && in<=126 ){ + cmd_buffer[cmd_index++]=in; + uart_push(in); + *AUX_MU_IER |= 2; + } + } +} + +void* m[10]; + +struct ARGS* parse_command(char *command){ + char** tmp = malloc(sizeof(char*)*16); + int p=0; + if(command[0] == 0) return NULL; + for(int i=0;command[i] != 0;i++){ + if(command[i] == ' ') continue; + char *arg = malloc(sizeof(char[128])); + int p2=0; + for(;command[i] != 0 && command[i] != ' ' && command[i]>=32 && command[i]<=127 ;i++){ + arg[p2++] = command[i]; + } + arg[p2] = 0; + tmp[p++] = arg; + if(command[i] == 0) break; + } + struct ARGS* args; + args = malloc(sizeof(struct ARGS)); + args->argc = p; + args->argv = tmp; + return args; +} + +void temp_func2(){ + uart_printf("2"); +} + +void temp_func3(){ + uart_printf("3"); +} +void temp_func(){ +} + + + +void fork_test(){ + uart_printf("\nFork Test, pid %d\n", getpid1()); + int cnt = 1; + int ret = 0; + if ((ret = fork1()) == 0) { // child + long long cur_sp; + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("first child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + ++cnt; + + if ((ret = fork1()) != 0){ + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("first child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + } + else{ + while (cnt < 5) { + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("second child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + delay(5000); + ++cnt; + } + } + exit1(); + } + else { + uart_printf("parent here, pid %d, child %d\n", getpid1(), ret); + } +} + +void check(char *input){ + struct ARGS *cmd = parse_command(input); + if(input[0] == '\0' || input[0] == '\n') return; + if(strcmp(input,"help")==1){ + uart_printf("help : print the help menu\n"); + uart_printf("hello : print Hello World!\n"); + uart_printf("reboot : reboot the device\n"); + }else if(strcmp(input,"hello")==1){ + uart_printf("Hello World!\n"); + }else if(strncmp(input,"reboot",6)==1){ + uart_printf("Rebooting...\n"); + if(input[6] != ' '){ + reset(50); + while(1); + } + int a=0; + for(int i=7;input[i]<='9' && input[i]>='0';i++){ + a *= 10; + a += (input[i]-'0'); + } + reset(a<50? 50:a); + while(1); + }else if(strncmp(input,"ls",2)){ + char name[128]; + memset(name,0,128); + int i=3; + for(;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-3]=input[i]; + } + name[i]='\0'; + vfs_ls(name); + }else if(strncmp(input,"cd ",3)){ + char name[128]; + memset(name,0,128); + int i=3; + for(;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-3]=input[i]; + } + name[i]='\0'; + vfs_cd(name); + }else if(strncmp(input,"cat ", 4)){ + char name[128]; + for(int i=0;i<128;i++) name[i] &= 0; + int i=4; + for(i=4;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-4]=input[i]; + } + name[i]='\0'; + print_content(name, cpio_start); + }else if(strncmp(input,"./",2)){ + irq_disable(); + char name[128]; + for(int i=0;i<128;i++) name[i] = 0; + int i; + for(i=2;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-2]=input[i]; + } + char *const argv[] = {name}; + execute(name,argv); + irq_enable(); + }else if(strcmp(input,"timer")){ + int clock_hz,now_time,interval; + asm volatile("mrs %[input0], cntfrq_el0\n" + "mrs %[input1], cntp_tval_el0\n" + :[input0] "=r" (clock_hz), + [input1] "=r" (interval)); + uart_printf("%d\n", interval/clock_hz); + + }else if(strncmp(input,"sleep", 5)){ + char time[5]; + for(int i=0;i<5 && input[i+6]>=32 && input[i+6]<=127;i++) time[i] = input[i+6]; + int times = atoi(time); + sleep(times); + }else if(strcmp(cmd->argv[0],"thread")){ + int t=1; + optind = 1; + while(t){ + char c = getopt(cmd->argc,cmd->argv,":a:r"); + switch (c){ + case 'a': + for(int i=0;i<10;i++) + Thread(temp_func); + break; + case 'r': + break; + case 0: + t=0; + break; + } + } + }else if(strcmp(cmd->argv[0],"mem")){ + int t=1; + optind = 1; + while(t){ + char c = getopt(cmd->argc,cmd->argv,":s:a:p"); + switch (c){ + case 's': + pool_status(); + break; + case 'a': + printf_thread(); + break; + case 'p': + print_node(); + break; + case 0: + t=0; + break; + default: + show_status(); + break; + + } + } + }else if(strcmp(cmd->argv[0],"lp")){ + loadimg(); + }else if(strcmp(cmd->argv[0],"test")){ + fb_splash2(); + }else{ + uart_printf("command not found: %s\n",input); + } +} + diff --git a/lab7/src/signal.c b/lab7/src/signal.c new file mode 100644 index 000000000..5f885130c --- /dev/null +++ b/lab7/src/signal.c @@ -0,0 +1,37 @@ +#include "thread.h" +#include "signal.h" +#include "scheduler.h" +#include "uint.h" +#include "queue.h" +#include "excep.h" +#include "mmu.h" +extern struct thread *threads[thread_numbers]; + +int signal(int SIGNAL, void (*handler)()){ + struct thread *t = get_current(); + t->sig_handler[SIGNAL] = handler; +} + +int sentSignal(int pid, int SIGNAL){ + threads[pid]->signal |= 1<signal & 1<sig_handler[i] != NULL){ + t->signal &= !(1<page_table & ~(uint64_t) 0b11) | 0xffff000000000000; + void *sp = malloc(0x4000); + pagetable_t *tmp_pt = allocate_page(); + t->page_table = ((uint64_t)tmp_pt & ~0xffff000000000000) | 0b11; + SetTaskStackPagetable(t->page_table, sp); + for(int j=0;j<0x1f0;j++) tmp_pt->entries[j] = pt->entries[j]; + set_ttbr0_el1(t->page_table); + sig_handler_assembly(t->sig_handler[i], 0xfffffffff000, NULL); + free(sp); + t->page_table = pt; + set_ttbr0_el1(t->page_table); + } + } + return t; +} \ No newline at end of file diff --git a/lab7/src/start.S b/lab7/src/start.S new file mode 100644 index 000000000..74ac47b35 --- /dev/null +++ b/lab7/src/start.S @@ -0,0 +1,79 @@ + +.section ".text.boot" + +.global _start +.global from_el1_to_el0 +.global user_process +.global boot_rest + + +_start: + // get cpu id + mrs x1, MPIDR_EL1 + and x1, x1, #3 + cbz x1, 2f + // if cpu_id > 0, stop +1: + wfe + b 1b + // if cpu_id == 0 +2: + mov x1, 0x02080000 + str x0, [x1] + bl disable_mmu + + // set stack pointer + ldr x1, =_start + mov sp, x1 + + bl from_el2_to_el1 + bl setup_mmu + +boot_rest: + // clear bss + ldr x1, =__bss_start + ldr x2, =__bss_size +3: cbz x2, 4f + str xzr, [x1], #8 + sub x2, x2, #1 + cbnz x2, 3b + + + +4: bl main + // halt this core if return + b 1b + + +from_el2_to_el1: + ldr x1, =_start + msr sp_el1, x1 + + mov x1, (0b11 << 20) // make el0, el1 can use Floating point and Advanced SIMD + msr CPACR_EL1, x1 + + mov x0, (1 << 31) // EL1 uses aarch64 + msr hcr_el2, x0 + + mov x0, 0x3c5 // EL1h (SPSel = 1) with interrupt disabled + msr spsr_el2, x0 + + msr elr_el2, lr + + + adr x9, exception_table + msr vbar_el1, x9 + + eret + +from_el1_to_el0: + msr elr_el1, x19 + + msr sp_el0, x20 + + ldr x1, =0x3c0 + msr spsr_el1, x1 + + + eret + diff --git a/lab7/src/string.c b/lab7/src/string.c new file mode 100644 index 000000000..40aa8fd00 --- /dev/null +++ b/lab7/src/string.c @@ -0,0 +1,178 @@ +#include "uint.h" +void itoa(unsigned long long value,char *s) { + int idx = 0; + char tmp[24]; + int tidx = 0; + do { + tmp[tidx++] = '0' + value % 10; + value /= 10; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for (i = tidx - 1; i >= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +void ftoa(float *value, int precise, char *s) { + int temp=1; + for(int i=0;i= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +int strcmp(char *string1, char *string2){ + while(*string1 && *string2){ + if(*string1!=*string2) return 0; + else{ + string1++; + string2++; + } + } + if(*string1){ + if((*string1>='a' && *string1<='z') || (*string1>='A' && *string1<='Z') || (*string1>='0' && *string1<='9')) + return 0; + else + return 1; + } + if(*string2){ + if((*string2>='a' && *string2<='z') || (*string2>='A' || *string2<='Z') || (*string2>=0 && *string2<=9)) + return 0; + else + return 1; + } + return 1; +} + +int strncmp(char *string1, char *string2, int length){ + char temp1[128],temp2[128]; + for(int i=0;i=32 && s1[i]<=127;i++){ + out[i]=s1[i]; + } + for(;s2[j]>=32 && s2[j]<=127;j++){ + out[i+j]=s2[j]; + } + out[i+j]=0; + +} + +int atoi(char *s){ + int n=0; + for(int i=0;s[i]>=32 && s[i]<=127;i++){ + n*=10; + n += s[i]-'0'; + } + return n; +} + +int a16toi(char *s){ + int n=0; + for(int i=0;(s[i]>='0' && s[i]<='9') || (s[i]>='A' && s[i]<='F') || (s[i]>='a' && s[i]<='f');i++){ + n*=16; + if(s[i]>='0' && s[i]<='9') + n += s[i]-'0'; + else if(s[i]>='A' && s[i]<='F') + n += s[i]-'A'; + else if(s[i]>='a' && s[i]<='f') + n += s[i]-'a'; + } + return n; +} + +int a16ntoi(char *num, int length){ // transform hex string to int + int namesize=0; + for(int i=0;i='0' && num[i]<='9'){ + namesize += (num[i]-'0'); + }else if(num[i]>='A' && num[i]<='F'){ + namesize += (num[i]-'A'+10); + } + } + return namesize; +} + +void *memset(void *str, int c, size_t n){ + unsigned char* string = (unsigned long)str + c; + for(int i=0;ipage_table); + SwitchTo(t); + } +} + +void UserExit(){ + struct thread *t = get_current(); + t->status = dead; + UserScheduler(); +} + +void* ReadyListPop(){ + void * tmp = ReadyList; + ReadyList = ReadyList->next; + return tmp; +} + +void InitUserTaskScheduler(){ + thread_timer(); + struct thread *t = get_current(); + t->status = dead; + UserScheduler(); +} + +void PushToReadyList(pid_t pid){ + struct thread* item = threads[pid]; + struct thread *tmp = ReadyList; + if(tmp == NULL){ + ReadyList = item; + }else{ + while(tmp->next != NULL) tmp = tmp->next; + tmp->next = item; + } + item->next = NULL; +} + +void RemoveItemFromReadyList(pid_t pid){ + struct thread *tmp = ReadyList; + if(tmp != NULL){ + if(tmp->tid == pid){ + ReadyList = ReadyList->next; + }else{ + while(tmp->next != NULL){ + if(tmp->next->tid == pid){ + tmp->next = tmp->next->next; + } + } + } + } +} + +int UserKill(pid_t pid){ + threads[pid]->status = dead; + RemoveItemFromReadyList(pid); +} + +int UserThread(void* func,void* arg){ + struct thread *t; + t = malloc(sizeof(struct thread)); + for(int i=0;itid = i; + break; + } + } + delete_last_mem(); + unsigned char* kstack = malloc(0x10000); + t->next = NULL; + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + t->sig_handler[9] = call_exit; + t->sig_handler[10] = UserKill; + t->page_table = ((uint64_t)allocate_page() | 0b11) & ~0xffff000000000000; + t->signal = 0; + t->childs = NULL; + t->kstack = kstack; + t->registers[0] = 0x0; + t->registers[1] = 0xfffffffff000; + t->registers[2] = arg; + t->registers[10] = ( (uint64)(t->kstack + 0x10000) & 0xfffffffffffffff0); + t->registers[11] = from_el1_to_el0; + t->registers[12] = t->registers[10]; + memset(t->fd,0,sizeof(struct file*) * 65536); + struct file* tmp; + vfs_open("/dev/uart",64,&tmp); + t->fd[0] = tmp; + t->fd[1] = tmp; + t->fd[2] = tmp; + vfs_lookup("/",&(t->CurWorkDir)); + + struct thread *temp = get_current(); + t->ptid = temp->tid; + t->malloc_table[0] = NULL; + struct thread_sibling *temp2 = temp->childs; + struct thread_sibling *new_child = malloc(sizeof(struct thread_sibling)); + move_last_mem(t->tid); + move_last_mem(t->tid); + move_last_mem(t->tid); + void *a; + new_child->self = t; + new_child->next = NULL; + if(temp2 == NULL){ + temp->childs = new_child; + }else{ + while(temp2->next != NULL){ + temp2 = temp2->next; + } + temp2->next = new_child; + } + PushToReadyList(t->tid); + return t->tid; +} + +int set_fork(void* sp){ + byte *t = get_current(); + tid_t tid = UserThread(return_to_child,NULL); + pagetable_t* pagetable = threads[tid]->page_table; + unsigned char* kstack = threads[tid]->kstack; + + byte *child = threads[tid]; + uint64 gap = (uint64)child - (uint64)t; + for(int i=0;ikstack; + threads[tid]->tid = tid; + threads[tid]->ptid = tmp->tid; + threads[tid]->registers[10] = tf-1; + threads[tid]->registers[11] = return_to_child; + threads[tid]->registers[12] = tf; + threads[tid]->next = NULL; + threads[tid]->kstack = kstack; + threads[tid]->page_table = pagetable; + for(int i=0;i<0x10000;i++) kstack[i] = tmp->kstack[i]; + map_pages(threads[tid]->page_table,tmp->page_table); + set_ttbr0_el1(tmp->page_table); + tf->spsr_el1 = 0; + tf->x[0] = 0; + return tid; +} + +void execute(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0) { + uart_printf("Error: \"%s\" is not an executable file\n",file); + return; + } + int tid = UserThread(code,NULL); + SetTaskCodePagetable(threads[tid]->page_table,code,length); + InitUserTaskScheduler(); +} + +void exec(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0){ + uart_printf("Error: \"%s\" is not an executable file\n",file); + return; + } + struct thread *t = get_current(); + SetTaskCodePagetable(t->page_table,code,length); + from_el1_to_el0(code, 0xfffffffff000); +} diff --git a/lab7/src/temp.S b/lab7/src/temp.S new file mode 100644 index 000000000..2a2161ba4 --- /dev/null +++ b/lab7/src/temp.S @@ -0,0 +1,49 @@ +.global getpid1 +getpid1: + mov x8, #0 + svc #0 + ret + +.global uart_read1 +uart_read1: + mov x8, #1 + svc #0 + ret + +.global uart_write1 +uart_write1: + mov x8, #2 + svc #0 + ret + +.global exec1 +exec1: + mov x8, #3 + svc #0 + ret + +.global fork1 +fork1: + mov x8, #4 + svc #0 + ret + +.global exit1 +exit1: + mov x8, #5 + svc #0 + ret + +.global mbox_call1 +mbox_call1: + mov x8, #6 + svc #0 + ret + +.global kill1 +kill1: + mov x8, #7 + svc #0 + ret + + diff --git a/lab7/src/thread.c b/lab7/src/thread.c new file mode 100644 index 000000000..3d180fb28 --- /dev/null +++ b/lab7/src/thread.c @@ -0,0 +1,224 @@ +#include "uint.h" +#include "thread.h" +#include "allocator.h" +#include "queue.h" +#include "scheduler.h" +#include "shell.h" +#include "excep.h" +#include "task.h" + +struct thread *threads[thread_numbers]; + + +int Thread(void *func(void),...){ + __builtin_va_list args; + __builtin_va_start(args, func); + void* arg = __builtin_va_arg(args, void*); + struct thread *t; + t = malloc(sizeof(struct thread)); + delete_last_mem(); + t->next = NULL; + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + t->sig_handler[9] = kill; + t->sig_handler[10] = kill; + t->signal = 0; + t->status = starting; + t->childs = NULL; + t->ustack = malloc(0x10000); + t->registers[0] = func; + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); + t->registers[2] = arg; + for(int i=0;i<65536;i++) t->fd[i] = NULL; + vfs_lookup("/",&(t->CurWorkDir)); + struct thread *temp = get_current(); + t->ptid = temp->tid; + t->malloc_table[0] = NULL; + struct thread_sibling *temp2 = temp->childs; + struct thread_sibling *new_child = malloc(sizeof(struct thread_sibling)); + delete_last_mem(); + void *a; + new_child->self = t; + new_child->next = NULL; + if(temp2 == NULL){ + temp->childs = new_child; + }else{ + while(temp2->next != NULL){ + temp2 = temp2->next; + } + temp2->next = new_child; + } + for(int i=0;itid = i; + break; + } + } + move_last_mem(t->tid); + push2run_queue(t); + return t->tid; +} + + +void set_first_thread(){ + struct thread *t; + t = malloc(sizeof(struct thread)); + delete_last_mem(); + t->status = starting; + t->childs = NULL; + t->ptid = 0; + t->tid = 0; + t->signal = 0; + threads[0] = t; + t->malloc_table[0] = NULL; + t->next = NULL; + t->ustack = malloc(0x10000); + delete_last_mem(); + t->registers[0] = idle; + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + push2run_queue(t); +} + +void push_first_thread(){ + push2run_queue(threads[0]); +} + +void init_thread(){ + clear_threads(); + asm("mov x0, #0\n" + "msr tpidr_el1, x0\n"); + return ; +} + +void kill_zombies(){ + for(int i=1;istatus == dead){ + free_mem_table(threads[i]); + free(threads[i]); + threads[i] = NULL; + } + } +} + +void idle(){ + while(1){ + handle_child(0); + kill_zombies(); + free_mem_table(threads[0]); + Thread(uart_read_line); + schedule(); + } +} + +void clear_threads(){ + for(int i=0;ichilds; + if(ts == NULL){ + return; + }else{ + while(ts->self->status == dead){ + free(ts); + threads[0]->childs = threads[0]->childs->next; + ts = threads[0]->childs; + if(ts == NULL) return; + } + while(ts->next != NULL){ + if(ts->next->self->status == dead){ + free(ts->next); + ts->next = ts->next->next; + } + ts = ts->next; + } + + } +} + +void free_mem_table(struct thread *t){ + for(int i=0;i<256;i++){ + if(t->malloc_table[i] != NULL){ + free(t->malloc_table[i]); + t->malloc_table[i] = NULL; + }else{ + return; + } + } +} + +void record_mem(void* addr){ + struct thread *t = get_current(); + for(int i=0;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i] = addr; + if(i<255) t->malloc_table[i+1] = NULL; + break; + } + } +} + +void delete_last_mem(){ + struct thread *t = get_current(); + if(t == NULL || t->malloc_table[0] == NULL) return; + for(int i=1;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i-1] = NULL; + break; + } + } +} + +void printf_thread(){ + for(int i=0;i<10;i++){ + if(threads[i] != NULL){ + uart_printf("tid: %d\n",threads[i]->tid); + uart_printf("addr: 0x%x\n",threads[i]); + uart_printf("status: %d\n",threads[i]->status); + uart_printf("ptid: %d\n",threads[i]->ptid); + uart_printf("stack: 0x%x ~ 0x%x\n",threads[i]->ustack,threads[i]->ustack+0x10000); + } + } +} + +int getpid(){ + struct thread *t = get_current(); + return t->tid; +} + +int kill(pid_t pid){ + free_mem_table(threads[pid]); + threads[pid]->status = dead; + threads[pid] = NULL; + remove_from_queue(pid); +} + +int move_last_mem(tid_t tid){ + struct thread *now = get_current(); + void* addr; + for(int i=0;i<256;i++){ + if(now->malloc_table[i] == NULL){ + if(i == 0) return -1; + addr = now->malloc_table[i-1]; + now->malloc_table[i-1] = NULL; + break; + } + } + + + struct thread *t = threads[tid]; + for(int i=0;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i] = addr; + if(i<255) t->malloc_table[i+1] = NULL; + return 0; + } + } +} \ No newline at end of file diff --git a/lab7/src/timer.S b/lab7/src/timer.S new file mode 100644 index 000000000..c995ff31b --- /dev/null +++ b/lab7/src/timer.S @@ -0,0 +1,24 @@ +#define CORE0_TIMER_IRQ_CTRL 0xFFFF000040000040 +.global core_timer_enable +.global core_timer_disable + + +core_timer_enable: + mov x0, 1 + msr cntp_ctl_el0, x0 // enable + mrs x0, cntfrq_el0 + msr cntp_tval_el0, x0 // set expired time + mov x0, 2 + ldr x1, =CORE0_TIMER_IRQ_CTRL + str w0, [x1] // unmask timer interrupt + ret + +core_timer_disable: + mov x0, 0 + msr cntp_ctl_el0, x0 // disable + mov x0, 0 + ldr x1, =CORE0_TIMER_IRQ_CTRL + str w0, [x1] // unmask timer interrupt + ret + + \ No newline at end of file diff --git a/lab7/src/tmpfs.c b/lab7/src/tmpfs.c new file mode 100644 index 000000000..50fe24216 --- /dev/null +++ b/lab7/src/tmpfs.c @@ -0,0 +1,255 @@ +#include "vfs.h" +#include "allocator.h" +#include "string.h" +#include "tmpfs.h" + +struct file_operations *tmpfs_fops; +struct vnode_operations *tmpfs_vops; + +extern struct mount* rootfs; + +void tmpfs_init(){ + tmpfs_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + tmpfs_fops = malloc(sizeof(struct file_operations)); + delete_last_mem(); + tmpfs_vops->create = tmpfs_create; + tmpfs_vops->lookup = tmpfs_lookup; + tmpfs_vops->mkdir = tmpfs_mkdir; + tmpfs_vops->mknod = tmpfs_mknod; + tmpfs_fops->close = tmpfs_close; + tmpfs_fops->lseek64 = tmpfs_lseek64; + tmpfs_fops->open = tmpfs_open; + tmpfs_fops->read = tmpfs_read; + tmpfs_fops->write = tmpfs_write; + struct filesystem *fs = malloc(sizeof(struct filesystem)); + delete_last_mem(); + fs->name = malloc(16); + delete_last_mem(); + memset(fs->name,0,16); + strcpy("tmpfs\0",fs->name,6); + fs->setup_mount = tmpfs_mount; + register_filesystem(fs); + fs->setup_mount(fs,rootfs); + struct vnode* tmp; + + tmpfs_mkdir(rootfs->root,&tmp,"initramfs"); + tmpfs_mkdir(rootfs->root,&tmp,"dev"); +} + +int tmpfs_mount(struct filesystem* fs, struct mount* mount){ + mount->fs = fs; + struct vnode *tmp = allo_vnode(); + struct dentry *tmp_child = allo_dentry(), *tmp_parent = allo_dentry(); + tmp->f_ops = tmpfs_fops; + tmp->v_ops = tmpfs_vops; + tmp->mount = mount; + + tmp->dt->name[0] = 0; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + if(mount->root !=NULL){ + tmp->dt->parent = mount->root->dt->parent; + tmp_parent = mount->root->dt->childs->next->entry; + }else{ + tmp->dt->parent = tmp->dt; + + tmp_parent = allo_dentry(); + tmp_parent->name[0] = '.'; + tmp_parent->name[1] = '.'; + tmp_parent->name[2] = 0; + tmp_parent->vnode = tmp; + tmp_parent->childs = tmp->dt->childs; + tmp_parent->type = directory; + tmp_parent->parent = tmp->dt->parent; + } + + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + + mount->root = tmp; + return 0; +} + +int tmpfs_create(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* tmp; + tmpfs_lookup(dir_node,&tmp,component_name); + if(tmp != NULL){ + *target = NULL; + return -1; + } + tmp = allo_vnode(); + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = tmpfs_fops; + tmp->internal = malloc(0x100); + delete_last_mem(); + memset(tmp->internal,0,0x100); + tmp->v_ops = tmpfs_vops; + tmp->f_ops = tmpfs_fops; + tmp->size = 0; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = file; + *target = tmp; + + struct link_list *parent_ll = dir_node->dt->childs; + while(parent_ll->next!=NULL)parent_ll = parent_ll->next; + parent_ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_ll->next->entry = tmp->dt; + parent_ll->next->next = NULL; + return 0; +} + +int tmpfs_mkdir(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* temp; + tmpfs_lookup(dir_node,&temp,component_name); + if(temp != NULL){ + *target = NULL; + return -1; + } + struct vnode *tmp = allo_vnode(); + struct dentry *tmp_child = allo_dentry(),*tmp_parent = allo_dentry(); + + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = tmpfs_fops; + tmp->v_ops = tmpfs_vops; + tmp->size = 0; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + *target = tmp; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + tmp_parent->name[0] = '.'; + tmp_parent->name[1] = '.'; + tmp_parent->name[2] = 0; + tmp_parent->vnode = tmp->dt->parent->vnode; + tmp_parent->childs = tmp->dt->parent->childs; + tmp_parent->type = directory; + tmp_parent->parent = tmp->dt->parent->parent; + + struct link_list *tmp_parent_child = tmp_parent->childs; + while(tmp_parent_child->next != NULL) tmp_parent_child = tmp_parent_child->next; + tmp_parent_child->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp_parent_child->next->next = NULL; + tmp_parent_child->next->entry = tmp->dt; + + return 0; +} + +int tmpfs_lookup(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct link_list* tmp = dir_node->dt->childs; + while(tmp != NULL){ + struct dentry* den_tmp = tmp->entry; + if(strcmp(den_tmp->name,component_name)){ + *target = den_tmp->vnode; + return 0; + } + tmp = tmp->next; + } + *target = NULL; + return -1; +} + +int tmpfs_write(struct file* file, const void* buf, size_t len){ + char *internal = file->vnode->internal, *tmp = buf; + for(int i=0;if_pos++] = tmp[i]; + //if(tmp[i] == EOF) return i; + } + return len; +} + +int tmpfs_read(struct file* file, void* buf, size_t len){ + char *internal = file->vnode->internal, *tmp = buf; + for(int i=0;if_pos++]; + if(tmp[i] == EOF) return i; + } + return len; +} + +int tmpfs_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = tmpfs_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int tmpfs_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +long tmpfs_lseek64(struct file* file, long offset, int whence){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} + +int tmpfs_mknod(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* tmp; + tmpfs_lookup(dir_node,&tmp,component_name); + if(tmp != NULL){ + *target = NULL; + return -1; + } + tmp = allo_vnode(); + strcpy(component_name,tmp->dt->name,16); + tmp->size = 0; + tmp->dt->type = device; + tmp->dt->vnode = tmp; + tmp->mount = NULL; + *target = tmp; + + struct link_list *parent_ll = dir_node->dt->childs; + while(parent_ll->next!=NULL)parent_ll = parent_ll->next; + parent_ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_ll->next->entry = tmp->dt; + parent_ll->next->next = NULL; + return 0; +} diff --git a/lab7/src/vfs.c b/lab7/src/vfs.c new file mode 100644 index 000000000..da1195297 --- /dev/null +++ b/lab7/src/vfs.c @@ -0,0 +1,303 @@ +#include "uint.h" +#include "vfs.h" +#include "allocator.h" +#include "cpio.h" +#include "string.h" +#include "list.h" +#include "mini_uart.h" +#include "thread.h" +#include "scheduler.h" + +struct mount* rootfs; +struct link_list* filesystem_pool = NULL; +struct device *dv[100]; + + +struct filesystem* find_filesystem(const char *name){ + struct link_list* fs_pool = filesystem_pool; + while(fs_pool != NULL){ + struct filesystem *fs = fs_pool->entry; + if(strcmp(fs->name,name)) return fs; + fs_pool = fs_pool->next; + } + return NULL; +} + +struct device* find_device(const char *name){ + for(int i=0;i<100;i++){ + if(strcmp(name,dv[i]->name)){ + return dv[i]; + } + } + return NULL; +} + +void vfs_init(){ + rootfs = malloc(sizeof(struct mount)); + rootfs->root = NULL; + for(int i=0;i<100;i++) dv[i] = NULL; +} + +int register_filesystem(struct filesystem* fs) { + // register the file system to the kernel. + // you can also initialize memory pool of the file system here. + struct link_list *tmp_pool; + if(filesystem_pool == NULL){ + tmp_pool = malloc(sizeof(struct link_list)); + filesystem_pool = tmp_pool; + }else{ + tmp_pool = filesystem_pool; + while(tmp_pool->next != NULL) tmp_pool = tmp_pool->next; + tmp_pool->next = malloc(sizeof(struct link_list)); + tmp_pool = tmp_pool->next; + } + tmp_pool->next = NULL; + tmp_pool->entry = fs; + return 0; +} + +int register_device(struct device* d) { + for(int i=0;i<100;i++){ + if(dv[i] == NULL){ + dv[i] = d; + return 0; + } + } + return -1; +} + +int vfs_open(const char* pathname, int flags, struct file** target) { + // 1. Lookup pathname + // 2. Create a new file handle for this vnode if found. + // 3. Create a new file if O_CREAT is specified in flags and vnode not found + // lookup error code shows if file exist or not or other error occurs + // 4. Return error code if fails + + struct vnode* filenode; + int errno; + if((errno = vfs_lookup(pathname,&filenode)) < 0){ + if(flags & O_CREAT){ + int last_slash = 0; + for(int i=0;pathname[i]!=0 && i<256;i++){ + if(pathname[i] == '/') last_slash = i; + } + char filename[256]; + memset(filename,0,256); + if(last_slash!=0) + for(int i=0;iv_ops->create(parent,&filenode,filename)) <0 ){ + return errno; + } + }else return errno; + } + int return_value = filenode->f_ops->open(filenode,target); + (*target)->flags = flags; + return return_value; +} + +int vfs_close(struct file* file) { + // 1. release the file handle + // 2. Return error code if fails + return file->f_ops->close(file); +} + +int vfs_write(struct file* file, const void* buf, size_t len) { + // 1. write len byte from buf to the opened file. + // 2. return written size or error code if an error occurs. + if(file == NULL) return -1; + return file->f_ops->write(file,buf,len); +} + +int vfs_read(struct file* file, void* buf, size_t len) { + // 1. read min(len, readable size) byte to buf from the opened file. + // 2. block if nothing to read for FIFO type + // 2. return read size or error code if an error occurs. + if(file == NULL) return -1; + file->f_pos = 0; + return file->f_ops->read(file,buf,len); +} + +int vfs_mkdir(const char* pathname){ + int last_slash = 0; + char path[256], component[256]; + memset(path,0,256); + memset(component,0,256); + for(int i=0;i<256;i++){ + if(pathname[i] == '/' && pathname[i+1]!=0 && pathname[i+1]!=' ') last_slash = i; + if(pathname[i] == 0) break; + } + for(int i=0;iv_ops->mkdir(target,&target2, component); + if(errno >= 0) target2->mount = NULL; + return errno; +} + +int vfs_mount(const char* target, const char* filesystem){ + struct vnode* mountpoint; + int errno; + if((errno = vfs_lookup(target,&mountpoint)) < 0){ + return errno; + } + struct filesystem *fs = find_filesystem(filesystem); + if(fs == NULL) return -1; + if(mountpoint->mount != NULL){ + return -1; + } + mountpoint->mount = malloc(sizeof(struct mount)); + mountpoint->mount->fs = fs; + mountpoint->mount->root = malloc(sizeof(struct vnode)); + mountpoint->mount->root->mount = NULL; + mountpoint->mount->root->dt = mountpoint->dt; + + return fs->setup_mount(fs,mountpoint->mount); +} + +int vfs_lookup(const char* pathname, struct vnode** target){ + struct thread *t = get_current(); + struct vnode* CurrWorkDir = t->CurWorkDir; + char *parse = malloc(16); + memset(parse, 0, 16); + int idx = 0; + for(int i=0;i<256;i++){ + if(pathname[i] == '/'){ + if(i == 0){ + CurrWorkDir = rootfs->root; + } + else{ + if(CurrWorkDir->dt->type != directory) return -1; + struct vnode* tmp; + int errno; + if((errno = CurrWorkDir->v_ops->lookup(CurrWorkDir,&tmp,parse)) < 0){ + return errno; + } + if(tmp->mount != NULL && tmp->mount->root!=NULL) tmp = tmp->mount->root; + CurrWorkDir = tmp; + memset(parse, 0, 16); + idx = 0; + } + }else if(pathname[i] == 0){ + if(idx == 0){ + *target = CurrWorkDir; + return 0; + } + else{ + if(CurrWorkDir->dt->type != directory) return -1; + struct vnode* tmp; + int errno; + if((errno = CurrWorkDir->v_ops->lookup(CurrWorkDir,target,parse)) < 0){ + return errno; + } + if((*target)->dt->type == directory && (*target)->mount != NULL && (*target)->mount->root!=NULL) *target = (*target)->mount->root; + return 0; + } + }else{ + parse[idx++] = pathname[i]; + } + } + return -2; +} + +int vfs_mknod(const char* pathname, const char* device){ + int errno; + struct vnode *tmp,*target; + if(vfs_lookup(pathname,&tmp) >= 0){ + return -1; + } + int last_slash = -1; + char path[256], component[256]; + memset(path,0,256); + memset(component,0,256); + for(int i=0;i<256;i++){ + if(pathname[i] == '/' && pathname[i+1]!=0 && pathname[i+1]!=' ') last_slash = i; + if(pathname[i] == 0) break; + } + for(int i=0;iCurWorkDir; + }else{ + if(last_slash == 0)path[0] = '/'; + vfs_lookup(path,&tmp); + } + for(int i=last_slash+1;i<256;i++){ + if(pathname[i] == 0)break; + component[i-last_slash-1] = pathname[i]; + } + errno = tmp->v_ops->mknod(tmp,&target,component); + if(errno < 0) return errno; + struct device *d = find_device(device); + if(d == NULL) return -2; + errno = d->setup(d,target); + return errno; +} + +long vfs_lseek(struct file* f, long offset, int whence){ + return f->f_ops->lseek64(f,offset,whence); +} + +void vfs_ls(const char* pathname){ + struct vnode *tmp; + if(pathname[0] == 0){ + vfs_lookup("/",&tmp); + }else{ + int errno; + if((errno = vfs_lookup(pathname,&tmp)) <0){ + uart_printf("File not found: %s\n",pathname); + return; + } + } + if(tmp->dt->type == directory){ + struct link_list* ll = tmp->dt->childs; + while(ll != NULL){ + struct dentry* tmp2 = ll->entry; + uart_printf("%s ",tmp2->name); + ll = ll->next; + } + uart_printf("\n"); + }else{ + uart_printf("%s\n",tmp->dt->name); + } +} + +void vfs_cd(const char* pathname){ + struct thread *t = get_current(); + + vfs_lookup(pathname, &(t->CurWorkDir)); +} + +struct vnode* allo_vnode(){ + struct vnode* vn = malloc(sizeof(struct vnode)); + delete_last_mem(); + vn->mount = NULL; + vn->dt = allo_dentry(); + return vn; +} + +struct dentry* allo_dentry(){ + struct dentry* de = malloc(sizeof(struct dentry)); + delete_last_mem(); + memset(de->name,0,32); + return de; +} \ No newline at end of file diff --git a/lab7/user/include/system.h b/lab7/user/include/system.h new file mode 100644 index 000000000..9a8aea0de --- /dev/null +++ b/lab7/user/include/system.h @@ -0,0 +1,27 @@ +#include "type.h" +#ifndef __system__ +#define __system__ + +/* +SCN : function +0 : int getpid() +1 : size_t uartread(char buf[], size_t size) +2 : size_t uartwrite(const char buf[], size_t size) +3 : int exec(const char *name, char *const argv[]) +4 : int fork() +5 : void exit(int status) +6 : int mbox_call(unsigned char ch, unsigned int *mbox) +7 : void kill(int pid) +*/ + +int getpid(); +size_t uart_read(char buf[], size_t size); +size_t uart_write(const char buf[], size_t size); +int exec(const char* name, char *const argv[]); +int fork(); +void exit(); +int mbox_call(unsigned char ch, unsigned int *mbox); +void kill(int pid); + + +#endif \ No newline at end of file diff --git a/lab7/user/include/type.h b/lab7/user/include/type.h new file mode 100644 index 000000000..6a773a4ac --- /dev/null +++ b/lab7/user/include/type.h @@ -0,0 +1,15 @@ +#ifndef __type__ +#define __type__ + +#define byte unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned long long +#define size_t uint32_t +#define NULL (void*)0 +#define bool byte +#define false 0 +#define true 1 +#define tid_t uint32_t + +#endif \ No newline at end of file diff --git a/lab7/user/out/main.o b/lab7/user/out/main.o new file mode 100644 index 000000000..d4fb3b0e7 Binary files /dev/null and b/lab7/user/out/main.o differ diff --git a/lab7/user/out/system.o b/lab7/user/out/system.o new file mode 100644 index 000000000..029fe5fb4 Binary files /dev/null and b/lab7/user/out/system.o differ diff --git a/lab7/user/src/main.c b/lab7/user/src/main.c new file mode 100644 index 000000000..886d87da7 --- /dev/null +++ b/lab7/user/src/main.c @@ -0,0 +1,7 @@ +#include "system.h" + +int main(){ + char a[] = "How are you\n"; + uart_write(a,sizeof(a)); + exit(); +} \ No newline at end of file diff --git a/lab7/user/src/system.S b/lab7/user/src/system.S new file mode 100644 index 000000000..fc9734502 --- /dev/null +++ b/lab7/user/src/system.S @@ -0,0 +1,49 @@ +.global getpid +getpid: + mov x8, #0 + svc #0 + ret + +.global uart_read +uart_read: + mov x8, #1 + svc #0 + ret + +.global uart_write +uart_write: + mov x8, #2 + svc #0 + ret + +.global exec +exec: + mov x8, #3 + svc #0 + ret + +.global fork +fork: + mov x8, #4 + svc #0 + ret + +.global exit +exit: + mov x8, #5 + svc #0 + ret + +.global mbox_call +mbox_call: + mov x8, #6 + svc #0 + ret + +.global kill +kill: + mov x8, #7 + svc #0 + ret + + diff --git a/lab8/.vscode/c_cpp_properties.json b/lab8/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..9b3b8cfad --- /dev/null +++ b/lab8/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/lab8/.vscode/configurationCache.log b/lab8/.vscode/configurationCache.log new file mode 100644 index 000000000..70686a99f --- /dev/null +++ b/lab8/.vscode/configurationCache.log @@ -0,0 +1 @@ +{"buildTargets":["all","clean","debug","dev","kernel8.img","out","run","screen","sender","super","tty","user/out","usercode.img"],"launchTargets":["/home/yuhu/osc2022/lab8>kernel8.elf()","/home/yuhu/osc2022/lab8>sender()"],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":["/home/yuhu/osc2022/lab8","/home/yuhu/osc2022/lab8/include","/home/yuhu/osc2022/lab8/src"],"compilerArgs":["-o","sender"],"compilerPath":"/usr/bin/g++-11","windowsSdkVersion":""},"fileIndex":[["/home/yuhu/osc2022/lab8/src/panic.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/panic.c","path":"/home/yuhu/osc2022/lab8/src/panic.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/panic.c","-o","out/panic.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/panic.c"}}],["/home/yuhu/osc2022/lab8/src/mmu.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/mmu.c","path":"/home/yuhu/osc2022/lab8/src/mmu.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mmu.c","-o","out/mmu.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/mmu.c"}}],["/home/yuhu/osc2022/lab8/src/getopt.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/getopt.c","path":"/home/yuhu/osc2022/lab8/src/getopt.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/getopt.c","-o","out/getopt.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/getopt.c"}}],["/home/yuhu/osc2022/lab8/src/tmpfs.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/tmpfs.c","path":"/home/yuhu/osc2022/lab8/src/tmpfs.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/tmpfs.c","-o","out/tmpfs.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/tmpfs.c -o out/tmpfs.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/tmpfs.c"}}],["/home/yuhu/osc2022/lab8/src/core_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/core_timer.c","path":"/home/yuhu/osc2022/lab8/src/core_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/core_timer.c","-o","out/core_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/core_timer.c"}}],["/home/yuhu/osc2022/lab8/src/dtb.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/dtb.c","path":"/home/yuhu/osc2022/lab8/src/dtb.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/dtb.c","-o","out/dtb.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/dtb.c"}}],["/home/yuhu/osc2022/lab8/src/mailbox.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/mailbox.c","path":"/home/yuhu/osc2022/lab8/src/mailbox.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mailbox.c","-o","out/mailbox.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/mailbox.c"}}],["/home/yuhu/osc2022/lab8/src/framebuffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/framebuffer.c","path":"/home/yuhu/osc2022/lab8/src/framebuffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/framebuffer.c","-o","out/framebuffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/framebuffer.c -o out/framebuffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/framebuffer.c"}}],["/home/yuhu/osc2022/lab8/src/queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/queue.c","path":"/home/yuhu/osc2022/lab8/src/queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/queue.c","-o","out/queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/queue.c"}}],["/home/yuhu/osc2022/lab8/src/exceptions.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/exceptions.c","path":"/home/yuhu/osc2022/lab8/src/exceptions.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/exceptions.c","-o","out/exceptions.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/exceptions.c"}}],["/home/yuhu/osc2022/lab8/src/vfs.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/vfs.c","path":"/home/yuhu/osc2022/lab8/src/vfs.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/vfs.c","-o","out/vfs.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/vfs.c -o out/vfs.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/vfs.c"}}],["/home/yuhu/osc2022/lab8/src/task.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/task.c","path":"/home/yuhu/osc2022/lab8/src/task.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/task.c","-o","out/task.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/task.c"}}],["/home/yuhu/osc2022/lab8/src/mini_uart.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/mini_uart.c","path":"/home/yuhu/osc2022/lab8/src/mini_uart.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/mini_uart.c","-o","out/mini_uart.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/mini_uart.c"}}],["/home/yuhu/osc2022/lab8/src/math.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/math.c","path":"/home/yuhu/osc2022/lab8/src/math.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/math.c","-o","out/math.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/math.c"}}],["/home/yuhu/osc2022/lab8/src/allocator.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/allocator.c","path":"/home/yuhu/osc2022/lab8/src/allocator.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/allocator.c","-o","out/allocator.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/allocator.c"}}],["/home/yuhu/osc2022/lab8/src/cpio.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/cpio.c","path":"/home/yuhu/osc2022/lab8/src/cpio.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/cpio.c","-o","out/cpio.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/cpio.c"}}],["/home/yuhu/osc2022/lab8/src/local_timer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/local_timer.c","path":"/home/yuhu/osc2022/lab8/src/local_timer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/local_timer.c","-o","out/local_timer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/local_timer.c"}}],["/home/yuhu/osc2022/lab8/src/signal.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/signal.c","path":"/home/yuhu/osc2022/lab8/src/signal.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/signal.c","-o","out/signal.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/signal.c"}}],["/home/yuhu/osc2022/lab8/src/main.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/main.c","path":"/home/yuhu/osc2022/lab8/src/main.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/main.c","-o","out/main.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/main.c"}}],["/home/yuhu/osc2022/lab8/src/shell.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/shell.c","path":"/home/yuhu/osc2022/lab8/src/shell.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/shell.c","-o","out/shell.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/shell.c"}}],["/home/yuhu/osc2022/lab8/src/buffer.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/buffer.c","path":"/home/yuhu/osc2022/lab8/src/buffer.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/buffer.c","-o","out/buffer.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/buffer.c"}}],["/home/yuhu/osc2022/lab8/src/irq2.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/irq2.c","path":"/home/yuhu/osc2022/lab8/src/irq2.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/irq2.c","-o","out/irq2.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/irq2.c"}}],["/home/yuhu/osc2022/lab8/src/priority_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/priority_queue.c","path":"/home/yuhu/osc2022/lab8/src/priority_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/priority_queue.c","-o","out/priority_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/priority_queue.c"}}],["/home/yuhu/osc2022/lab8/src/fat32.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/fat32.c","path":"/home/yuhu/osc2022/lab8/src/fat32.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/fat32.c","-o","out/fat32.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/fat32.c -o out/fat32.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/fat32.c"}}],["/home/yuhu/osc2022/lab8/src/reboot.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/reboot.c","path":"/home/yuhu/osc2022/lab8/src/reboot.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/reboot.c","-o","out/reboot.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/reboot.c"}}],["/home/yuhu/osc2022/lab8/src/loadimg.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/loadimg.c","path":"/home/yuhu/osc2022/lab8/src/loadimg.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/loadimg.c","-o","out/loadimg.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/loadimg.c"}}],["/home/yuhu/osc2022/lab8/src/sd_driver.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/sd_driver.c","path":"/home/yuhu/osc2022/lab8/src/sd_driver.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/sd_driver.c","-o","out/sd_driver.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/sd_driver.c -o out/sd_driver.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/sd_driver.c"}}],["/home/yuhu/osc2022/lab8/src/thread.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/thread.c","path":"/home/yuhu/osc2022/lab8/src/thread.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/thread.c","-o","out/thread.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/thread.c"}}],["/home/yuhu/osc2022/lab8/src/string.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/string.c","path":"/home/yuhu/osc2022/lab8/src/string.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/string.c","-o","out/string.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/string.c"}}],["/home/yuhu/osc2022/lab8/src/sd.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/sd.c","path":"/home/yuhu/osc2022/lab8/src/sd.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/sd.c","-o","out/sd.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/sd.c -o out/sd.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/sd.c"}}],["/home/yuhu/osc2022/lab8/src/interrupt_queue.c",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/src/interrupt_queue.c","path":"/home/yuhu/osc2022/lab8/src/interrupt_queue.c","scheme":"file"},"configuration":{"defines":[],"includePath":["/home/yuhu/osc2022/lab8/include"],"forcedInclude":[],"compilerPath":"/usr/bin/aarch64-linux-gnu-gcc-10","compilerArgs":["-g","-Wall","-c","src/interrupt_queue.c","-o","out/interrupt_queue.o","-fno-stack-protector","-mstrict-align"],"windowsSdkVersion":""},"compileCommand":{"command":"aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/src/interrupt_queue.c"}}],["/home/yuhu/osc2022/lab8/sendfile.cpp",{"uri":{"$mid":1,"fsPath":"/home/yuhu/osc2022/lab8/sendfile.cpp","path":"/home/yuhu/osc2022/lab8/sendfile.cpp","scheme":"file"},"configuration":{"defines":[],"includePath":[],"forcedInclude":[],"compilerPath":"/usr/bin/g++-11","compilerArgs":["-o","sender"],"windowsSdkVersion":""},"compileCommand":{"command":"g++-11 sendfile.cpp -o sender","directory":"/home/yuhu/osc2022/lab8","file":"/home/yuhu/osc2022/lab8/sendfile.cpp"}}]]}} \ No newline at end of file diff --git a/lab8/.vscode/dryrun.log b/lab8/.vscode/dryrun.log new file mode 100644 index 000000000..745802104 --- /dev/null +++ b/lab8/.vscode/dryrun.log @@ -0,0 +1,47 @@ +make --dry-run --always-make --keep-going --print-directory +make: Entering directory '/home/yuhu/osc2022/lab8' +mkdir -p out +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/panic.c -o out/panic.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu.c -o out/mmu.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/getopt.c -o out/getopt.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/tmpfs.c -o out/tmpfs.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/core_timer.c -o out/core_timer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/dtb.c -o out/dtb.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mailbox.c -o out/mailbox.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/framebuffer.c -o out/framebuffer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/queue.c -o out/queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/exceptions.c -o out/exceptions.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/vfs.c -o out/vfs.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/task.c -o out/task.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mini_uart.c -o out/mini_uart.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/math.c -o out/math.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/allocator.c -o out/allocator.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/cpio.c -o out/cpio.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/local_timer.c -o out/local_timer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/signal.c -o out/signal.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/main.c -o out/main.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/shell.c -o out/shell.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/buffer.c -o out/buffer.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq2.c -o out/irq2.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/priority_queue.c -o out/priority_queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/fat32.c -o out/fat32.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/reboot.c -o out/reboot.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/loadimg.c -o out/loadimg.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/sd_driver.c -o out/sd_driver.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/thread.c -o out/thread.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/string.c -o out/string.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/sd.c -o out/sd.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/interrupt_queue.c -o out/interrupt_queue.o -fno-stack-protector -mstrict-align +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/start.S -o out/start.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/timer.S -o out/timer.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/irq.S -o out/irq.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/scheduler.S -o out/scheduler.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/temp.S -o out/temp.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/mmu_asm.S -o out/mmu_asm.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/excep_handler.S -o out/excep_handler.o +aarch64-linux-gnu-gcc-10 -g -Wall -I include -c src/jump.S -o out/jump.o +aarch64-linux-gnu-ld -T src/linker.ld -o kernel8.elf out/panic.o out/mini_uart.o out/core_timer.o out/math.o out/queue.o out/cpio.o out/dtb.o out/task.o out/allocator.o out/framebuffer.o out/exceptions.o out/vfs.o out/main.o out/priority_queue.o out/reboot.o out/sd_driver.o out/thread.o out/string.o out/mailbox.o out/mmu.o out/getopt.o out/loadimg.o out/local_timer.o out/signal.o out/shell.o out/buffer.o out/tmpfs.o out/irq2.o out/fat32.o out/sd.o out/interrupt_queue.o out/timer.o out/temp.o out/start.o out/jump.o out/irq.o out/scheduler.o out/mmu_asm.o out/excep_handler.o +aarch64-linux-gnu-objcopy -O binary kernel8.elf kernel8.img +g++-11 sendfile.cpp -o sender +make: Leaving directory '/home/yuhu/osc2022/lab8' + diff --git a/lab8/.vscode/launch.json b/lab8/.vscode/launch.json new file mode 100644 index 000000000..d90c1acf0 --- /dev/null +++ b/lab8/.vscode/launch.json @@ -0,0 +1,31 @@ +{ + "configurations": [ + { + "name": "C/C++: aarch64-linux-gnu-gcc 建置及偵錯使用中的檔案", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "啟用 gdb 的美化顯示", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "將反組譯碼變體設為 Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: aarch64-linux-gnu-gcc 建置使用中檔案", + "miDebuggerPath": "/usr/bin/gdb" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/lab8/.vscode/settings.json b/lab8/.vscode/settings.json new file mode 100644 index 000000000..fb62553c5 --- /dev/null +++ b/lab8/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "files.associations": { + "uint.h": "c", + "mmu.h": "c", + "mini_uart.h": "c", + "queue.h": "c", + "task.h": "c", + "vfs.h": "c", + "device.h": "c", + "fstream": "c", + "tmpfs.h": "c", + "typeinfo": "c", + "stdio.h": "c", + "cstdio": "c" + }, + "C_Cpp.errorSquiggles": "Disabled" +} \ No newline at end of file diff --git a/lab8/.vscode/targets.log b/lab8/.vscode/targets.log new file mode 100644 index 000000000..4afa8ecb4 --- /dev/null +++ b/lab8/.vscode/targets.log @@ -0,0 +1,657 @@ +make all --print-data-base --no-builtin-variables --no-builtin-rules --question +# GNU Make 4.2.1 +# Built for x86_64-pc-linux-gnu +# Copyright (C) 1988-2016 Free Software Foundation, Inc. +# License GPLv3+: GNU GPL version 3 or later +# This is free software: you are free to change and redistribute it. +# There is NO WARRANTY, to the extent permitted by law. + +# Make data base, printed on Sun Jun 19 16:05:15 2022 + +# Variables + +# automatic +> 3; +__relocation = 0x01080000; +__dtb_addr = 0x02080000; diff --git a/lab8/bootloader/src/loadimg.c b/lab8/bootloader/src/loadimg.c new file mode 100644 index 000000000..14a3b150f --- /dev/null +++ b/lab8/bootloader/src/loadimg.c @@ -0,0 +1,60 @@ +#include "mini_uart.h" +#include "string.h" + +#define byte unsigned char +#define uint32 unsigned int +#define block_size 128 + + +void loadimg(){ + uint32 addr=0x80000; // load to 0x80000 + uart_printf("Start receiving.\n"); + byte SIZE[5]; + byte par=0; + for(int i=0;i<5;i++){ //receive file size + byte temp=uart_read_raw(); + SIZE[i]=temp; + if(i!=4) par ^= temp; + } + if(par != SIZE[4]){ + uart_printf("Receiving error\n"); + return; + } + uint32 size=0; + for(int i=0;i<4;i++){ + size <<= 8; + size += SIZE[i]; + } + byte *kernel = (byte*) addr; + byte check_byte=0; + int j=0; + for(int i=0;i=5){ + uart_printf("Error! Please try again later.\n"); + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(2); + return; + } + uart_printf("Something went wrong. Trying to fix it. %d\n",i/8); + i-=8; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(1); + }else{ + j=0; + check_byte &= 0; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(0); + } + } + } + void (*start_os)(void) = (void *)kernel; //set start_os's addr to the loaded image's addr + uart_printf("Loading Complete.\n"); + uart_printf("Redirecting to 0x%x\n",addr); + start_os(); +} \ No newline at end of file diff --git a/lab8/bootloader/src/mailbox.c b/lab8/bootloader/src/mailbox.c new file mode 100644 index 000000000..c4f7957b7 --- /dev/null +++ b/lab8/bootloader/src/mailbox.c @@ -0,0 +1,85 @@ +#include "mini_uart.h" +#include "mmio.h" +#include "string.h" +typedef unsigned int uint32; +typedef unsigned char byte; + +#define MAILBOX_BASE MMIO_BASE + 0xb880 + +#define MAILBOX_READ (uint32*)(MAILBOX_BASE) +#define MAILBOX_STATUS (uint32*)(MAILBOX_BASE+0x18) +#define MAILBOX_WRITE (uint32*)(MAILBOX_BASE+0x20) + +#define MAILBOX_EMPTY 0x40000000 +#define MAILBOX_FULL 0x80000000 +#define MAILBOX_CODE_BUF_RES_SUCC 0x80000000 +#define MAILBOX_CODE_BUF_REQ 0x00000000 +#define MAILBOX_CODE_TAG_REQ 0x00000000 + +#define GET_ARM_MEMORY 0x00010005 +#define GET_BOARD_REVISION 0x00010002 +#define REQUEST_CODE 0x00000000 +#define REQUEST_SUCCEED 0x80000000 +#define REQUEST_FAILED 0x80000001 +#define TAG_REQUEST_CODE 0x00000000 +#define END_TAG 0x00000000 + +void mailbox_call(uint32 *mailbox,byte channel){ + uint32 r = (uint32)(((unsigned long)mailbox) & (~0xF)) | (channel & 0xF); + while (*MAILBOX_STATUS & MAILBOX_FULL) { + } + *MAILBOX_WRITE = r; + while(1){ + while(*MAILBOX_STATUS & MAILBOX_EMPTY){ + } + + if (r == *MAILBOX_READ){ + return mailbox[1] == MAILBOX_CODE_BUF_RES_SUCC; + } + } + return 0; +} + +void get_board_revision(){ + uint32 __attribute__((aligned(16))) mailbox[7]; + mailbox[0] = 7 * 4; // buffer size in bytes + mailbox[1] = REQUEST_CODE; + // tags begin + mailbox[2] = GET_BOARD_REVISION; // tag identifier + mailbox[3] = 4; // maximum of request and response value buffer's length. + mailbox[4] = TAG_REQUEST_CODE; + mailbox[5] = 0; // value buffer + // tags end + mailbox[6] = END_TAG; + + mailbox_call(mailbox,8); // message passing procedure call, you should implement it following the 6 steps provided above. + char s[11]; + i16toa(mailbox[5],s,8); + uart_printf("Board Revision: 0x"); // it should be 0xa020d3 for rpi3 b+ + uart_printf(s); + uart_printf("\n"); +} + +void get_arm_memory() { + unsigned int __attribute__((aligned(16))) mailbox[8]; + mailbox[0] = 8 * 4; // buffer size in bytes + mailbox[1] = MAILBOX_CODE_BUF_REQ; + // tags begin + mailbox[2] = GET_ARM_MEMORY; // tag identifier + mailbox[3] = 8; // maximum of request and response value buffer's length. + mailbox[4] = MAILBOX_CODE_TAG_REQ; // tag code + mailbox[5] = 0; // base address + mailbox[6] = 0; // size in bytes + mailbox[7] = 0x0; // end tag + // tags end + mailbox_call(mailbox, 8); + uart_printf("ARM memory base addr: 0x"); + char a[11]; + i16toa(mailbox[5],a,8); + uart_printf(a); + uart_printf(" size: 0x"); + char b[11]; + i16toa(mailbox[6],b,8); + uart_printf(b); + uart_printf("\n"); +} diff --git a/lab8/bootloader/src/main.c b/lab8/bootloader/src/main.c new file mode 100644 index 000000000..aea11d56e --- /dev/null +++ b/lab8/bootloader/src/main.c @@ -0,0 +1,18 @@ +#include "mini_uart.h" +#include "shell.h" +#include "mailbox.h" +#include "loadimg.h" +#define max_length 128 + + +int main() { + shell_init(); + uart_printf("Initial completed\n"); + get_board_revision(); + get_arm_memory(); + while (1) { + char input[max_length]; + uart_read_line(input); + check(input); + } +} diff --git a/lab8/bootloader/src/mini_uart.c b/lab8/bootloader/src/mini_uart.c new file mode 100644 index 000000000..17f755b4b --- /dev/null +++ b/lab8/bootloader/src/mini_uart.c @@ -0,0 +1,125 @@ +#include "aux.h" +#include "gpio.h" + +void uart_init() { + /* Initialize UART */ + *AUX_ENABLES |= 1; // Enable mini UART + *AUX_MU_CNTL = 0; // Disable TX, RX during configuration + *AUX_MU_IER = 0; // Disable interrupt + *AUX_MU_LCR = 3; // Set the data size to 8 bit + *AUX_MU_MCR = 0; // Don't need auto flow control + *AUX_MU_BAUD = 270; // Set baud rate to 115200 + *AUX_MU_IIR = 6; // No FIFO + + /* Map UART to GPIO Pins */ + + // 1. Change GPIO 14, 15 to alternate function + register unsigned int r = *GPFSEL1; //gpio10~19 is located GPSEL1 + r &= ~((7 << 12) | (7 << 15)); // Reset GPIO 14, 15 + r |= (2 << 12) | (2 << 15); // Set ALT5 + *GPFSEL1 = r; + + // 2. Disable GPIO pull up/down (Because these GPIO pins use alternate functions, not basic input-output) + // Set control signal to disable + *GPPUD = 0; + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Clock the control signal into the GPIO pads + *GPPUDCLK0 = (1 << 14) | (1 << 15); + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Remove the clock + *GPPUDCLK0 = 0; + + // 3. Enable TX, RX + *AUX_MU_CNTL = 3; +} + +char uart_read() { + // Check data ready field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + // Read + char r = (char)(*AUX_MU_IO); + // Convert carrige return to newline + return r == '\r' ? '\n' : r; +} + +char uart_read_raw() { + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + return (char)(*AUX_MU_IO); +} + +void uart_write(unsigned int c) { + // Check transmitter idle field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x20)); + // Write + *AUX_MU_IO = c; +} + +void uart_printf(char* fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + + while (*fmt) { + if (*fmt == '\n') uart_write('\r'); + else if(*fmt == '%'){ + fmt++; + if(*fmt == 'd'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + itoa(arg,temp); + uart_printf(temp); + }else if(*fmt == 's'){ + char *arg = __builtin_va_arg(args, char*); + uart_printf(arg); + }else if(*fmt == 'x'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + i16toa(arg,temp,8); + uart_printf(temp); + }else if(*fmt == 'c'){ + char *arg = __builtin_va_arg(args, char*); + uart_write(*arg); + } + else if(*fmt++ == 'l'){ + if(*fmt == 'e'){ + unsigned int arg = __builtin_va_arg(args, unsigned int); + unsigned char *t = (unsigned char *) &arg; + for(int i=0;i<4;i++){ + unsigned char temp[3]; + temp[2]='\0'; + i16toa(t[i],temp,2); + uart_printf(temp); + } + }else if(*fmt == 'l'){ + unsigned long long arg = __builtin_va_arg(args, unsigned long long); + unsigned char temp[24]; + itoa(arg, temp); + uart_printf("%s",temp); + } + } + fmt++; + continue; + } + else if(*fmt == '\0') break; + uart_write(*fmt++); + } +} + +void uart_flush() { + while (*AUX_MU_LSR & 0x01) { + *AUX_MU_IO; + } +} \ No newline at end of file diff --git a/lab8/bootloader/src/reboot.c b/lab8/bootloader/src/reboot.c new file mode 100644 index 000000000..a6de4e65a --- /dev/null +++ b/lab8/bootloader/src/reboot.c @@ -0,0 +1,13 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC ((volatile unsigned int*)0x3F10001c) +#define PM_WDOG ((volatile unsigned int*)0x3F100024) + +void reset(int tick){ // reboot after watchdog timer expire + *PM_RSTC = PM_PASSWORD | 0x20; // full reset + *PM_WDOG = PM_PASSWORD | tick; // number of watchdog tick +} + +void cancel_reset() { + *PM_RSTC = PM_PASSWORD | 0; // full reset + *PM_WDOG = PM_PASSWORD | 0; // number of watchdog tick +} \ No newline at end of file diff --git a/lab8/bootloader/src/relocate.c b/lab8/bootloader/src/relocate.c new file mode 100644 index 000000000..ef5e9d6c4 --- /dev/null +++ b/lab8/bootloader/src/relocate.c @@ -0,0 +1,12 @@ +extern unsigned char _begin_, _end_, __relocation; +__attribute__((section(".text.relocator")))void relocate(void){ + unsigned long long length = ( &_end_ - &_begin_); + unsigned char* addr_after = (unsigned char*) &__relocation; + unsigned char* addr_before = (unsigned char*) &_begin_; + for(unsigned int i=0; i0){ + i--; + char t[1]={8}; + fmt[i]='\0'; + uart_printf("%s %s",t,t); + } + continue; + }else if(in == 3){ + for(int j=0;j=32 && in<=126 ){ + fmt[i++]=in; + uart_write(in); + } + } + fmt[i]='\0'; +} + +void check(char *input){ + if(input[0] == '\0' || input[0] == '\n') return; + if(strcmp(input,"help")==1){ + uart_printf("help : print the help menu\n"); + uart_printf("hello : print Hello World!\n"); + uart_printf("reboot : reboot the device\n"); + }else if(strcmp(input,"hello")==1){ + uart_printf("Hello World!\n"); + }else if(strncmp(input,"reboot ",7)==1){ + uart_printf("Rebooting...\n"); + int a=0; + for(int i=7;input[i]<='9' && input[i]>='0';i++){ + a *= 10; + a += (input[i]-'0'); + } + reset(a<50? 50:a); + while(1); + }else if(strcmp(input,"loadimg")){ + uart_printf("loading...\n"); + loadimg(); + }else{ + uart_printf("command not found: %s\n",input); + } +} \ No newline at end of file diff --git a/lab8/bootloader/src/start.S b/lab8/bootloader/src/start.S new file mode 100644 index 000000000..099e3f29d --- /dev/null +++ b/lab8/bootloader/src/start.S @@ -0,0 +1,46 @@ +.section ".text.relocate" + +.global _relocate + +_relocate: + // get cpu id + mrs x1, MPIDR_EL1 + and x1, x1, #3 + cbz x1, 2f + // if cpu_id > 0, stop +1: + wfe + b 1b + // if cpu_id == 0 +2: + // save dtb location + ldr x1, =__dtb_addr + str x0, [x1] + + // set stack pointer + ldr x1, =__relocation + mov sp, x1 + + + // clear bss + ldr x1, =__bss_start + ldr x2, =__bss_size +3: cbz x2, 4f + str xzr, [x1], #8 + sub x2, x2, #1 + cbnz x2, 3b + +4: bl relocate + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl main + // halt this core if return +1: + wfe + b 1b \ No newline at end of file diff --git a/lab8/bootloader/src/string.c b/lab8/bootloader/src/string.c new file mode 100644 index 000000000..4d6e92609 --- /dev/null +++ b/lab8/bootloader/src/string.c @@ -0,0 +1,85 @@ +#include "uint.h" +void itoa(unsigned long long value,char *s) { + int idx = 0; + char tmp[24]; + int tidx = 0; + do { + tmp[tidx++] = '0' + value % 10; + value /= 10; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for (i = tidx - 1; i >= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +void i16toa(unsigned int value, char *s, int digits) { + int idx = 0; + char tmp[11]; + int tidx = 0; + do { + if((value % 16) < 10) + tmp[tidx++] = '0' + value % 16; + else + tmp[tidx++] = 'A' + value % 16 - 10; + value /= 16; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for(int j=0;j= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +int strcmp(char *string1, char *string2){ + while(*string1 && *string2){ + if(*string1!=*string2) return 0; + else{ + string1++; + string2++; + } + } + if(*string1){ + if((*string1>='a' && *string1<='z') || (*string1>='A' && *string1<='Z') || (*string1>='0' && *string1<='9')) + return 0; + else + return 1; + } + if(*string2){ + if((*string2>='a' && *string2<='z') || (*string2>='A' || *string2<='Z') || (*string2>=0 && *string2<=9)) + return 0; + else + return 1; + } + return 1; +} + +int strncmp(char *string1, char *string2, int length){ + char temp1[128],temp2[128]; + for(int i=0;i +#include +#include +#include +#include + +using namespace std; +// Linux headers +#include +#include // Contains file controls like O_RDWR +#include // Error integer and strerror() function +#include // Contains POSIX terminal control definitions +#include // write(), read(), close() + +#define block_size 128 + +void port_setting(int serial_port, struct termios tty){ + + //general setting + tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity + tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication + tty.c_cflag &= ~CSIZE; // Clear all the size bits, then use one of the statements below + tty.c_cflag |= CS8; // 8 bits per byte + tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) + tty.c_lflag &= ~ICANON; //Disable canonial mode. Canonial mode is sending message line by line. + tty.c_lflag &= ~ECHO; // Disable echo + tty.c_lflag &= ~ECHOE; // Disable erasure + tty.c_lflag &= ~ECHONL; // Disable new-line echo + tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP + + //setting input + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes + + //setting output + tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) + tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed + tty.c_cc[VTIME] = 10; // Wait for up to 1s (10 deciseconds), returning as soon as any data is received. + tty.c_cc[VMIN] = 0; + + cfsetspeed(&tty, B115200); //Set baud rate + + if (tcsetattr(serial_port, TCSANOW, &tty) != 0) { + printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); + exit(errno); + } +} + +int main(int argc, char* argv[]){ + if(argc!=3){ + cout<<"Error! Need the port number and file name!"< buffer(std::istreambuf_iterator(file), {}); + uint32_t size=buffer.size(); + unsigned char par_bit=0; + unsigned char SIZE[5]; + //unsigned char command[]={'l','o','a','d','i','m','g','\n'}; + //write(serial_port,command,sizeof(command)); + + for(int i=0;i<4;i++){ + SIZE[3-i] = size%256; + size/=256; + par_bit ^= SIZE[3-i]; + } + SIZE[4]=par_bit; + size=buffer.size(); + write(serial_port, SIZE, sizeof(SIZE)); + + uint32_t now=0; + char check_byte=0; + for(int i=0;i= f1->start && addr <= f1->end){ + break; + } + f1 = f1->next; + } + if(f1 == NULL) return addr; + } +} + +void* getbestfit(int ind){ + int i; + for(i=0;i+ind<=log2(frame_num);i++) + if(frame_list[(int)log2(frame_num)-ind-i] != NULL) + break; + while(i != 0){ + struct FrameArray* tmp=frame_list[(int)log2(frame_num)-ind-i]; + frame_list[(int)log2(frame_num)-ind-i] = (frame_list[(int)log2(frame_num)-ind-i])->next; + unsigned int n= exp2(tmp->val-1); + struct FrameArray* tmp2=&frame_array[tmp->index + n]; + tmp->next = tmp2; + tmp->val -= 1; + tmp2->next = NULL; + tmp2->val = tmp->val; + i--; + frame_list[(int)log2(frame_num)-ind-i] = tmp; + } + + struct FrameArray* tmp = frame_list[(int)log2(frame_num)-ind]; + frame_list[(int)log2(frame_num)-ind] = (frame_list[(int)log2(frame_num)-ind])->next; + tmp->allocatable = 0; + tmp->next = NULL; + return (void*)(base_addr + page_size*tmp->index); +} + +void show_status(){ + int i=0; + uart_printf("0x%x: ",base_addr); + while(i < frame_num){ + if(i != 0) uart_write('|'); + int length = exp2(frame_array[i].val); + char a = frame_array[i].allocatable + '0'; + for(int j=0;j length){ + front = index; + back = index + (int)exp2(length); + }else{ + front = index - (int)exp2(length); + back = index; + } + } + if(frame_array[front].val == frame_array[back].val && frame_array[front].allocatable && frame_array[back].allocatable){ + struct FrameArray *tmp = frame_list[(int)log2(frame_num) - length]; + if(tmp->index == index + (int)exp2(length)){ + frame_list[(int)log2(frame_num) - length] = frame_list[(int)log2(frame_num) - length]->next; + } + else { + int the_removed = index == front? back:front; + while(tmp->next != NULL){ + if(tmp->next->index == the_removed){ + tmp->next = tmp->next->next; + break; + } + } + } + frame_array[front].val += 1; + frame_array[back].val = -1; + merge(front); + }else{ + struct FrameArray *tmp = frame_list[(int)log2(frame_num) - length]; + if(tmp == NULL || tmp->index > index) + frame_list[(int)log2(frame_num) - length] = &(frame_array[index]); + else{ + while(tmp != NULL && tmp->next != NULL){ + if(tmp->next->index > index){ + frame_array[index].next = tmp->next; + tmp->next = &(frame_array[index]); + break; + } + } + if(tmp->next == NULL){ + tmp->next = &(frame_array[index]); + frame_array[index].next =NULL; + } + } + } +} + +void insert_pool(struct mem_frag* f){ + struct mem_frag* tmp = pool; + if(tmp == NULL){ + pool = f; + return; + } + while(tmp->next != NULL) tmp = tmp->next; + tmp->next = f; +} + + +void* malloc(size_t size){ + struct mem_frag* tmp = pool; + if(size != exp2(log2(size))) size = exp2(log2(size) + 1); + while(tmp != NULL){ + if(tmp->size == size && tmp->leave > 0){ + for(int i=0;inum;i++){ + if(tmp->status[i] == 1){ + tmp->status[i] = 0; + void* addr = tmp->start + tmp->size*i; + tmp->leave--; + record_mem(addr); + return addr; + } + } + + } + tmp = tmp->next; + } + int req_page_num; + req_page_num = size%page_size != 0? size/page_size+1 : size/page_size; + req_page_num = exp2(log2(req_page_num)) != req_page_num? exp2(log2(req_page_num) + 1) : req_page_num; + + tmp = simple_malloc(sizeof(struct mem_frag)); + tmp->size = size; + tmp->start = page_alloc(req_page_num); + tmp->num = req_page_num * 4096 / size; + tmp->end = tmp->start + req_page_num * 4096; + tmp->status = simple_malloc(tmp->num); + tmp->leave = tmp->num - 1; + tmp->next = NULL; + insert_pool(tmp); + for(int i=0;inum;i++){ + tmp->status[i] = 1; + } + tmp->status[0] = 0; + void* addr = tmp->start; + record_mem(addr); + uint64_t res = (uint64_t)addr | 0xffff000000000000; + return res; +} + +void pool_status(){ + struct mem_frag* f = pool; + uart_printf("Available pool:\n"); + for(int i=1;f!=NULL;i++){ + uart_printf(" %d: addr: 0x%x size: %d num: %d leave: %d\n",i,f->start,f->size,f->num,f->leave); + f = f->next; + } + struct mem_reserved_pool* f1 = MR_pool; + uart_printf("Reserved pool:\n"); + for(int i=1;f1!=NULL;i++){ + uart_printf(" %d: addr: 0x%x to 0x%x\n",i,f1->start,f1->end); + f1 = f1->next; + } +} + +void free(void* addr){ + struct mem_frag* tmp = pool; + while(tmp != NULL){ + if((uint64)addr < (uint64)tmp->end && (uint64)tmp->start <= (uint64)addr){ + if(tmp->status[(addr-tmp->start)/tmp->size] == 0){ + tmp->leave++; + tmp->status[(addr-tmp->start)/tmp->size] = 1; + } + return; + } + tmp = tmp->next; + } +} + +void clear_pool(){ + while(pool!=NULL){ + page_free(pool->start); + pool = pool->next; + } +} + +void memory_reserve(uint64 start,uint64 end){ + if(end < start) return; + struct mem_reserved_pool *tmp; + tmp = MR_pool; + if(tmp != NULL){ + if(start >= tmp->start && start <= tmp->end){ + if(end > tmp->end){tmp->end = end; + MR_pool = MR_pool->next; + return memory_reserve(tmp->start,tmp->end); + } + return; + }else if(end >= tmp->start && end <= tmp->end){ + tmp->start = start; + MR_pool = MR_pool->next; + return memory_reserve(tmp->start,tmp->end); + } + } + while(tmp != NULL && tmp->next != NULL){ + if(start >= tmp->next->start && start <= tmp->next->end){ + if(end > tmp->next->end){ + tmp->next->end = end; + struct mem_reserved_pool *tmp2 = tmp->next; + tmp->next = tmp2->next; + return memory_reserve(tmp2->start,tmp2->end); + } + return; + }else if(end >= tmp->next->start && end <= tmp->next->end){ + tmp->next->start = start; + struct mem_reserved_pool *tmp2 = tmp->next; + tmp->next = tmp2->next; + return memory_reserve(tmp2->start,tmp2->end); + } + tmp = tmp->next; + } + tmp = simple_malloc(sizeof(struct mem_reserved_pool)); + tmp->start = start; + tmp->end = end; + tmp->next = MR_pool; + MR_pool = tmp; +} \ No newline at end of file diff --git a/lab8/src/buffer.c b/lab8/src/buffer.c new file mode 100644 index 000000000..f07679dce --- /dev/null +++ b/lab8/src/buffer.c @@ -0,0 +1,19 @@ +#include "allocator.h" +#include "buffer.h" + + +int write_buffer(struct buffer *b, unsigned char c){ + if(b->start-1 == b->end || (b->start == buffer_size-1 && b->end == 0)) return 0; + b->buf[b->end++] = c; + if(b->end == buffer_size) b->end=0; + return 1; +} + +int read_buffer(struct buffer *b, unsigned char* output){ + if(b->start == b->end) return 0; + *output = b->buf[b->start]; + b->buf[b->start++] = 0; + if(b->start == buffer_size) b->start=0; + return 1; +} + diff --git a/lab8/src/core_timer.c b/lab8/src/core_timer.c new file mode 100644 index 000000000..315cbb815 --- /dev/null +++ b/lab8/src/core_timer.c @@ -0,0 +1,80 @@ +#include "mini_uart.h" +#include "uint.h" +#include "priority_queue.h" +#include "queue.h" +#include "scheduler.h" +#include "task.h" + +uint64 freq_thread = 31; + +void core_timer_init(){ + uint64 tmp; + asm volatile("mrs %0, cntkctl_el1" : "=r"(tmp)); + tmp |= 1; + asm volatile("msr cntkctl_el1, %0" : : "r"(tmp)); + core_timer_disable(); +} + +void arm_core_timer_intr_handler() { + core_timer_handler(); +} + +void core_timer_handler(){ + struct node* node = delete_first_node(); + if(node->next == NULL){ + asm volatile("mrs x0, cntfrq_el0\n" + "ldr x1, =10\n" + "mul x0, x0, x1\n" + "msr cntp_tval_el0, x0\n"); + core_timer_disable(); + }else{ + core_timer_enable(); + uint64 interval = node->next->time_to_ring; + asm volatile("msr cntp_tval_el0, %[output0]\n" + ::[output0] "r" (interval)); + } + free(node); + node->todo(node->arguments); +} + +void add_timer(void (*callback_f)(void*),void *argu_for_call,int times){ + uint64 clock_hz,now_time,interval; + asm volatile("mrs %[input0], cntfrq_el0\n" + "mrs %[input2], cntp_tval_el0\n" + :[input0] "=r" (clock_hz), + [input2] "=r" (interval)); + uint64 time_to_ring = add_node(callback_f, argu_for_call, clock_hz / 1000 * times, interval); + core_timer_enable(); + asm volatile("msr cntp_tval_el0, %[output0]\n" + ::[output0] "r" (time_to_ring)); +} + +void *wakeup(void *p){ + uart_printf("Timeout!!\n"); +} + +void sleep(int duration){ + add_timer(wakeup,NULL,duration); + uart_printf("Timer is set...\n"); +} + +void delay(int duration){ + irq_disable(); + void *argu = get_current(); + add_timer(wakeup_queue,argu,duration); + irq_enable(); + schedule(); +} + +void thread_timer_handler(){ + void *t = get_current(); + struct thread *s = t; + PushToReadyList(s->tid); + thread_timer(); + task_schedule(t); +} + +void thread_timer(){ + while(delete_first_node() != NULL); + add_timer(thread_timer_handler,NULL,freq_thread); +} diff --git a/lab8/src/cpio.c b/lab8/src/cpio.c new file mode 100644 index 000000000..17d93b7fd --- /dev/null +++ b/lab8/src/cpio.c @@ -0,0 +1,332 @@ +#include "uint.h" +#include "mini_uart.h" +#include "string.h" +#include "excep.h" +#include "thread.h" +#include "queue.h" +#include "scheduler.h" +#include "task.h" +#include "mmu.h" +#include "vfs.h" +#include "cpio.h" +#include "list.h" +extern uint64_t cpio_start; +struct file_operations *cpio_fops; +struct vnode_operations *cpio_vops; +struct vnode* cpio_root = NULL; + +typedef struct cpio_newc_header { //cpio new ascii struct + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}CPIO_H ; + +struct vnode* cpio_create_node(const char *name,const char mode, size_t size,const char *internal){ + struct vnode* new_node = allo_vnode(); + strcpy(name,new_node->dt,32); + new_node->f_ops = cpio_fops; + new_node->v_ops = cpio_vops; + new_node->size = size; + new_node->internal = internal; + + new_node->dt->vnode = new_node; + if(mode == '4'){ + new_node->dt->type = directory; + new_node->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + new_node->dt->childs->next = NULL; + struct dentry *tmpchild = allo_dentry(); + tmpchild->name[0] = '.'; + tmpchild->name[1] = 0; + tmpchild->type = directory; + tmpchild->vnode = new_node; + tmpchild->childs = new_node->dt->childs; + new_node->dt->childs->entry = tmpchild; + }else{ + new_node->dt->type = file; + new_node->dt->vnode = new_node; + } + return new_node; +} + +void traverse_cpio(struct vnode* root){ // proceed ls + uint64_t addr = cpio_start; + CPIO_H *cpio=(CPIO_H*) addr; + while(strncmp(cpio->c_magic,"070701\0",6)==1){ //c_magic is always "070701" + struct vnode* parent = root; + int namesize=a16ntoi(cpio->c_namesize, 8); + char *name=(char*)(cpio+1); + char temp[128]; + memset(temp,0,128); + for(int i=0,j=0;ic_filesize, 8); + + + if(temp[0]!='.'){ + struct vnode* new_node = cpio_create_node(temp,cpio->c_mode[4],filesize,addr+110+namesize); + if(cpio->c_mode[4] == '4'){ + new_node->dt->parent = parent->dt; + struct link_list* parent_list = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_list->next = new_node->dt->childs->next; + new_node->dt->childs->next = parent_list; + struct dentry* parent_dentry = allo_dentry(); + strcpy("..\0",parent_dentry->name,32); + parent_dentry->type = directory; + parent_dentry->vnode = parent; + parent_dentry->parent = parent->dt->parent; + parent_dentry->childs = parent->dt->childs; + parent_list->entry = parent_dentry; + } + struct link_list* ll = parent->dt->childs; + //uart_printf("%s\n%s\n",parent->dt->name,new_node->dt->name); + while(ll->next != NULL) ll = ll->next; + ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + ll->next->entry = new_node->dt; + ll->next->next = NULL; + //uart_printf("13"); + } + int sum=110+namesize+filesize; + if(sum%4 != 0){ + sum/=4; + sum*=4; + sum+=4; + } + addr+=sum; // padding is included in namesize and filesize + + cpio=(CPIO_H*) addr; + } +} + +uint64_t find_file_addr(char *file_name){ + uint64_t addr = cpio_start; + CPIO_H *cpio=(CPIO_H*) addr; + while(strncmp(cpio->c_magic,"070701\0",6)==1){ + int namesize=a16ntoi(cpio->c_namesize, 8); + char *name=(char*)(cpio+1); + char temp[128]; + for(int i=0;ic_filesize, 8); + if(strcmp(file_name, temp)){ + return addr; + } + int sum=110+namesize+filesize; + if(sum%4 != 0){ + sum/=4; + sum*=4; + sum+=4; + } + addr+=sum; // padding is included in namesize and filesize + cpio=(CPIO_H*) addr; + } + return NULL; +} + +void* getContent(uint64_t addr,int *length){ + CPIO_H *cpio=(CPIO_H*) addr; + int namesize=a16ntoi(cpio->c_namesize, 8); + int filesize=a16ntoi(cpio->c_filesize, 8); + addr += (110+namesize); + *length = filesize; + return addr; +} + +void print_content(char *file){ + uint64_t f_addr=find_file_addr(file); + if(f_addr != NULL){ + int length; + char *content_addr = getContent(f_addr, &length); + while(length--){ + if(*content_addr == '\n') uart_write('\r'); + uart_write(*content_addr++); + } + return; + }else{ + uart_printf("Not found file \"%s\"\n",file); + return; + } +} + +void copy_content(char *file,void **addr, uint64_t *size){ + struct vnode *tmp; + vfs_lookup(file,&tmp); + if(tmp != NULL){ + if(tmp->dt->type == directory){ + *addr = NULL; + return; + } + int length = tmp->size; + uint64_t address = tmp->internal; + if(address%4 != 0){ + address /= 4; + address *= 4; + address += 4; + } + void * start = malloc(length); + move_last_mem(0); + byte *ucode = (uint64)start; + byte *file = address; + for(int i=0;icreate = cpio_perm_denied; + cpio_vops->mkdir = cpio_perm_denied; + cpio_vops->lookup = cpio_lookup; + cpio_vops->mknod = cpio_perm_denied; + cpio_fops->write = cpio_perm_denied; + cpio_fops->close = cpio_close; + cpio_fops->lseek64 = cpio_lseek64; + cpio_fops->open = cpio_open; + cpio_fops->read = cpio_read; + + struct filesystem *fs = malloc(sizeof(struct filesystem)); + delete_last_mem(); + fs->name = malloc(16); + delete_last_mem(); + memset(fs->name,0,16); + strcpy("initramfs\0",fs->name,10); + fs->setup_mount = cpio_mount; + register_filesystem(fs); + vfs_mount("/initramfs\0","initramfs\0"); + struct vnode* tmp; + vfs_lookup("/initramfs\0",&tmp); +} + +int cpio_mount(struct filesystem* fs, struct mount* mount){ + if(cpio_root == NULL){ + cpio_root = allo_vnode(); + cpio_root->mount = NULL; + cpio_root->size = 0x400; + cpio_root->f_ops = cpio_fops;; + cpio_root->v_ops = cpio_vops; + cpio_root->internal = NULL; + + struct dentry *tmp_child = allo_dentry(); + struct dentry *tmp_parent = mount->root->dt->childs->next->entry; + + strcpy(mount->root->dt->name[0],cpio_root->dt->name,256); + cpio_root->dt->type = directory; + cpio_root->dt->vnode = cpio_root; + cpio_root->dt->parent = cpio_root->dt; + cpio_root->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + cpio_root->dt->childs->entry = tmp_child; + cpio_root->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + cpio_root->dt->childs->next->entry = tmp_parent; + cpio_root->dt->childs->next->next= NULL; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->parent = cpio_root->dt; + tmp_child->childs = cpio_root->dt->childs; + tmp_child->type = directory; + tmp_child->vnode = cpio_root; + + } + mount->root = cpio_root; + traverse_cpio(cpio_root); + struct link_list* ll = cpio_root->dt->childs; +} + +int cpio_perm_denied(){ + uart_printf("Error: Read only file\n"); + return -1; +} + +int cpio_lookup(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct link_list* tmp = dir_node->dt->childs; + while(tmp != NULL){ + struct dentry* den_tmp = tmp->entry; + if(strcmp(den_tmp->name,component_name)){ + *target = den_tmp->vnode; + return 0; + } + tmp = tmp->next; + } + *target = NULL; + return -1; +} + +int cpio_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +int cpio_read(struct file* file, void* buf, size_t len){ + uint64_t address = file->vnode->internal; + char *internal, *tmp = buf; + if(address%4 != 0){ + address /= 4; + address *= 4; + address += 4; + } + internal = address; + for(int i=0;if_pos++]; + } + return len; +} + +int cpio_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = cpio_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +long cpio_lseek64(struct file* file, long offset, int whence){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} \ No newline at end of file diff --git a/lab8/src/dtb.c b/lab8/src/dtb.c new file mode 100644 index 000000000..4d1b20516 --- /dev/null +++ b/lab8/src/dtb.c @@ -0,0 +1,347 @@ +#include "uint.h" +#include "dtb.h" +#include "fdt.h" +#include "mini_uart.h" +#include "string.h" +#include "allocator.h" + +extern byte __dtb_addr; + +int acceptable_word(char con){ + if(((con >= 'A' && con<='Z') || (con >= 'a' && con <= 'z') || (con >= '0' || con <= '9') || con == '.' || con == '/')) return 1; + else return 0; +} + +void *find_property_value(char* device_name, char* property_name){ + device_tree_node *node; + node = initramfs_callback(device_name); + device_prop *prop = node->property; + uint32 *p = prop->prop_content.prop_name; + while( *p != 0){ + if(strcmp(property_name, prop->prop_content.prop_name)==1){ + return prop->prop_content.prop_value; + } + prop= prop->next; + p=prop->prop_content.prop_name; + } + uart_printf("Error! Device or Property not found.\n"); + return (void*)0; +} + +void print_properties(device_prop* node, int level){ + uint32 *p = (uint32*) (node->prop_content).prop_name; + for(int i=0;iprop_content).prop_name); + if(strcmp(node->prop_content.prop_name,"compatible\0")){ + uart_write(34); + int is_bottom=0; + for(int i=0;ilen;i++){ + if(node->prop_content.prop_value[i]!='\0'){ + if(is_bottom==1){ + uart_printf(",\""); + is_bottom=0; + } + uart_write(node->prop_content.prop_value[i]); + }else{ + uart_printf("\""); + is_bottom=1; + } + } + uart_printf("\n"); + }else if(strcmp(node->prop_content.prop_name,"model\0") || + strcmp(node->prop_content.prop_name,"status\0") || + strcmp(node->prop_content.prop_name,"name\0") || + strcmp(node->prop_content.prop_name,"device_type\0")){ + uart_printf("\"%s\"\n",node->prop_content.prop_value); + }else if(strcmp(node->prop_content.prop_name,"phandle\0") || + strcmp(node->prop_content.prop_name,"#address-cells\0") || + strcmp(node->prop_content.prop_name,"#size-cells\0") || + strcmp(node->prop_content.prop_name,"virtual-reg\0")){ + uint32 *temp = node->prop_content.prop_value; + int value=letobe(*temp); + if(strcmp(node->prop_content.prop_name,"#address-cells\0")) address_cells=value; + else if(strcmp(node->prop_content.prop_name,"#size-cells\0")) size_cells=value; + uart_printf("<%d>\n",value); + }else if(strcmp(node->prop_content.prop_name,"reg\0")){ + uart_printf("<"); + uint32 *temp = node->prop_content.prop_value; + for(int i=0;ilen;){ + if(address_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + i+=4; + }else if(address_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + i+=8; + } + if(i>=node->len) break; + if(size_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + i+=4; + }else if(size_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + i+=8; + } + } + uart_printf(" >\n"); + }else if(strcmp(node->prop_content.prop_name,"ranges\0") || + strcmp(node->prop_content.prop_name,"dma-ranges\0")){ + if(node->len != 0){ + uart_printf("<"); + uint32 *temp = node->prop_content.prop_value; + if(address_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x 0x%x", letobe(*temp2),letobe(*(temp2+1))); + temp+=2; + }else if(address_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x %x 0x%x %x", letobe(temp2[0]),letobe(temp2[1]),letobe(temp2[3]),letobe(temp2[4])); + temp+=4; + } + + if(size_cells == 1){ + uint32 *temp2 = temp; + uart_printf(" 0x%x", letobe(*temp2)); + temp++; + }else if(size_cells == 2){ + uint32 *temp2 = temp; + uart_printf(" 0x%x%x", letobe(temp2[0]),letobe(temp2[1])); + temp+=2; + } + uart_printf(" >\n"); + }else uart_printf("\n"); + }else if(strcmp(node->prop_content.prop_name,"interrupts\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<0x%x %d>\n",letobe(temp[0]),letobe(temp[1])); + }else if(strcmp(node->prop_content.prop_name,"interrupt-parent\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"interrupts-extended\0")){ + uint32 *temp=node->prop_content.prop_value; + //uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"interrupt-cells\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("<%d>\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"linux,initrd-end\0") || + strcmp(node->prop_content.prop_name,"linux,serial\0") || + strcmp(node->prop_content.prop_name,"linux,initrd-start\0") || + strcmp(node->prop_content.prop_name,"linux,revision\0")){ + uint32 *temp=node->prop_content.prop_value; + uart_printf("0x%x\n",letobe(temp[0])); + }else if(strcmp(node->prop_content.prop_name,"size\0") || + strcmp(node->prop_content.prop_name,"clock-frequency\0") || + strcmp(node->prop_content.prop_name,"timebase-frequency\0")){ + uint32 *temp=node->prop_content.prop_value; + if(size_cells == 1) + uart_printf("<0x%x>\n",letobe(temp[0])); + else if(size_cells == 2) + uart_printf("<0x%x %x>\n",letobe(temp[0]),letobe(temp[1])); + }else{ + if(node->len == 0 ){ + char temp[4]={8,8,' ','\0'}; + uart_printf("%s\n",temp); + } + else{ + char *temp2=node->prop_content.prop_value; + if(acceptable_word(temp2[0]) && acceptable_word(temp2[1])){ + uart_printf("\"%s\"\n",temp2); + }else{ + uart_printf("0x"); + uint32 *temp = node->prop_content.prop_value; + int t=node->len%4==0? node->len/4 : node->len/4+1; + for(int j=0;jnext; + p=(uint32*) (node->prop_content).prop_name; + } +} + + +void traverse_tree(char* start,int level){ //print start's properties and its sub_device's properties + device_tree_node *node; + node = initramfs_callback(start); + sub_device *now = node->sd; + + for(int i=0;idevice_name); + print_properties(node->property,level+1); + uint32 *n = (uint32*) now->name; + while(*n!=0){ + char next[128]; + int j; + for(j=0;j<128;j++){ + next[j] = start[j]; + if(start[j] == '\0') break; + } + if(start[j-1] != '/'){ + next[j++]='/'; + next[j]='\0'; + } + for(int k=0;k<128;k++){ + next[k+j] = now->name[k]; + if(now->name[k] == '\0') break; + } + traverse_tree(next, level+1); + now=now->next; + n=(uint32*) now->name; + + } + return; +} + +device_tree_node* initramfs_callback(char* path){ //looking for device + uint32* addr = (uint32*) &__dtb_addr; + device_tree_node *node = simple_malloc(sizeof(device_tree_node)); + sub_device *temp_node=simple_malloc(sizeof(sub_device)); + device_prop* temp_prop=simple_malloc(sizeof(device_prop)); + node->property = temp_prop; + node->sd=temp_node; + for(int i=0;i<4;i++){ + (temp_node->name)[i]=0; + ((temp_prop->prop_content).prop_name)[i]=0; + } + if(path[0] != '/'){ + uart_printf("Device not fount: %s\n", path); + return node; + }else{ + fdt_header *fh=(fdt_header*)(*addr); + uint32* struct_addr = (uint32*) (*addr + letobe(fh->off_dt_struct)); + uint32* string_addr = (uint32*) (*addr + letobe(fh->off_dt_strings)); + int now=0,level=0; + char name[128]; + while(path[now++] != '\0' && path[now] != '\0'){ + int i=0; + for(i=0;path[now+i]!='\0' && path[now+i]!='/';i++){ + name[i]=path[now+i]; + } + now+=i; + name[i]='\0'; + while(1){ + int struct_block=letobe(*struct_addr++); + if(struct_addr >= string_addr){ + uart_printf("Device not found: %s\n",path); + return node; + } + if(struct_block == 1){ + if(level == 1){ + char device_name[128]; + char *temp = (char*) (struct_addr); + int j; + for(j=0;temp[j]!=0;j++){ + device_name[j]=temp[j]; + } + device_name[j]='\0'; + + if(strcmp(device_name, name)){ + break; + }else{ + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + }else{ + char *temp = (char*) (struct_addr); + int j; + for(j=0;temp[j]!=0;j++); + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + level++; + }else if(struct_block == 2){ + level--; + if(level == 0){ + uart_printf("Device not found: %s\n",path); + return node; + } + }else if(struct_block == 3){ + FDT_PROP *pro = (FDT_PROP*) struct_addr; + uint32 len = letobe(pro->len)%4==0? letobe(pro->len)/4 : letobe(pro->len)/4+1; + struct_addr += ( 2 + len); + }else if(struct_block == 9){ + uart_printf("Device not found: %s\n",path); + return node; + } + } + } + if(now-1<=1) strcpy("/\0", node->device_name, 1); + else strcpy(path,node->device_name,now-1); + level=0; + struct_addr--; + while(1){ + if(struct_addr >= string_addr) return node; + int struct_block=letobe(*struct_addr++); + if(struct_block == 1){ + if(level == 1){ + char device_name[128]; + char *temp = (char*) (struct_addr); + int j=0; + for(j=0;temp[j]!=0;j++){ + device_name[j]=temp[j]; + } + device_name[j]='\0'; + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + strcpy(device_name,temp_node->name,j); + sub_device *node_t=simple_malloc(sizeof(sub_device)); + for(int l=0;l<4;l++){ + node_t->name[l]=0; + } + temp_node->next=node_t; + temp_node=node_t; + + }else{ + char *temp = (char*) (struct_addr); + int j=0; + for(;temp[j]!=0;j++); + struct_addr += ( j%4 ==0 ? j/4:j/4+1); + } + level++; + }else if(struct_block == 2){ + level--; + if(level == 0){ + return node; + } + }else if(struct_block == 3){ + if(level == 1){ + char* name = (char*)string_addr + letobe(struct_addr[1]); + device_prop *prop = simple_malloc(sizeof(device_prop)); + int l=0; + for(l=0;name[l] != 0; l++){ + (temp_prop->prop_content).prop_name[l]=name[l]; + } + (temp_prop->prop_content).prop_name[l]='\0'; + char *t=&(struct_addr[2]); + for(l=0;lprop_content).prop_value[l]=t[l]; + } + (temp_prop->prop_content).prop_value[l]='\0'; + temp_prop->len=letobe(struct_addr[0]); + for(l=0;l<4;l++) (prop->prop_content).prop_name[l]='\0'; + temp_prop->next=prop; + temp_prop=prop; + } + uint32 len = letobe(struct_addr[0])%4==0? letobe(struct_addr[0])/4 : letobe(struct_addr[0])/4+1; + struct_addr += ( 2 + len); + }else if(struct_block == 9){ + return node; + } + } + + } + +} + diff --git a/lab8/src/excep_handler.S b/lab8/src/excep_handler.S new file mode 100644 index 000000000..7fdb9ba36 --- /dev/null +++ b/lab8/src/excep_handler.S @@ -0,0 +1,151 @@ +// save general registers to stack +.macro save_all + sub sp, sp, #0x110 + stp x0, x1, [sp ,16 * 0] + stp x2, x3, [sp ,16 * 1] + stp x4, x5, [sp ,16 * 2] + stp x6, x7, [sp ,16 * 3] + stp x8, x9, [sp ,16 * 4] + stp x10, x11, [sp ,16 * 5] + stp x12, x13, [sp ,16 * 6] + stp x14, x15, [sp ,16 * 7] + stp x16, x17, [sp ,16 * 8] + stp x18, x19, [sp ,16 * 9] + stp x20, x21, [sp ,16 * 10] + stp x22, x23, [sp ,16 * 11] + stp x24, x25, [sp ,16 * 12] + stp x26, x27, [sp ,16 * 13] + stp x28, x29, [sp ,16 * 14] + str x30, [sp, 16 * 15] + + mrs x0, sp_el0 + str x0, [sp, 16 * 15 + 8] + mrs x0, spsr_el1 + mrs x1, elr_el1 + stp x0, x1, [sp ,16 * 16] +.endm + +// load general registers from stack +.macro load_all + + ldp x0, x1, [sp ,16 * 16] + msr spsr_el1, x0 + msr elr_el1, x1 + + ldr x0, [sp, 16 * 15 + 8] + msr sp_el0, x0 + + ldp x0, x1, [sp ,16 * 0] + ldp x2, x3, [sp ,16 * 1] + ldp x4, x5, [sp ,16 * 2] + ldp x6, x7, [sp ,16 * 3] + ldp x8, x9, [sp ,16 * 4] + ldp x10, x11, [sp ,16 * 5] + ldp x12, x13, [sp ,16 * 6] + ldp x14, x15, [sp ,16 * 7] + ldp x16, x17, [sp ,16 * 8] + ldp x18, x19, [sp ,16 * 9] + ldp x20, x21, [sp ,16 * 10] + ldp x22, x23, [sp ,16 * 11] + ldp x24, x25, [sp ,16 * 12] + ldp x26, x27, [sp ,16 * 13] + ldp x28, x29, [sp ,16 * 14] + ldr x30, [sp, 16 * 15] + + add sp, sp, #0x110 +.endm + +.macro exception_handler type + save_all + mov x0, #\type + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mov x4, sp + bl exception_entry + load_all + eret +.endm + +.align 11 // vector table should be aligned to 0x800 +.global exception_table +exception_table: + b sync_1// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_1 + .align 7 + b fir_1 + .align 7 + b serror_1 + .align 7 + + b sync_2// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_2 + .align 7 + b fir_2 + .align 7 + b serror_2 + .align 7 + + b sync_3// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_3 + .align 7 + b fir_3 + .align 7 + b serror_3 + .align 7 + + b sync_4// branch to a handler function. + .align 7 // entry size is 0x80, .align will pad 0 + b irq_4 + .align 7 + b fir_4 + .align 7 + b serror_4 + .align 7 + +sync_1: + exception_handler 0 +irq_1: + exception_handler 1 +fir_1: + exception_handler 2 +serror_1: + exception_handler 3 + +sync_2: + exception_handler 4 +irq_2: + exception_handler 5 +fir_2: + exception_handler 6 +serror_2: + exception_handler 7 + +sync_3: + exception_handler 8 +irq_3: + exception_handler 9 +fir_3: + exception_handler 10 +serror_3: + exception_handler 11 + +sync_4: + exception_handler 12 +irq_4: + exception_handler 13 +fir_4: + exception_handler 14 +serror_4: + exception_handler 15 + +.global err_han +err_han: b err_han + +.global return_to_child +return_to_child: + load_all + eret diff --git a/lab8/src/exceptions.c b/lab8/src/exceptions.c new file mode 100644 index 000000000..3a71e47db --- /dev/null +++ b/lab8/src/exceptions.c @@ -0,0 +1,288 @@ +#include "mini_uart.h" +#include "irq.h" +#include "peripheral/irq.h" +#include "timer.h" +#include "interrupt_queue.h" +#include "reboot.h" +#include "thread.h" +#include "cpio.h" +#include "mailbox.h" +#include "queue.h" +#include "task.h" +#include "mmu.h" +#include "vfs.h" +#include "scheduler.h" + +#define uart_puts uart_printf + + +void exception_entry(unsigned long type, unsigned long esr, unsigned long elr, unsigned long spsr, void* sp_addr) +{ + // print out interruption type + switch(type%4) { + case 0: + { + if(esr>>26 == 0b010101){ + asm volatile("msr DAIFClr, 0xf\n"); + struct trapframe *tf = sp_addr; + switch(tf->x[8]){ + case 0: + tf->x[0] = getpid(); + return; + break; + case 1:{ + char *buf = tf->x[0], temp[256]; + int rn = 0; + while(1){ + temp[0] = 0; + uart_pop(temp); + for(int i=0;i<256;i++){ + if(temp[i] == 0) break; + buf[rn++] = temp[i]; + if(rn >= tf->x[1]){ + tf->x[0] = tf->x[1]; + return; + } + } + } + return; + break; + } + case 2:{ + char *buf = tf->x[0]; + for(int i=0;ix[1];i++){ + uart_write(buf[i]); + } + tf->x[0] = tf->x[1]; + return; + break; + } + case 3: + exec(tf->x[0],tf->x[1]); + return; + break; + case 4: + irq_disable(); + tf->x[0] = set_fork(sp_addr); + irq_enable(); + return; + break; + case 5: + UserExit(); + break; + case 6:{ + uint32_t* mbox = malloc(*(uint32_t*)(tf->x[1])); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + uint32_t tr = *((uint32_t*)(tf->x[1]) + i); + mbox[i] = tr; + } + unsigned char channel = tf->x[0]; + mailbox_call(mbox,channel); + for(int i=0;i<*(uint32_t*)(tf->x[1]) / 4;i++){ + *((uint32_t*)(tf->x[1]) + i) = mbox[i]; + } + free(mbox); + return; + break; + } + case 7: + UserKill(tf->x[0]); + return; + break; + case 8: + signal(tf->x[0],tf->x[1]); + return; + break; + case 9: + sentSignal(tf->x[0],tf->x[1]); + return; + break; + case 10: + tf->x[0] = mmap_set(tf->x[0],tf->x[1],tf->x[2],tf->x[3]); + return; + break; + case 11:{ //file open + //uart_printf("11\n"); + void* vnode; + int errno; + if((errno = vfs_open(tf->x[0],tf->x[1],&vnode)) < 0){ + uart_printf("File not found: %s\n",tf->x[0]); + tf->x[0] = errno; + return; + } + struct thread *t = get_current(); + for(int i=0;i<65536;i++){ + if(t->fd[i] == NULL){ + t->fd[i] = vnode; + tf->x[0] = i; + return; + } + } + tf->x[0] = -1; + return; + break; + }case 12:{ //file close + //uart_printf("12\n"); + struct thread *t = get_current(); + int fd = tf->x[0]; + tf->x[0] = vfs_close(t->fd[tf->x[0]]); + if(tf->x[0]>=0) t->fd[fd] = NULL; + return; + break; + }case 13:{ //file write + //uart_printf("13\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_write(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + break; + }case 14:{ //file read + //uart_printf("14\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_read(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + break; + }case 15:{ //mkdir + //uart_printf("15\n"); + struct thread *t = get_current(); + tf->x[0] = vfs_mkdir(tf->x[0]); + return; + break; + }case 16:{ //mount + //uart_printf("16\n"); + tf->x[0] = vfs_mount(tf->x[1],tf->x[2]); + return; + break; + }case 17:{ //chdir + //uart_printf("17\n"); + void *vnode; + tf->x[0] = vfs_lookup(tf->x[0], &vnode); + if(tf->x[0] >= 0){ + struct thread *t = get_current(); + t->CurWorkDir = vnode; + } + return; + break; + }case 18:{ //long lseek64(int fd, long offset, int whence); + //uart_printf("18\n"); + struct thread *t = get_current(); + vfs_lseek(t->fd[tf->x[0]],tf->x[1],tf->x[2]); + return; + }case 19:{ //int ioctl(int fd, unsigned long request, ...); + //uart_printf("19\n"); + struct thread *t = get_current(); + struct file* file = t->fd[tf->x[0]]; + if(file == NULL){ + tf->x[0] = -1; + return; + } + tf->x[0] = file->vnode->v_ops->ioctl(file,tf->x[1],tf->x[2]); + return; + }case 20:{ + tf->x[0] = vfs_sync(); + return; + }case 100: + ret_to_sig_han(sp_addr + 0x110); + return; + break; + default: + uart_printf("%d ",tf->x[8]); + break; + } + }else if(esr>>26==0b100100 || esr>>26==0b100101){ + uint64_t far; + asm volatile("mrs %[input0],far_el1\n" + : [input0] "=r" (far)); + // For Translation fault + uart_printf("[Translation fault]: 0x%x %x\n", far>>32, far); + if(!mmap_check(far)){ + // For Segmentation fault + struct thread *t = get_current(); + uart_printf("[Segmentation fault]: Kill Process %d\n",t->tid); + asm volatile("msr DAIFClr, 0xf\n"); + UserExit(); + } + return; + } + uart_puts("Synchronous"); + break; + } + case 1: + if(handle_irq()){ + asm volatile("msr DAIFClr, 0xf\n"); + exe_first_task(); + return; + } + uart_puts("IRQ"); + break; + case 2: uart_puts("FIQ"); break; + case 3: uart_puts("SError"); break; + } + uart_puts(": "); + // decode exception type (some, not all. See ARM DDI0487B_b chapter D10.2.28) + switch(esr>>26) { + case 0b000000: uart_puts("Unknown"); break; + case 0b000001: uart_puts("Trapped WFI/WFE"); break; + case 0b001110: uart_puts("Illegal execution"); break; + case 0b010101: uart_puts("System call"); break; + case 0b100000: uart_puts("Instruction abort, lower EL"); break; + case 0b100001: uart_puts("Instruction abort, same EL"); break; + case 0b100010: uart_puts("Instruction alignment fault"); break; + case 0b100100: uart_puts("Data abort, lower EL"); break; + case 0b100101: uart_puts("Data abort, same EL"); break; + case 0b100110: uart_puts("Stack alignment fault"); break; + case 0b101100: uart_puts("Floating point"); break; + default: uart_puts("Unknown"); break; + } + // decode data abort cause + if(esr>>26==0b100100 || esr>>26==0b100101) { + uart_puts(", "); + switch((esr>>2)&0x3) { + case 0: uart_puts("Address size fault"); break; + case 1: uart_puts("Translation fault"); break; + case 2: uart_puts("Access flag fault"); break; + case 3: uart_puts("Permission fault"); break; + } + switch(esr&0x3) { + case 0: uart_puts(" at level 0"); break; + case 1: uart_puts(" at level 1"); break; + case 2: uart_puts(" at level 2"); break; + case 3: uart_puts(" at level 3"); break; + } + } + + int ec = (esr >> 26) & 0b111111; + int iss = esr & 0x1FFFFFF; + int cntfrq_el0,cntpct_el0; + // system call + if (ec == 0b010101) { + switch (iss) { + case 1: + uart_printf("Exception return address 0x%x\n", elr); + uart_printf("Exception class (EC) 0x%x\n", ec); + uart_printf("Instruction specific syndrome (ISS) 0x%x\n", iss); + break; + case 2: + core_timer_enable(); + break; + case 3: + core_timer_disable(); + break; + case 4: + asm volatile ("mrs %0, cntfrq_el0" : "=r" (cntfrq_el0)); // get current counter frequency + asm volatile ("mrs %0, cntpct_el0" : "=r" (cntpct_el0)); // read current counter + break; + } + } + // dump registers + uart_puts(":\n ESR_EL1 "); + uart_printf("0x%x ",esr>>32); + uart_printf("0x%x",esr); + uart_puts("\n ELR_EL1 "); + uart_printf("0x%x ",elr>>32); + uart_printf("0x%x",elr); + uart_puts("\n SPSR_EL1 "); + uart_printf("0x%x ",spsr>>32); + uart_printf("0x%x",spsr); + uart_puts("\n"); + //if (type%4 == 0) reset(50); +} diff --git a/lab8/src/fat32.c b/lab8/src/fat32.c new file mode 100644 index 000000000..f5385b50e --- /dev/null +++ b/lab8/src/fat32.c @@ -0,0 +1,459 @@ +#include "vfs.h" +#include "fat32.h" +#include "allocator.h" +#include "list.h" +#include "string.h" +#include "mini_uart.h" +#include "sd.h" + +struct file_operations *fat32_fops; +struct vnode_operations *fat32_vops; + +struct fat32_metadata sd_metadata; + +static unsigned int next_cluster(uint32_t cluster_idx); +static uint32_t get_cluster_blk_idx(uint32_t cluster_idx); +static unsigned int get_fat_idx(uint32_t cluster_idx); +static unsigned int get_next_cluster(uint32_t cluster_idx); + +int fat32_create(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* tmp; + fat32_lookup(dir_node,&tmp,component_name); + if(tmp != NULL){ + *target = NULL; + return -1; + } + tmp = allo_vnode(); + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = fat32_fops; + struct file_internal* fi = malloc(sizeof(struct file_internal)); + delete_last_mem(); + fi->cluster_idx = EOC; + fi->dentry_cluster_idx = EOC; + fi->pages = NULL; + fi->page_num = 0; + tmp->internal = fi; + + tmp->v_ops = fat32_vops; + tmp->f_ops = fat32_fops; + tmp->size = 512; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = file; + *target = tmp; + + struct link_list *parent_ll = dir_node->dt->childs; + while(parent_ll->next!=NULL)parent_ll = parent_ll->next; + parent_ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_ll->next->entry = tmp->dt; + parent_ll->next->next = NULL; + return 0; +} + +int fat32_mkdir(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* temp; + fat32_lookup(dir_node,&temp,component_name); + if(temp != NULL){ + *target = NULL; + return -1; + } + struct vnode *tmp = allo_vnode(); + struct dentry *tmp_child = allo_dentry(),*tmp_parent = allo_dentry(); + + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = fat32_fops; + tmp->v_ops = fat32_vops; + tmp->size = 0; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + struct file_internal* fi = malloc(sizeof(struct file_internal)); + delete_last_mem(); + fi->cluster_idx = EOC; + fi->pages = NULL; + tmp->internal = fi; + *target = tmp; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + tmp_parent->name[0] = '.'; + tmp_parent->name[1] = '.'; + tmp_parent->name[2] = 0; + tmp_parent->vnode = tmp->dt->parent->vnode; + tmp_parent->childs = tmp->dt->parent->childs; + tmp_parent->type = directory; + tmp_parent->parent = tmp->dt->parent->parent; + + struct link_list *tmp_parent_child = tmp_parent->childs; + while(tmp_parent_child->next != NULL) tmp_parent_child = tmp_parent_child->next; + tmp_parent_child->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp_parent_child->next->next = NULL; + tmp_parent_child->next->entry = tmp->dt; + + return 0; +} + +int fat32_lookup(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct link_list* tmp = dir_node->dt->childs; + while(tmp != NULL){ + struct dentry* den_tmp = tmp->entry; + if(strcmp(den_tmp->name,component_name)){ + *target = den_tmp->vnode; + return 0; + } + tmp = tmp->next; + } + *target = NULL; + return -1; +} + +int fat32_get_content(unsigned int cluster_idx, struct page_cache **pages){ + uint32_t cluster_idx_tmp = cluster_idx; + (*pages) = malloc(sizeof(struct page_cache) * 20); + delete_last_mem(); + struct page_cache *pc = (*pages); + int i=0; + for(i=0;cluster_idx_tmpvnode->internal; + if(internal->pages != NULL){ + char *tmp = buf; + size_t read_l = 0; + int pt = file->f_pos%512; + int pages_num = file->f_pos/512; + while(read_l < len){ + if(pages_num >= internal->page_num){ + struct page_cache* new_page_num = malloc(sizeof(struct page_cache) * (pages_num/10+1)*10); + memcpy(new_page_num,internal->pages,internal->page_num); + free(internal->pages); + file->vnode->size += 512*(pages_num-internal->page_num+1); + internal->page_num = pages_num+1; + } + if(internal->pages[pages_num].buf == NULL) { + internal->pages[pages_num].buf = malloc(512); + delete_last_mem(); + } + char *tmp_buf = internal->pages[pages_num].buf; + internal->pages[pages_num].modified = 1; + for(int i=pt;i<512 && read_l < len;i++){ + tmp_buf[i] = tmp[read_l++]; + file->f_pos++; + } + pt = 0; + pages_num++; + } + return len; + }else{ + if(internal->cluster_idx >= EOC){ + internal->page_num = 1; + internal->pages = malloc(sizeof(struct page_cache)); + delete_last_mem(); + internal->pages[0].modified = 1; + internal->pages[0].buf = malloc(512); + delete_last_mem(); + memset(internal->pages[0].buf,0,512); + return fat32_write(file,buf,len); + } + struct page_cache *tmp; + fat32_get_content(internal->cluster_idx,&tmp); + internal->pages = tmp; + internal->page_num = 20; + return fat32_write(file,buf,len); + } +} + +int fat32_read(struct file* file, void* buf, size_t len){ + struct file_internal *internal = file->vnode->internal; + if(internal->pages != NULL){ + if(file->f_pos >= file->vnode->size) return 0; + char *tmp = buf; + size_t read_l = 0; + int pt = file->f_pos%512; + int pages_num = file->f_pos/512; + struct link_list *tmp_ll = internal->pages; + while(read_l < len){ + if(tmp_ll == NULL) { + file->f_pos += read_l; + return read_l; + } + for(int i=pt;i<512 && read_l < len;i++){ + char *tmp_buf = internal->pages[pages_num].buf; + tmp[read_l++] = tmp_buf[i]; + file->f_pos++; + if(file->f_pos >= file->vnode->size) return read_l; + } + pt = 0; + pages_num++; + } + return len; + }else{ + if(internal->cluster_idx >= EOC) return 0; + struct page_cache *tmp; + fat32_get_content(internal->cluster_idx,&tmp); + internal->pages = tmp; + internal->page_num = 20; + return fat32_read(file,buf,len); + } +} +int fat32_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = fat32_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int fat32_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +long fat32_lseek64(struct file* file, long offset, int whence){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} + +static uint32_t get_cluster_blk_idx(uint32_t cluster_idx) { + return sd_metadata.data_region_blk_idx + + (cluster_idx - sd_metadata.first_cluster) * sd_metadata.sector_per_cluster; +} + +static unsigned int get_fat_idx(uint32_t cluster_idx){ + return sd_metadata.fat_region_blk_idx + (cluster_idx / FAT_ENTRY_PER_BLOCK); +} + +static unsigned int get_next_cluster(uint32_t cluster_idx){ + if(cluster_idx >= EOC) return cluster_idx; + unsigned int buf[128]; + readblock(get_fat_idx(cluster_idx),buf); + return buf[cluster_idx%FAT_ENTRY_PER_BLOCK]; +} + +void traverse_fat32(struct vnode* start){ + struct file_internal* fi = start->internal; + uint32_t cluster_idx = fi->cluster_idx; + struct fat32_dirent *fd; + char buf[512]; + do{ + uint32_t d = get_cluster_blk_idx(cluster_idx); + readblock(d,buf); + fd = buf; + for(int i=0;fd[i].name[0]!='\0' && i<16;i++){ + if(fd[i].name[0]==0xE5 || fd[i].name[0]=='.') continue; //unused + struct vnode* record; + char name[32]; + memset(name,0,32); + int j; + for(j=0;j<8;j++){ + if(fd[i].name[j] == ' ') break; + else { + name[j] = fd[i].name[j]; + } + } + for(int k=0;k<3 && fd[i].ext[k] != ' ';k++){ + if(k == 0) name[j] = '.'; + name[k+j+1] = fd[i].ext[k]; + } + if(fd[i].attr&(1<<4)) fat32_mkdir(start,&record,name); + else fat32_create(start,&record,name); + struct file_internal* internal = malloc(sizeof(struct file_internal)); + delete_last_mem(); + internal->dentry_cluster_idx = cluster_idx*DIRENT_PER_CLUSTER + i; + internal->cluster_idx = (uint32_t)fd[i].cluster_high << 16|fd[i].cluster_low; + internal->pages = NULL; + internal->page_num = 0; + record->internal = internal; + record->size = fd[i].size; + if(record->dt->type == directory) traverse_fat32(record); + } + + cluster_idx = get_next_cluster(cluster_idx); + }while(cluster_idx < EOC); +} + +int fat32_sync(struct vnode* dir_node, struct vnode* target){ + struct file_internal* internal = target->internal; + if(internal->dentry_cluster_idx >= EOC && internal->cluster_idx >= EOC){ + struct file_internal* parent_internal = dir_node->internal; + unsigned int parent_idx = parent_internal->cluster_idx; + while (get_next_cluster(parent_idx) < EOC) parent_idx = get_next_cluster(parent_idx); + char buf[512]; + readblock(get_cluster_blk_idx(parent_idx),buf); + struct fat32_dirent *fds = buf; + struct page_cache* pc = internal->pages; + int num = 0, cross = -1; + unsigned int *last_entry = &(internal->cluster_idx); + for(int n=0;n<65536 && num < internal->page_num;n+=FAT_ENTRY_PER_BLOCK){ + unsigned int tmp_buf[128]; + readblock(get_fat_idx(n),tmp_buf); + for(int k=0;k<128;k++){ + if(tmp_buf[k] == 0){ + if(cross != -1){ + readblock(get_fat_idx(cross),tmp_buf); + *last_entry = n+k; + writeblock(get_fat_idx(cross),tmp_buf); + cross = -1; + readblock(get_fat_idx(n),tmp_buf); + }else *last_entry = n+k; + if(pc[num].modified == 0 || pc[num].buf == NULL){ + char tmp_buf2[512]; + memset(tmp_buf2,0,512); + writeblock(get_cluster_blk_idx(n+k),tmp_buf2); + }else writeblock(get_cluster_blk_idx(n+k),pc[num].buf); + last_entry = &(tmp_buf[k]); + if(++num >= internal->page_num) break; + } + } + writeblock(get_fat_idx(n),tmp_buf); + cross = n; + } + for(int i=0;i<16;i++){ + if(fds[i].name[0] == '\0' || fds[i].name[0] == 0xE5){ + internal->dentry_cluster_idx = parent_idx*DIRENT_PER_CLUSTER+i; + memset(fds[i].name,' ',8); + memset(fds[i].ext,' ',3); + int j; + for(j=0;j<8 && target->dt->name[j]!='.' && target->dt->name[j]!=0;j++) + fds[i].name[j] = target->dt->name[j]; + for(int k=0;k<3 && j < 8 && target->dt->name[j+1+k]!=0;k++){ + fds[i].ext[k] = target->dt->name[j+1+k]; + } + int attr = 0; + if(target->dt->type == directory) attr |= (1<<4); + fds[i].attr = attr; + fds[i].size = target->size; + fds[i].cluster_high = (internal->cluster_idx >> 16); + fds[i].cluster_low = (internal->cluster_idx & 65535); + writeblock(get_cluster_blk_idx(parent_idx),buf); + break; + } + } + if(target->dt->type == directory){ + struct link_list *child = target->dt->childs; + while(child != NULL){ + struct dentry* d = child->entry; + if(d->name[0] == '.') continue; + fat32_sync(target,d->vnode); + } + } + }else{ + if(target->dt->type == directory){ + struct link_list *child = target->dt->childs; + while(child != NULL){ + struct dentry* d = child->entry; + if(d->name[0] == '.'){ + child = child->next; + continue; + } + fat32_sync(target,d->vnode); + child = child->next; + } + } + } +} + +int fat32_mount(struct filesystem* fs, struct mount* mount){ + mount->fs = fs; + struct vnode *tmp = allo_vnode(); + tmp->f_ops = fat32_fops; + tmp->v_ops = fat32_vops; + tmp->mount = NULL; + + struct dentry *tmp_child = allo_dentry(); + struct dentry *tmp_parent = mount->root->dt->childs->next->entry; + tmp->dt->parent = mount->root->dt->parent; + + tmp->dt->name[0] = '0'; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + + mount->root = tmp; + struct file_internal* fi = malloc(sizeof(struct file_internal)); + delete_last_mem(); + fi->cluster_idx = sd_metadata.first_cluster; + fi->dentry_cluster_idx = EOC; + tmp->internal = fi; + traverse_fat32(tmp); + return 0; +} + +void fat32_init(struct fat32_metadata* metadata){ + fat32_vops = malloc(sizeof(struct vnode_operations)); + fat32_fops = malloc(sizeof(struct file_operations)); + delete_last_mem(); + delete_last_mem(); + memcpy(&sd_metadata,metadata,sizeof(struct fat32_metadata)); + fat32_vops->create = fat32_create; + fat32_vops->lookup = fat32_lookup; + fat32_vops->mkdir = fat32_mkdir; + fat32_vops->mknod = NULL; + fat32_vops->sync = fat32_sync; + fat32_fops->close = fat32_close; + fat32_fops->lseek64 = fat32_lseek64; + fat32_fops->open = fat32_open; + fat32_fops->read = fat32_read; + fat32_fops->write = fat32_write; + struct filesystem *fs = malloc(sizeof(struct filesystem)); + delete_last_mem(); + fs->name = malloc(16); + delete_last_mem(); + memset(fs->name,0,16); + strcpy("fat32\0",fs->name,6); + fs->setup_mount = fat32_mount; + register_filesystem(fs); +} \ No newline at end of file diff --git a/lab8/src/framebuffer.c b/lab8/src/framebuffer.c new file mode 100644 index 000000000..124122f28 --- /dev/null +++ b/lab8/src/framebuffer.c @@ -0,0 +1,94 @@ +#include "framebuffer.h" +#include "string.h" +#include "mini_uart.h" +#include "allocator.h" +#include "mailbox.h" +#include "irq.h" +struct file_operations *fb_fops; +struct vnode_operations *fb_vops; + + +int fb_setup(struct device* device, struct vnode* mount){ + mount->f_ops = fb_fops; + mount->v_ops = fb_vops; +} + +int fb_per_denied(){ + uart_printf("Permission denied\n"); + return -1; +} + +int fb_write(struct file* file, const void* buf, size_t len){ + const unsigned char *color = buf; + for(int i=0;if_pos++); + } + return len; +} + +int fb_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = fb_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int fb_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +int fb_lseek64(struct file* file, long offset, int whence){ + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} + +int fb_ioctl(struct file* file, unsigned long request, uint32_t fb_info[4]){ + if(request == 0){ + set_vc(fb_info); + return 0; + } + return -1; +} + +void vfs_fb_init(){ + struct device *dev = malloc(sizeof(struct device)); + delete_last_mem(); + dev->name = malloc(16); + delete_last_mem(); + memset(dev->name,0,16); + + fb_fops = malloc(sizeof(struct file_operations)); + fb_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + delete_last_mem(); + fb_fops->open = fb_open; + fb_fops->read = fb_per_denied; + fb_fops->write = fb_write; + fb_fops->close = fb_close; + fb_fops->lseek64 = fb_lseek64; + fb_vops->create = fb_per_denied; + fb_vops->lookup = fb_per_denied; + fb_vops->mkdir = fb_per_denied; + fb_vops->mknod = fb_per_denied; + fb_vops->ioctl = fb_ioctl; + + + + strcpy("framebuffer\0",dev->name,12); + dev->setup = fb_setup; + register_device(dev); + vfs_mknod("/dev/framebuffer", "framebuffer"); +} \ No newline at end of file diff --git a/lab8/src/getopt.c b/lab8/src/getopt.c new file mode 100644 index 000000000..d4b792118 --- /dev/null +++ b/lab8/src/getopt.c @@ -0,0 +1,25 @@ +#include "uint.h" +#include "mini_uart.h" + +int optind=1; +char* optarg; + +char *getopt(int argc, char* argv[],char* opt){ + char param[16]; + int ind = 0; + for(int i=0;opt[i] != 0;i++){ + if(opt[i] == ':') param[ind++] = opt[i+1]; + } + for(;optindcallback = callback; + tmp->next = NULL; + if(task_controller == NULL){ + task_controller = tmp; + }else{ + struct interrupt_event *tmp2 = task_controller; + while(tmp2->next != NULL) tmp2 = tmp2->next; + tmp2->next = tmp; + } +} + +int task_empty(){ + return task_controller == NULL; +} + +void exe_first_task(){ + if(task_controller == NULL){ return;} + struct interrupt_event* tmp = task_controller; + task_controller = task_controller->next; + tmp->callback(); + *AUX_MU_IER |= 1; + exe_first_task(); +} \ No newline at end of file diff --git a/lab8/src/irq.S b/lab8/src/irq.S new file mode 100644 index 000000000..afb1244e3 --- /dev/null +++ b/lab8/src/irq.S @@ -0,0 +1,9 @@ +.global irq_enable +irq_enable: + msr daifclr, 0xf + ret + +.global irq_disable +irq_disable: + msr daifset, 0xf + ret \ No newline at end of file diff --git a/lab8/src/irq2.c b/lab8/src/irq2.c new file mode 100644 index 000000000..428973bec --- /dev/null +++ b/lab8/src/irq2.c @@ -0,0 +1,37 @@ +#include "uint.h" +#include "mini_uart.h" +#include "peripheral/irq.h" +#include "aux.h" +#include "timer.h" +#include "gpio.h" +#include "interrupt_queue.h" + +void irq_init_vectors(){ + asm volatile("ldr x0, =exception_table\n" + "msr vbar_el1, x0\n"); + return; +} + +void enable_interrupt_controller() { + uint32 *tmp = irq0_enable_1; + *tmp |= (1 << 29); +} + +int handle_irq() { + uint64 *core_irq=0xFFFF000040000060; + uint32 *irq; + irq = irq0_pending_1; + if (*irq & (1 << 29)) { + *irq &= ~(1 << 29); + *AUX_MU_IER = 0; + push_queue(handle_uart_irq); + return 1; + } + if ((*core_irq) & 2) { + *irq &= ~2; + core_timer_disable(); + push_queue(arm_core_timer_intr_handler); + return 1; + } + return 0; +} diff --git a/lab8/src/jump.S b/lab8/src/jump.S new file mode 100644 index 000000000..7dea7e7cb --- /dev/null +++ b/lab8/src/jump.S @@ -0,0 +1,52 @@ +.global setjump +.global longjump +setjump: + stp x1, x2, [x0 ,16 * 0] + stp x3, x4, [x0 ,16 * 1] + stp x5, x6, [x0 ,16 * 2] + stp x7, x8, [x0 ,16 * 3] + stp x9, x10, [x0 ,16 * 4] + stp x11, x12, [x0 ,16 * 5] + stp x13, x14, [x0 ,16 * 6] + stp x15, x16, [x0 ,16 * 7] + stp x17, x18, [x0 ,16 * 8] + stp x19, x20, [x0 ,16 * 9] + stp x21, x22, [x0 ,16 * 10] + stp x23, x24, [x0 ,16 * 11] + stp x25, x26, [x0 ,16 * 12] + stp x27, x28, [x0 ,16 * 13] + stp x29, x30, [x0 ,16 * 14] + mov x1, lr + mov x2, sp + stp x1, x2, [x0 ,16 * 15] + + ldr x0, =0 + ret + +longjump: + ldp x2, x3, [x0,16 * 15] + mov sp, x3 + mov lr, x2 + + ldp x3, x4, [x0 ,16 * 1] + ldp x5, x6, [x0 ,16 * 2] + ldp x7, x8, [x0 ,16 * 3] + ldp x9, x10, [x0 ,16 * 4] + ldp x11, x12, [x0 ,16 * 5] + ldp x13, x14, [x0 ,16 * 6] + ldp x15, x16, [x0 ,16 * 7] + ldp x17, x18, [x0 ,16 * 8] + ldp x19, x20, [x0 ,16 * 9] + ldp x21, x22, [x0 ,16 * 10] + ldp x23, x24, [x0 ,16 * 11] + ldp x25, x26, [x0 ,16 * 12] + ldp x27, x28, [x0 ,16 * 13] + ldp x29, x30, [x0 ,16 * 14] + + mov x2, x0 + mov x0, x1 + ldp x1, x2, [x2 , 16 * 0] + + ret + + diff --git a/lab8/src/linker.ld b/lab8/src/linker.ld new file mode 100644 index 000000000..950540afa --- /dev/null +++ b/lab8/src/linker.ld @@ -0,0 +1,48 @@ +__heap_size = 0x100000; +SECTIONS +{ + . = 0xffff000000000000; + . += 0x80000; + _begin_ = .; + .text : + { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); + + .data : + { + *(.data) + } + . = ALIGN(4096); + + .bss (NOLOAD) : + { + __bss_start = .; + + *(.bss) + + __bss_end = .; + } + . = ALIGN(4096); + + . = . + 0x100000; + + .heap : + { + __heap_start = .; + + *(.heap*) + + __HeapLimit = . + __heap_size; + + . = . + __heap_size; + + } + . = ALIGN(0x20000); + _end_ = .; + +} +__bss_size = (__bss_end - __bss_start) >> 3; +__dtb_addr = 0xffff000002080000; diff --git a/lab8/src/loadimg.c b/lab8/src/loadimg.c new file mode 100644 index 000000000..ddd26cb32 --- /dev/null +++ b/lab8/src/loadimg.c @@ -0,0 +1,65 @@ +#include "mini_uart.h" +#include "string.h" +#include "allocator.h" + +#define byte unsigned char +#define uint32 unsigned int +#define block_size 128 + + +void loadimg(){ + asm volatile("msr DAIFClr, 0x0\n"); + uint32 addr=malloc(0x100000) + 0x20000; // load to 0x80000 + uart_printf("Start receiving.\n"); + byte SIZE[5]; + byte par=0; + for(int i=0;i<5;i++){ //receive file size + byte temp=uart_read_raw(); + SIZE[i]=temp; + par ^= temp; + uart_printf(" ||%d|| \n",(int)temp); + } + if(par != 0){ + uart_printf("Receiving error\n"); + return; + } + uint32 size=0; + for(int i=0;i<4;i++){ + size <<= 8; + size += SIZE[i]; + } + byte *kernel = (byte*) addr; + byte check_byte=0; + int j=0; + for(int i=0;i=5){ + uart_printf("Error! Please try again later.\n"); + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(2); + return; + } + uart_printf("Something went wrong. Trying to fix it.\n"); + i-=8; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(1); + }else{ + j=0; + check_byte &= 0; + for(int j=0;j<5000;j++) asm volatile("nop"); + uart_write(0); + } + } + } + void (*start_os)(void) = (void *)kernel; //set start_os's addr to the loaded image's addr + uart_printf("Loading Complete.\n"); + uart_printf("Redirecting to 0x%x\n",addr); + asm volatile("msr DAIFClr, 0xf\n"); + start_os(); + free(addr); +} \ No newline at end of file diff --git a/lab8/src/local_timer.c b/lab8/src/local_timer.c new file mode 100644 index 000000000..1aee8f458 --- /dev/null +++ b/lab8/src/local_timer.c @@ -0,0 +1,22 @@ +#include "uint.h" +#include "mini_uart.h" +#include "peripheral/irq.h" +#include "aux.h" +#include "peripheral/timer.h" + +uint32 interval_time = CLOCKHZ * 2; +uint32 cur_val_1 = 0; + +void timer_init(){ + cur_val_1 = *SYSTEM_TIMER_COUNTER_L_32; + cur_val_1 += interval_time; + *SYSTEM_TIMER_COMPARE1 = cur_val_1; +} + +void handle_timer_1(){ + cur_val_1 += interval_time; + *SYSTEM_TIMER_COMPARE1 = cur_val_1; + *SYSTEM_TIMER_CONTROL |= 2; + + uart_printf("Timer 1 recceived!\n"); +} \ No newline at end of file diff --git a/lab8/src/mailbox.c b/lab8/src/mailbox.c new file mode 100644 index 000000000..128a3402e --- /dev/null +++ b/lab8/src/mailbox.c @@ -0,0 +1,177 @@ +#include "mini_uart.h" +#include "peripheral/mmio.h" +#include "string.h" +typedef unsigned int uint32; +typedef unsigned char byte; + +#define MAILBOX_BASE MMIO_BASE + 0xb880 + +#define MAILBOX_READ (uint32*)(MAILBOX_BASE) +#define MAILBOX_STATUS (uint32*)(MAILBOX_BASE+0x18) +#define MAILBOX_WRITE (uint32*)(MAILBOX_BASE+0x20) + +#define MAILBOX_EMPTY 0x40000000 +#define MAILBOX_FULL 0x80000000 +#define MAILBOX_CODE_BUF_RES_SUCC 0x80000000 +#define MAILBOX_CODE_BUF_REQ 0x00000000 +#define MAILBOX_CODE_TAG_REQ 0x00000000 + +#define GET_ARM_MEMORY 0x00010005 +#define GET_BOARD_REVISION 0x00010002 +#define REQUEST_CODE 0x00000000 +#define REQUEST_SUCCEED 0x80000000 +#define REQUEST_FAILED 0x80000001 +#define TAG_REQUEST_CODE 0x00000000 +#define END_TAG 0x00000000 + +#define MBOX_REQUEST 0 +#define MBOX_CH_PROP 8 +#define MBOX_TAG_LAST 0 + +void mailbox_call(uint32 *mailbox,byte channel){ + uint32 r = (uint32)(((unsigned long)mailbox) & (~0xF)) | (channel & 0xF); + while (*MAILBOX_STATUS & MAILBOX_FULL) { + } + *MAILBOX_WRITE = r; + while(1){ + while(*MAILBOX_STATUS & MAILBOX_EMPTY){ + } + + if (r == *MAILBOX_READ){ + return mailbox[1] == MAILBOX_CODE_BUF_RES_SUCC; + } + } + return 0; +} + +void get_board_revision(){ + uint32 __attribute__((aligned(16))) mailbox[7]; + mailbox[0] = 7 * 4; // buffer size in bytes + mailbox[1] = REQUEST_CODE; + // tags begin + mailbox[2] = GET_BOARD_REVISION; // tag identifier + mailbox[3] = 4; // maximum of request and response value buffer's length. + mailbox[4] = TAG_REQUEST_CODE; + mailbox[5] = 0; // value buffer + // tags end + mailbox[6] = END_TAG; + + mailbox_call(mailbox,8); // message passing procedure call, you should implement it following the 6 steps provided above. + char s[11]; + i16toa(mailbox[5],s,8); + uart_printf("Board Revision: 0x"); // it should be 0xa020d3 for rpi3 b+ + uart_printf(s); + uart_printf("\n"); +} + +void get_arm_memory() { + unsigned int __attribute__((aligned(16))) mailbox[8]; + mailbox[0] = 8 * 4; // buffer size in bytes + mailbox[1] = MAILBOX_CODE_BUF_REQ; + // tags begin + mailbox[2] = GET_ARM_MEMORY; // tag identifier + mailbox[3] = 8; // maximum of request and response value buffer's length. + mailbox[4] = MAILBOX_CODE_TAG_REQ; // tag code + mailbox[5] = 0; // base address + mailbox[6] = 0; // size in bytes + mailbox[7] = 0x0; // end tag + // tags end + mailbox_call(mailbox, 8); + uart_printf("ARM memory base addr: 0x%x size: 0x%x\n",mailbox[5],mailbox[6]); + +} + +unsigned int width, height, pitch, isrgb; /* dimensions and channel order */ +unsigned long long lfb; /* raw frame buffer address */ + +int set_vc(unsigned int fb_info[4]){ + unsigned int __attribute__((aligned(16))) mbox[36]; + + mbox[0] = 35 * 4; + mbox[1] = MBOX_REQUEST; + + mbox[2] = 0x48003; // set phy wh + mbox[3] = 8; + mbox[4] = 8; + mbox[5] = fb_info[0]; // FrameBufferInfo.width + mbox[6] = fb_info[1]; // FrameBufferInfo.height + + mbox[7] = 0x48004; // set virt wh + mbox[8] = 8; + mbox[9] = 8; + mbox[10] = fb_info[0]; // FrameBufferInfo.virtual_width + mbox[11] = fb_info[1]; // FrameBufferInfo.virtual_height + + mbox[12] = 0x48009; // set virt offset + mbox[13] = 8; + mbox[14] = 8; + mbox[15] = 0; // FrameBufferInfo.x_offset + mbox[16] = 0; // FrameBufferInfo.y.offset + + mbox[17] = 0x48005; // set depth + mbox[18] = 4; + mbox[19] = 4; + mbox[20] = 32; // FrameBufferInfo.depth + + mbox[21] = 0x48006; // set pixel order + mbox[22] = 4; + mbox[23] = 4; + mbox[24] = fb_info[3]; // RGB, not BGR preferably + + mbox[25] = 0x40001; // get framebuffer, gets alignment on request + mbox[26] = 8; + mbox[27] = 8; + mbox[28] = fb_info[2]; // FrameBufferInfo.pointer + mbox[29] = 0; // FrameBufferInfo.size + + mbox[30] = 0x40008; // get pitch + mbox[31] = 4; + mbox[32] = 4; + mbox[33] = 0; // FrameBufferInfo.pitch + + mbox[34] = MBOX_TAG_LAST; + + // this might not return exactly what we asked for, could be + // the closest supported resolution instead + mailbox_call(mbox, MBOX_CH_PROP); + if ( mbox[20] == 32 && mbox[28] != 0) { + mbox[28] &= 0x3FFFFFFF; // convert GPU address to ARM address + width = mbox[5]; // get actual physical width + height = mbox[6]; // get actual physical height + pitch = mbox[33]; // get number of bytes per line + isrgb = mbox[24]; // get the actual channel order + lfb = ((unsigned long long)mbox[28] | 0xFFFF000000000000); + } else { + uart_printf("Unable to set screen resolution to %dx%dx32\n",fb_info[0],fb_info[1]); + } +} + +void fb_splash(unsigned char color, unsigned long ptr){ + *((unsigned char *)(lfb + ptr)) = color; +} + +void fb_splash2() { + int x, y; + unsigned char *ptr = lfb; + unsigned int white = 255 << 16 | 0 << 8 | 255; // A B G R + unsigned int black = 0; + unsigned int current, start = black, spacing = 40; + unsigned long long tmp = 0; + + for (y = 0; y < height; y++) { + if (y % spacing == 0 && y != 0) { + start = (start == white) ? black : white; + } + current = start; + for (x = 0; x < width; x++) { + if (x % spacing == 0 && x != 0) { + current = (current == white) ? black : white; + } + unsigned char *c = ¤t; + for(int i=0;i<4;i++){ + fb_splash(c[i],tmp+i); + } + tmp+=4; + } + } +} \ No newline at end of file diff --git a/lab8/src/main.c b/lab8/src/main.c new file mode 100644 index 000000000..39bd4d40e --- /dev/null +++ b/lab8/src/main.c @@ -0,0 +1,45 @@ +#include "mini_uart.h" +#include "shell.h" +#include "mailbox.h" +#include "irq.h" +#include "timer.h" +#include "uint.h" +#include "interrupt_queue.h" +#include "aux.h" +#include "jump.h" +#include "thread.h" + +#define max_length 128 + +struct JumpBuf jb; + +int gettime(){ + int time,freq; + asm volatile("mrs %[input0], cntpct_el0\n" + "mrs %[input1], cntfrq_el0\n" + :[input0] "=r" (time), [input1] "=r" (freq)); + float temp=(float)time/freq; + int start_time= temp*1000; + return start_time; +} + +int main() { + + shell_init(); + uart_printf("Initial completed\n"); + get_board_revision(); + get_arm_memory(); + + irq_init_vectors(); + enable_interrupt_controller(); + irq_enable(); + + //core_timer_enable(); + //timer_init(); //local timer + setjump(&jb); + clear_threads(); + set_first_thread(); + schedule(); + while (1){ + } +} diff --git a/lab8/src/math.c b/lab8/src/math.c new file mode 100644 index 000000000..a018bef5d --- /dev/null +++ b/lab8/src/math.c @@ -0,0 +1,32 @@ +int log(int base, int logarithm){ + int tmp = 1; + int exp = 0; + while(tmp <= logarithm){ + tmp *= base; + exp ++; + } + return exp-1; +} + +int exp(int base, int exponent){ + int tmp = 1; + for(int i=0;i=b ? b:a; +} \ No newline at end of file diff --git a/lab8/src/mini_uart.c b/lab8/src/mini_uart.c new file mode 100644 index 000000000..51a3cbfac --- /dev/null +++ b/lab8/src/mini_uart.c @@ -0,0 +1,288 @@ +#include "aux.h" +#include "gpio.h" +#include "buffer.h" +#include "allocator.h" +#include "jump.h" +#include "signal.h" +#include "thread.h" +#include "vfs.h" +#include "string.h" + +int transmit_interrupt_open = 0; +char uart_buffer[1024]; +unsigned int wr_buffer_index = 0; +unsigned int rd_buffer_index = 0; +struct buffer wbuffer,rbuffer; +extern struct jumpBuf jb; + + +void uart_init() { + + /* Initialize UART */ + *AUX_IRQ |= 1; // Enable mini UART interrupt pending + *AUX_ENABLES |= 1; // Enable mini UART + *AUX_MU_CNTL = 0; // Disable TX, RX during configuration + *AUX_MU_IER = 1; // enable interrupt + *AUX_MU_LCR = 3; // Set the data size to 8 bit + *AUX_MU_MCR = 0; // Don't need auto flow control + *AUX_MU_BAUD = 270; // Set baud rate to 115200 + *AUX_MU_IIR = 6; // No FIFO + + /* Map UART to GPIO Pins */ + + // 1. Change GPIO 14, 15 to alternate function + register unsigned int r = *GPFSEL1; //gpio10~19 is located GPSEL1 + r &= ~((7 << 12) | (7 << 15)); // Reset GPIO 14, 15 + r |= (2 << 12) | (2 << 15); // Set ALT5 + *GPFSEL1 = r; + + // 2. Disable GPIO pull up/down (Because these GPIO pins use alternate functions, not basic input-output) + // Set control signal to disable + *GPPUD = 0; + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Clock the control signal into the GPIO pads + *GPPUDCLK0 = (1 << 14) | (1 << 15); + // Wait 150 cycles + r = 150; + while (r--) { + asm volatile("nop"); + } + // Remove the clock + *GPPUDCLK0 = 0; + + // 3. Enable TX, RX + *AUX_MU_CNTL = 3; + + transmit_interrupt_open = 0; +} + +void uart_init_buffer(){ + wbuffer.start = 0; + wbuffer.end = 0; + rbuffer.start = 0; + rbuffer.end = 0; +} + +char uart_read() { + // Check data ready field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + // Read + char r = (char)(*AUX_MU_IO); + // Convert carrige return to newline + return r == '\r' ? '\n' : r; +} + +char uart_read_raw() { + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x01)); + return (char)(*AUX_MU_IO); +} + +void uart_write(unsigned int c) { + // Check transmitter idle field + do { + asm volatile("nop"); + } while (!(*AUX_MU_LSR & 0x20)); + // Write + *AUX_MU_IO = c; +} + +void uart_printf(char* fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + + while (*fmt) { + if (*fmt == '\n') uart_write('\r'); + else if(*fmt == '%'){ + fmt++; + if(*fmt == 'd'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + itoa(arg,temp); + uart_printf(temp); + }else if(*fmt == 's'){ + char *arg = __builtin_va_arg(args, char*); + uart_printf(arg); + }else if(*fmt == 'x'){ + int arg = __builtin_va_arg(args, int); + char temp[10]; + i16toa(arg,temp,8); + uart_printf(temp); + }else if(*fmt == 'c'){ + unsigned char arg = __builtin_va_arg(args,int); + uart_write(arg); + }else if(*fmt == '.'){ + int l = *(++fmt)-'0'; + if(*(++fmt) == 'f'){ + float *arg = __builtin_va_arg(args, float*); + char temp[20]; + ftoa(arg,l,temp); + uart_printf(temp); + } + } + else if(*fmt++ == 'l'){ + if(*fmt == 'e'){ + unsigned int arg = __builtin_va_arg(args, unsigned int); + unsigned char *t = (unsigned char *) &arg; + for(int i=0;i<4;i++){ + unsigned char temp[3]; + temp[2]='\0'; + i16toa(t[i],temp,2); + uart_printf(temp); + } + }else if(*fmt == 'l'){ + unsigned long long arg = __builtin_va_arg(args, unsigned long long); + unsigned char temp[24]; + itoa(arg, temp); + uart_printf("%s",temp); + } + } + fmt++; + continue; + } + else if(!(*fmt >=32 && *fmt <= 127)) break; + uart_write(*fmt++); + } +} + +void uart_flush() { + while (*AUX_MU_LSR & 0x01) { + *AUX_MU_IO; + } +} + +int uart_push(char c){ + return write_buffer(&wbuffer,c); +} + +int uart_pop(unsigned char *c){ + return read_buffer(&rbuffer,c); +} + +void *handle_uart_irq() +{ + unsigned int id = *AUX_MU_IIR; + if((id & 0x06) == 0x04) //receive interrupt + { + if( *AUX_MU_LSR & 0x01) { + char c; + c = *AUX_MU_IO & 0xFF; + if(c == 3){ + uart_printf("^C\n"); + reset_flag(); + + longjump(&jb,1); + }else{ + write_buffer(&rbuffer,c); + } + } + } + if((id & 0x06) == 0x02) //transmit interrupt + { + while(*AUX_MU_LSR & 0x20) { + unsigned char c; + if(read_buffer(&wbuffer,&c) == 0) { + // close transmit interrupt + *AUX_MU_IER = 1; + transmit_interrupt_open = 0; + return; + } + *AUX_MU_IO = c; + } + } + *AUX_MU_IER = 1; + return; +} + +struct file_operations *uart_fops; +struct vnode_operations *uart_vops; + + +int uart_setup(struct device* device, struct vnode* mount){ + mount->f_ops = uart_fops; + mount->v_ops = uart_vops; +} + +int device_per_denied(){ + uart_printf("Permission denied\n"); + return -1; +} + +int uart_vfs_write(struct file* file, const void* buf, size_t len){ + char *tmp = buf; + //for(int i=0;i= len){ + return len; + } + } + } +} + +int uart_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = uart_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int uart_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +void vfs_uart_init(){ + struct device *dev = malloc(sizeof(struct device)); + delete_last_mem(); + dev->name = malloc(16); + delete_last_mem(); + memset(dev->name,0,16); + + uart_fops = malloc(sizeof(struct file_operations)); + uart_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + delete_last_mem(); + uart_fops->open = uart_open; + uart_fops->read = uart_vfs_read; + uart_fops->write = uart_vfs_write; + uart_fops->close = uart_close; + uart_fops->lseek64 = device_per_denied; + uart_vops->create = device_per_denied; + uart_vops->lookup = device_per_denied; + uart_vops->mkdir = device_per_denied; + uart_vops->mknod = device_per_denied; + uart_vops->sync = do_nothing; + + + + strcpy("uart\0",dev->name,5); + dev->setup = uart_setup; + register_device(dev); + vfs_mknod("/dev/uart", "uart"); +} + diff --git a/lab8/src/mmu.c b/lab8/src/mmu.c new file mode 100644 index 000000000..77b91a9fa --- /dev/null +++ b/lab8/src/mmu.c @@ -0,0 +1,176 @@ +#include "mmu.h" +#include "peripheral/mmu.h" +#include "uint.h" +#include "allocator.h" +#include "math.h" +#include "thread.h" +#include "scheduler.h" + +struct pte_manage +{ + byte prot,num; +}*pm; + +void cow_init(){ + pm = malloc(sizeof(struct pte_manage) * (0x40000000/0x1000)); + delete_last_mem(pm); + for(int i=0;i<(0x40000000/0x1000);i++){ + pm[i].prot = 0; + pm[i].num = 0; + } +} + +uint64_t vm_decode(uint64_t va, pagetable_t *p){ + pagetable_t *pt = ((uint64_t) p & 0xfffff000) | 0xffff000000000000; + uint64_t blocksize = 0x8000000000; + for(int i=0;i<4;i++){ + pt = ((uint64_t)pt->entries[va/blocksize] & 0xfffff000) | 0xffff000000000000; + va %= blocksize; + blocksize >>= 9; + if(pt == 0xffff000000000000){ + return NULL; + } + } + uint64_t re = ((uint64_t)pt&0xfffffffff000) + va; + return re; +} + +pagetable_t* allocate_page(){ + pagetable_t* pt = malloc(sizeof(pagetable_t)); + for(int i=0;i<512;i++) pt->entries[i] = NULL; + return pt; +} + +pte_t walk(pagetable_t *pt, uint64_t va, uint64_t end, uint64_t pa, uint64_t blocksize, byte prot){ + if(blocksize < 1<<12){ + uint32_t idx = (pa & 0xfffff000) >> 12; + uint64_t label = PTE_ATTR_BASE; + pm[idx].num=1; + pm[idx].prot = prot; + if(prot == 0) return (pa & 0xfffff000); + if(prot & PROT_WRITE == 0) label |= RO_BIT | PD_ACCESS; + else label |= PD_ACCESS; + if(prot & PROT_EXEC == 0) label |= USR_EXE_NEVER_BIT; + return (pa & 0xfffff000) | label; + }else{ + uint64_t start = va / blocksize; + uint64_t num = upper_bound(end,blocksize) - va/blocksize; + if(pt == NULL){ + pt = allocate_page(); + move_last_mem(0); + }else{ + pt = ((uint64_t)pt & ~(uint64_t)0x3) | 0xffff000000000000; + } + for(int i=0;ientries[start + i] = walk(pt->entries[start + i], va2 - gap,min(end,(va2/blocksize + 1) * blocksize) - gap,pa + va2 - va,blocksize >> (uint64_t)9,prot); + } + return ((uint64_t)pt & (uint64_t)0xffffffff) | 0b11; + } +} + +void mappages(pagetable_t* pagetable, uint64_t va, uint64_t size, uint64_t pa, byte prot){ + uint64_t end_addr = va + size; + walk(pagetable, va, end_addr, pa, (uint64_t)1 << 39, prot); +} + +void SetTaskStackPagetable(pagetable_t *pt, void* stack_addr){ + int stack_size = 0x4000; + mappages(pt,0xffffffffb000,stack_size, (uint64_t)stack_addr & 0xfffffffc,PROT_READ | PROT_WRITE); +} + +void SetTaskCodePagetable(pagetable_t *pt, void* code_addr, uint64_t size){ + mappages(pt,0x0, size, (uint64_t)code_addr & 0xfffffffc, PROT_READ | PROT_EXEC); +} + +void SetPeripherialPagetable(pagetable_t *pt){ + mappages(pt,0x3c000000, 0x4000000, 0x3c000000, PROT_READ | PROT_WRITE); +} + +void* mmap_set(void* addr, size_t len, int prot, int flags){ + uint64_t align_addr = (uint64_t)addr & ~(uint64_t)0xfff; + thread_t *t = get_current(); + while(vm_decode(align_addr,t->page_table) != NULL){ + align_addr += 0x1000; + if(align_addr >= 0xffffffffb000) return NULL; + } + for(int i=0;i>12;i++) mappages(t->page_table,align_addr + i * 0x1000,0x1000,(uint64_t)prot<<12,0); + + return align_addr; +} + +bool mmap_check(uint64_t FAR){ + thread_t *t = get_current(); + if(FAR >= 0xFFFFFFFFB000 && FAR < 0xFFFFFFFFF000){ + uint64_t pa = vm_decode(FAR & ~(uint64_t)0xfff,t->page_table); + if(pa == NULL){ + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, (uint64_t)malloc(0x1000),PROT_READ | PROT_WRITE); + }else{ + byte *stack = (pa & ~(uint64_t)0xfff) | 0xffff000000000000; + byte *new_stack = malloc(0x1000); + for (int i=0;i<0x1000;i++) new_stack[i] = stack[i]; + mappages(t->page_table,FAR & ~(uint64_t)0xfff,0x1000, new_stack,PROT_READ | PROT_WRITE); + } + set_ttbr0_el1(t->page_table); + return true; + } + if(FAR >= 0x3c000000 && FAR < 0x40000000){ + SetPeripherialPagetable(t->page_table); + set_ttbr0_el1(t->page_table); + return true; + } + uint64_t align_addr = (uint64_t)FAR & ~(uint64_t)0xfff; + uint64_t addr = vm_decode(align_addr,t->page_table)>>12; + if(addr != 0){ + if(addr < 0x10000){ + uint64_t *pa = malloc(0x1000); + for(int i=0;i<200;i++) pa[i] = 0; + mappages(t->page_table,align_addr,0x1000,pa,addr); + }else{ + if((pm[addr].prot&PROT_WRITE) == 0) return false; + uint64_t *space = (addr<<12) | 0xffff000000000000; + uint64_t *new_space = malloc(0x1000); + for(int i=0;i<0x200;i++) new_space[i] = space[i]; + mappages(t->page_table,align_addr,0x1000,new_space,pm[addr].prot); + } + set_ttbr0_el1(t->page_table); + return true; + } + return false; +} + + +void map_pages(uint64_t des, uint64_t src){ + pagetable_t* pt_des = (des&~(uint64_t)0xfff) | 0xffff000000000000; + pagetable_t* pt_src = (src&~(uint64_t)0xfff) | 0xffff000000000000; + for(int i=0;i<512;i++){ + if(pt_src->entries[i] == NULL) continue; + pagetable_t* pt_des_l2 = allocate_page(); + pt_des->entries[i] = ((uint64_t)pt_des_l2 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l2 = ((uint64_t)pt_src->entries[i] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int j=0;j<512;j++){ + if(pt_src_l2->entries[j] == NULL) continue; + pagetable_t* pt_des_l1 = allocate_page(); + pt_des_l2->entries[i] = ((uint64_t)pt_des_l1 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l1 = ((uint64_t)pt_src_l2->entries[j] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int k=0;k<512;k++){ + if(pt_src_l1->entries[k] == NULL) continue; + pagetable_t* pt_des_l0 = allocate_page(); + pt_des_l1->entries[i] = ((uint64_t)pt_des_l0 & ~0xffff000000000000) | 0b11; + move_last_mem(0); + pagetable_t* pt_src_l0 = ((uint64_t)pt_src_l1->entries[k] & ~(uint64_t)0xfff) | 0xffff000000000000; + for(int l=0;l<512;l++){ + if(pt_src_l0->entries[l] == NULL) continue; + pm[((uint32_t)(pt_src_l0->entries[l]))>>12].num++; + pt_src_l0->entries[l] |= RO_BIT; + pt_des_l0->entries[l] = pt_src_l0->entries[l]; + } + } + } + } +} \ No newline at end of file diff --git a/lab8/src/mmu_asm.S b/lab8/src/mmu_asm.S new file mode 100644 index 000000000..1579a5980 --- /dev/null +++ b/lab8/src/mmu_asm.S @@ -0,0 +1,109 @@ +#include "peripheral/mmu.h" +.global disable_mmu +.global set_tcr +.global set_mair +.global identity_paging +.global page_table_set +.global setup_mmu +.global set_ttbr0_el1 + +disable_mmu: + ldr x1, =0 //close MMU + msr sctlr_el1, x1 + ret + +set_tcr: + ldr x0, = TCR_CONFIG_DEFAULT + msr tcr_el1, x0 + ret + +set_mair: + ldr x0, =( \ + (MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE_nGnRnE * 8)) | \ + (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL_NOCACHE * 8)) \ + ) + msr mair_el1, x0 + ret + +identity_paging: + mov x0, 0 // PGD's page frame at 0x0 + mov x1, 0x1000 // PUD's page frame at 0x1000 + + ldr x2, = BOOT_PGD_ATTR + orr x2, x1, x2 // combine the physical address of next level page with attribute. + str x2, [x0] + + ldr x2, = BOOT_PUD0_ATTR + mov x3, 0x2000 + orr x3, x2, x3 + str x3, [x1] // 1st 1GB mapped by the 1st entry of PUD + ldr x2, = BOOT_PUD1_ATTR + mov x3, 0x40000000 + orr x3, x2, x3 + str x3, [x1, 8] // 2nd 1GB mapped by the 2nd entry of PUD + +/* mov x1, 0x2000 + ldr x2, = BOOT_PMD0_ATTR + mov x3, 0x10000 //PTE base + mov x4, xzr + mov x5, 0x200 + mov x6, 8 + +1: mul x7, x4, x6 + lsl x9, x4, 12 + add x9, x3, x9 + orr x9, x2, x9 + add x8, x1, x7 + str x9, [x8] + add x4, x4, #1 + cmp x4, x5 + b.ls 1b*/ + +2: mov x1, 0x2000 + ldr x2, = BOOT_PMD0_ATTR_RAM + mov x3, 0x1f7 + mov x4, xzr + +3: lsl x6, x4, 3 + add x7, x1, x6 + lsl x8, x4, 21 + orr x8, x2, x8 + str x8, [x7] + add x4, x4, #1 + cmp x4, x3 + b.ls 3b + +4: cmp x4, 0x1ff + bge 5f + ldr x2, = BOOT_PMD0_ATTR_MMIO + mov x3, 0x200 + b 3b + +5: msr ttbr0_el1, x0 // load PGD to the bottom translation-based register. + msr ttbr1_el1, x0 + + mrs x2, sctlr_el1 + orr x2 , x2, 1 + msr sctlr_el1, x2 // enable MMU, cache remains disabled + + + ldr x2, = boot_rest // indirect branch to the virtual address + br x2 + +setup_mmu: + bl set_tcr + bl set_mair + bl identity_paging + ret + +set_ttbr0_el1: + dsb ish // ensure write has completed + msr ttbr0_el1, x0 // switch translation based address. + tlbi vmalle1is // invalidate all TLB entries + dsb ish // ensure completion of TLB invalidatation + isb // clear pipeline + ret +.global get_ttbr0_el1 +get_ttbr0_el1: + mrs x0, ttbr0_el1 + ret \ No newline at end of file diff --git a/lab8/src/panic.c b/lab8/src/panic.c new file mode 100644 index 000000000..17942c5b6 --- /dev/null +++ b/lab8/src/panic.c @@ -0,0 +1,33 @@ +#include "mini_uart.h" +const char *entry_error_messages[] = { + "SYNC_INVALID_EL1t", + "IRQ_INVALID_EL1t", + "FIQ_INVALID_EL1t", + "ERROR_INVALID_EL1T", + + "SYNC_INVALID_EL1h", + "IRQ_INVALID_EL1h", + "FIQ_INVALID_EL1h", + "ERROR_INVALID_EL1h", + + "SYNC_INVALID_EL0_64", + "IRQ_INVALID_EL0_64", + "FIQ_INVALID_EL0_64", + "ERROR_INVALID_EL0_64", + + "SYNC_INVALID_EL0_32", + "IRQ_INVALID_EL0_32", + "FIQ_INVALID_EL0_32", + "ERROR_INVALID_EL0_32", +}; + +void not_implemented() { + uart_printf("kenel panic because of not implemented function...\n"); + while (1); +} + +void show_exception_status(int type, unsigned long esr, unsigned long address) { + uart_printf("%s, ESR: 0x%x, address: 0x%x\n", entry_error_messages[type], esr, address); + uart_printf("Exception class (EC) 0x%x\n", (esr >> 26) & 0b111111); + uart_printf("Instruction specific syndrome (ISS) 0x%x\n", esr & 0xFFFFFF); +} \ No newline at end of file diff --git a/lab8/src/priority_queue.c b/lab8/src/priority_queue.c new file mode 100644 index 000000000..183647ef7 --- /dev/null +++ b/lab8/src/priority_queue.c @@ -0,0 +1,79 @@ +#include "allocator.h" +#include "priority_queue.h" +#include "uint.h" +#include "thread.h" + +struct node *nodes = NULL; +int num_of_nodes=0; + +uint64 add_node(void (*callback_f)(),void* arguments,uint64 times,uint64 time_gap){ + + struct node *node = malloc(sizeof(struct node)); + node->time_to_ring = times; + node->todo = callback_f; + node->next = NULL; + node->arguments = arguments; + int a; + if(nodes == NULL){ + nodes = node; + }else if( time_gap >= times){ + time_gap = nodes->time_to_ring-time_gap; + node->next = nodes; + nodes = node; + struct node *temp=nodes->next; + while(temp != NULL){ + temp->time_to_ring -= time_gap; + temp = temp->next; + } + }else{ + struct node* temp = nodes; + time_gap = nodes->time_to_ring-time_gap; + temp->time_to_ring -= time_gap; + while(temp->next != NULL){ + temp->next->time_to_ring -= time_gap; + if(temp->next->time_to_ring >= times){ + node->next = temp->next; + temp->next = node; + temp->next = temp->next->next; + break; + }else{ + temp = temp->next; + } + } + if(temp->next == NULL){ + temp->next = node; + }else{ + while(temp->next != NULL){ + temp->next->time_to_ring -= time_gap; + temp = temp->next; + } + } + } + num_of_nodes++; + return nodes->time_to_ring; +} + +struct node* delete_first_node(){ + if(nodes == NULL) return NULL; + uint64 times=nodes->time_to_ring; + struct node *t = nodes; + nodes = nodes->next; + free(t); + struct node *temp = nodes; + while(temp != NULL){ + temp->time_to_ring -= times; + temp = temp->next; + } + num_of_nodes--; + return t; +} + +void print_node(){ + struct node *temp = nodes; + int i=0; + while(temp != NULL){ + uart_printf("%d: %d\n",i,temp->time_to_ring); + i++; + temp = temp->next; + } +} \ No newline at end of file diff --git a/lab8/src/queue.c b/lab8/src/queue.c new file mode 100644 index 000000000..56798b4ed --- /dev/null +++ b/lab8/src/queue.c @@ -0,0 +1,77 @@ +#include "uint.h" +#include "thread.h" +#include "scheduler.h" + +struct thread* run_queue = NULL; +extern uint64 freq_thread; +void init_queue(){ + run_queue = NULL; +} + +int schedule(){ +start: + if(run_queue == NULL) + push_first_thread(); + struct thread* prev = get_current(); + struct thread* tmp = run_queue; + run_queue = run_queue->next; + + if(tmp->status == running){ + switch_to(prev,tmp); + }else if(tmp->status == dead){ + remove_from_queue(tmp->tid); + goto start; + }else{ + tmp->status = running; + if(tmp->tid == 0){ + set_current(tmp); + }else{ + store_and_jump(prev,tmp); + } + } +} + +void push2run_queue(struct thread* thread){ + if(run_queue != NULL){ + struct thread *tmp = run_queue; + while(tmp->next != NULL){ + tmp = tmp->next; + } + tmp->next = thread; + }else{ + run_queue = thread; + } + thread->next = NULL; +} + +void push2run_queue_top(struct thread* thread){ + thread->next = run_queue; + run_queue = thread; +} + +void wakeup_queue(struct thread *t){ + if(t->status == dead) return; + t->status = running; + push2run_queue(t); +} + +void exit(){ + struct thread *t = get_current(); + free_mem_table(t); + t->status = dead; + schedule(); +} + +void remove_from_queue(pid_t pid){ + struct thread *t = run_queue; + if(t != NULL && t->tid == pid) run_queue = run_queue->next; + else if(t != NULL){ + while(t->next != NULL){ + if(t->next->tid == pid){ + t->next = t->next->next; + return; + } + } + } +} + diff --git a/lab8/src/reboot.c b/lab8/src/reboot.c new file mode 100644 index 000000000..867cabdf7 --- /dev/null +++ b/lab8/src/reboot.c @@ -0,0 +1,13 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC ((volatile unsigned int*)0xFFFF00003F10001c) +#define PM_WDOG ((volatile unsigned int*)0xFFFF00003F100024) + +void reset(int tick){ // reboot after watchdog timer expire + *PM_RSTC = PM_PASSWORD | 0x20; // full reset + *PM_WDOG = PM_PASSWORD | tick; // number of watchdog tick +} + +void cancel_reset() { + *PM_RSTC = PM_PASSWORD | 0; // full reset + *PM_WDOG = PM_PASSWORD | 0; // number of watchdog tick +} \ No newline at end of file diff --git a/lab8/src/scheduler.S b/lab8/src/scheduler.S new file mode 100644 index 000000000..7e7301203 --- /dev/null +++ b/lab8/src/scheduler.S @@ -0,0 +1,157 @@ +.macro push_registers + stp x19, x20, [x0, 16 * 0] + stp x21, x22, [x0, 16 * 1] + stp x23, x24, [x0, 16 * 2] + stp x25, x26, [x0, 16 * 3] + stp x27, x28, [x0, 16 * 4] + stp fp, lr, [x0, 16 * 5] + mov x9, sp + str x9, [x0, 16 * 6] +.endm + +.macro pop_registers + ldp x19, x20, [x0, 16 * 0] + ldp x21, x22, [x0, 16 * 1] + ldp x23, x24, [x0, 16 * 2] + ldp x25, x26, [x0, 16 * 3] + ldp x27, x28, [x0, 16 * 4] + ldp fp, lr, [x0, 16 * 5] + ldr x9, [x0, 16 * 6] + mov sp, x9 +.endm + +.global switch_to +switch_to: + push_registers + + mov x0, x1 + + pop_registers + msr tpidr_el1, x1 + mov x0, #0 + ret + +.global get_current +get_current: + mrs x0, tpidr_el1 + ret + +.global store_and_jump +store_and_jump: + push_registers + + ldr x0, [x1, 8 * 2] + ldr x2, [x1, 8 * 3] + ldr x3, [x1, 8 * 4] + + mov x29, sp + + ldr x9, [x1, 8 * 1] + mov sp, x9 + + stp x1, x29, [sp, #-16]! + mov fp, sp + + ldr x9, [x1, 8 * 0] + msr tpidr_el1, x1 + mov x1, sp + blr x9 + + ldp x0, x29, [sp, 16 * 0] + mov sp, x29 + + mov w1, 3 + str w1, [x0, 140] + + bl exit + +.global set_current +set_current: + ldr x9, [x0, 8 * 1] + mov sp, x9 + + mov fp, sp + + msr tpidr_el1, x0 + ldr x9, [x0, 8 * 0] + blr x9 + +.global set_proc +set_proc: + msr tpidr_el1, x0 + ret + +.global task_schedule +task_schedule: + msr daifclr, 0x0 + push_registers + + bl UserScheduler + +.global SwitchTo +SwitchTo: + pop_registers + msr tpidr_el1, x0 + b check_signal + ret + +.global sig_handler_assembly +sig_handler_assembly: + mov x19, x0 + mov x0, x2 + sub sp, sp, #16 + str lr, [sp, 0 * 16] + msr daifclr, 0xf + bl from_el1_to_el0_forsig + mov x0, x19 + blr x19 //el0 start + mov x8, #100 + svc #0 + +.global ret_to_sig_han +ret_to_sig_han: + msr daifclr, 0x0 + mov sp, x0 + ldr lr, [sp, 0 * 16] + add sp, sp, #16 + ret + +.global check_signal +check_signal: + mov x1, sp + sub x1, x1, 16 * 7 + mov x2, x0 + mov x0, x1 + push_registers + mov sp, x1 + mov x0, x2 + + bl sig_handler_kernel + + mov x0, sp + pop_registers + msr daifclr, 0xf + ret + +from_el1_to_el0_forsig: + msr elr_el1, lr + + msr sp_el0, x1 + + ldr x1, =0 + msr spsr_el1, x1 + + + eret + +.global get_el +get_el: + mrs x0, CurrentEL + lsr x0, x0, #2 + and x0, x0, #3 + ret + +.global call_exit +call_exit: + mov x8, #5 + svc #0 \ No newline at end of file diff --git a/lab8/src/sd.c b/lab8/src/sd.c new file mode 100644 index 000000000..640d620e7 --- /dev/null +++ b/lab8/src/sd.c @@ -0,0 +1,73 @@ +#include "sd.h" +#include "string.h" +#include "peripheral/sd.h" +#include "string.h" +#include "vfs.h" +#include "fat32.h" + +int sd_mount(); +void init_sd(){ + sd_init(); + sd_mount(); +} + +int sd_mount(){ + char buf[512]; + readblock(0,buf); + if(buf[0x01FE] != 0x55 && buf[0x01FF] != 0xAA) return -1; + struct mbr_partition mp; + memcpy(&mp,buf+0x01BE,sizeof(struct mbr_partition)); + if(mp.partition_type == 0x0B){ // sd card with chs + readblock(mp.lba,buf); + struct fat32_boot_sector *fbs = buf; + struct fat32_metadata sd_metadeta; + sd_metadeta.data_region_blk_idx = mp.lba + + fbs->n_sectors_per_fat_32 * fbs->n_file_alloc_tabs + + fbs->n_reserved_sectors; + sd_metadeta.fat_region_blk_idx = mp.lba + fbs-> n_reserved_sectors; + sd_metadeta.n_fat = fbs->n_file_alloc_tabs; + sd_metadeta.sector_per_fat = fbs->n_sectors_per_fat_32; + sd_metadeta.sector_per_cluster = fbs->logical_sector_per_cluster; + sd_metadeta.first_cluster = fbs->root_dir_start_cluster_num; + fat32_init(&sd_metadeta); + vfs_mount("/boot","fat32"); + } +} + +/*int sd_mount(){ + // read MBR + char buf[512]; + readblock(0, buf); + + // check boot signature + if (buf[510] != 0x55 || buf[511] != 0xAA) { + return -1; + } + + // parse first partition only + struct mbr_partition p1; + memcpy(&p1, buf + 446, sizeof(struct mbr_partition)); + + // mount partition + readblock(p1.lba, buf); + // route each filesystem + if (p1.partition_type == 0x0b) { // FAT32 with CHS addressing + // create FAT32's root directory object + + // store metadata + struct fat32_boot_sector* boot_sector = (struct fat32_boot_sector*)buf; + struct fat32_metadata fd; + fd.data_region_blk_idx = p1.lba + + boot_sector->n_sectors_per_fat_32 * boot_sector->n_file_alloc_tabs + + boot_sector->n_reserved_sectors; + fd.fat_region_blk_idx = p1.lba + boot_sector->n_reserved_sectors; + fd.n_fat = boot_sector->n_file_alloc_tabs; + fd.sector_per_fat = boot_sector->n_sectors_per_fat_32; + fd.first_cluster = boot_sector->root_dir_start_cluster_num; + fd.sector_per_cluster = boot_sector->logical_sector_per_cluster; + + uart_printf("%d\n",fd.data_region_blk_idx); + } + + return 0; +}*/ \ No newline at end of file diff --git a/lab8/src/sd_driver.c b/lab8/src/sd_driver.c new file mode 100644 index 000000000..536283291 --- /dev/null +++ b/lab8/src/sd_driver.c @@ -0,0 +1,186 @@ +#include "peripheral/mmio.h" +#include "peripheral/sd.h" +#include "gpio.h" +// gpio +#define GPIO_GPFSEL4 (GPIO_BASE + 0x10) +#define GPIO_GPFSEL5 (GPIO_BASE + 0x14) +#define GPIO_GPPUD (GPIO_BASE + 0x94) +#define GPIO_GPPUDCLK1 (GPIO_BASE + 0x9c) + +// helper +#define set(io_addr, val) \ + asm volatile("str %w1, [%0]" ::"r"(io_addr), "r"(val) : "memory"); + +#define get(io_addr, val) \ + asm volatile("ldr %w0, [%1]" : "=r"(val) : "r"(io_addr) : "memory"); + +static inline void delay(unsigned long tick) { + while (tick--) { + asm volatile("nop"); + } +} + +static int is_hcs; // high capcacity(SDHC) + +static void pin_setup() { + set(GPIO_GPFSEL4, 0x24000000); + set(GPIO_GPFSEL5, 0x924); + set(GPIO_GPPUD, 0); + delay(15000); + set(GPIO_GPPUDCLK1, 0xffffffff); + delay(15000); + set(GPIO_GPPUDCLK1, 0); +} + +static void sdhost_setup() { + unsigned int tmp; + set(SDHOST_PWR, 0); + set(SDHOST_CMD, 0); + set(SDHOST_ARG, 0); + set(SDHOST_TOUT, SDHOST_TOUT_DEFAULT); + set(SDHOST_CDIV, 0); + set(SDHOST_HSTS, SDHOST_HSTS_MASK); + set(SDHOST_CFG, 0); + set(SDHOST_CNT, 0); + set(SDHOST_SIZE, 0); + get(SDHOST_DBG, tmp); + tmp &= ~SDHOST_DBG_MASK; + tmp |= SDHOST_DBG_FIFO; + set(SDHOST_DBG, tmp); + delay(250000); + set(SDHOST_PWR, 1); + delay(250000); + set(SDHOST_CFG, SDHOST_CFG_SLOW | SDHOST_CFG_INTBUS | SDHOST_CFG_DATA_EN); + set(SDHOST_CDIV, SDHOST_CDIV_DEFAULT); +} + +static int wait_sd() { + int cnt = 1000000; + unsigned int cmd; + do { + if (cnt == 0) { + return -1; + } + get(SDHOST_CMD, cmd); + --cnt; + } while (cmd & SDHOST_NEW_CMD); + return 0; +} + +static int sd_cmd(unsigned cmd, unsigned int arg) { + set(SDHOST_ARG, arg); + set(SDHOST_CMD, cmd | SDHOST_NEW_CMD); + return wait_sd(); +} + +static int sdcard_setup() { + unsigned int tmp; + sd_cmd(GO_IDLE_STATE | SDHOST_NO_REPONSE, 0); + sd_cmd(SEND_IF_COND, VOLTAGE_CHECK_PATTERN); + get(SDHOST_RESP0, tmp); + if (tmp != VOLTAGE_CHECK_PATTERN) { + return -1; + } + while (1) { + if (sd_cmd(APP_CMD, 0) == -1) { + // MMC card or invalid card status + // currently not support + continue; + } + sd_cmd(SD_APP_OP_COND, SDCARD_3_3V | SDCARD_ISHCS); + get(SDHOST_RESP0, tmp); + if (tmp & SDCARD_READY) { + break; + } + delay(1000000); + } + + is_hcs = tmp & SDCARD_ISHCS; + sd_cmd(ALL_SEND_CID | SDHOST_LONG_RESPONSE, 0); + sd_cmd(SEND_RELATIVE_ADDR, 0); + get(SDHOST_RESP0, tmp); + sd_cmd(SELECT_CARD, tmp); + sd_cmd(SET_BLOCKLEN, 512); + return 0; +} + +static int wait_fifo() { + int cnt = 1000000; + unsigned int hsts; + do { + if (cnt == 0) { + return -1; + } + get(SDHOST_HSTS, hsts); + --cnt; + } while ((hsts & SDHOST_HSTS_DATA) == 0); + return 0; +} + +static void set_block(int size, int cnt) { + set(SDHOST_SIZE, size); + set(SDHOST_CNT, cnt); +} + +static void wait_finish() { + unsigned int dbg; + do { + get(SDHOST_DBG, dbg); + } while ((dbg & SDHOST_DBG_FSM_MASK) != SDHOST_HSTS_DATA); +} + +void readblock(int block_idx, void* buf) { + unsigned int* buf_u = (unsigned int*)buf; + int succ = 0; + if (!is_hcs) { + block_idx <<= 9; + } + do{ + set_block(512, 1); + sd_cmd(READ_SINGLE_BLOCK | SDHOST_READ, block_idx); + for (int i = 0; i < 128; ++i) { + wait_fifo(); + get(SDHOST_DATA, buf_u[i]); + } + unsigned int hsts; + get(SDHOST_HSTS, hsts); + if (hsts & SDHOST_HSTS_ERR_MASK) { + set(SDHOST_HSTS, SDHOST_HSTS_ERR_MASK); + sd_cmd(STOP_TRANSMISSION | SDHOST_BUSY, 0); + } else { + succ = 1; + } + } while(!succ); + wait_finish(); +} + +void writeblock(int block_idx, void* buf) { + unsigned int* buf_u = (unsigned int*)buf; + int succ = 0; + if (!is_hcs) { + block_idx <<= 9; + } + do{ + set_block(512, 1); + sd_cmd(WRITE_SINGLE_BLOCK | SDHOST_WRITE, block_idx); + for (int i = 0; i < 128; ++i) { + wait_fifo(); + set(SDHOST_DATA, buf_u[i]); + } + unsigned int hsts; + get(SDHOST_HSTS, hsts); + if (hsts & SDHOST_HSTS_ERR_MASK) { + set(SDHOST_HSTS, SDHOST_HSTS_ERR_MASK); + sd_cmd(STOP_TRANSMISSION | SDHOST_BUSY, 0); + } else { + succ = 1; + } + } while(!succ); + wait_finish(); +} + +void sd_init() { + pin_setup(); + sdhost_setup(); + sdcard_setup(); +} \ No newline at end of file diff --git a/lab8/src/shell.c b/lab8/src/shell.c new file mode 100644 index 000000000..89af2c108 --- /dev/null +++ b/lab8/src/shell.c @@ -0,0 +1,319 @@ +#include "mini_uart.h" +#include "string.h" +#include "reboot.h" +#include "uint.h" +#include "dtb.h" +#include "allocator.h" +#include "aux.h" +#include "thread.h" +#include "getopt.h" +#include "scheduler.h" +#include "loadimg.h" +#include "mailbox.h" +#include "mmu.h" +#include "vfs.h" +#include "tmpfs.h" +#include "framebuffer.h" +#include "sd.h" + +struct ARGS{ + char** argv; + int argc; +}; + + +extern unsigned char __heap_start, _end_, _begin_; +extern byte __dtb_addr; +uint64_t cpio_start,cpio_end; +char cmd_buffer[1024]; +unsigned int cmd_index = 0; +unsigned int cmd_flag = 0; + + +void shell_init(){ + uint64 *heap = (uint64*)(&__heap_start-8); + *heap &= 0x00000000; + uart_init(); + uart_printf("\n\n\nHello From RPI3\n"); + uart_init_buffer(); + uart_flush(); + core_timer_init(); + init_allocator(); + uint64 *ramf_start,*ramf_end; + ramf_start=find_property_value("/chosen\0","linux,initrd-start\0"); //get ramf start addr from dtb + ramf_end=find_property_value("/chosen\0","linux,initrd-end\0"); //get ramf end addr from dtb + if(ramf_start != 0){ + uart_printf("Ramf start: 0x%x\n",letobe(*ramf_start)); + cpio_start=letobe(*ramf_start); + }if(ramf_end != 0){ + uart_printf("Ramf end: 0x%x\n",letobe(*ramf_end)); + cpio_end=letobe(*ramf_end); + } + cpio_start |= 0xFFFF000000000000; + cpio_end |= 0xFFFF000000000000; + memory_reserve(0xffff000000000000,0xffff000000080000); //Spin tables for multicore boot + + memory_reserve(0xFFFF000000001000,0xFFFF000000003000); //Spin tables for multicore boot + + memory_reserve(cpio_start,cpio_end); //Initramfs + + memory_reserve(&_begin_,&_end_); //Kernel image in the physical memory and simple allocator + + uint64 *addr = &__dtb_addr; + + memory_reserve(*addr,*addr + 0x100000); //Device tree + + memory_reserve(0xFFFF000000000000,0xFFFF000000080000); //Kernel stack + + init_thread(); + + cow_init(); + + vfs_init(); + + tmpfs_init(); + + init_cpio(); + + vfs_uart_init(); + + vfs_fb_init(); + + init_sd(); + + +} + +void reset_flag(){ + cmd_flag=0; + *AUX_MU_IER = 1; + core_timer_disable(); + irq_enable(); +} + +void uart_read_line(){ + //check("./initramfs/vfs1.img"); + char in; + if(cmd_flag == 0){ + uart_printf("# "); + cmd_flag = 1; + cmd_index = 0; + for(int i=0;i<1024;i++) cmd_buffer[i]=0; + } + while( uart_pop(&in) ){ + if(cmd_flag == 0){ + uart_printf("# "); + cmd_flag = 1; + cmd_index = 0; + for(int i=0;i<1024;i++) cmd_buffer[i]=0; + } + if(in == 13){ + uart_printf("\n"); + cmd_buffer[cmd_index++] = '\0'; + cmd_flag = 0; + check(cmd_buffer); + }else if((in==8 || in==127)){ + if(cmd_index>0){ + cmd_index--; + char t[1]={8}; + cmd_buffer[cmd_index]='\0'; + uart_write(8); + uart_write(' '); + uart_write(8); + } + }else if( in>=32 && in<=126 ){ + cmd_buffer[cmd_index++]=in; + uart_push(in); + *AUX_MU_IER |= 2; + } + } +} + +void* m[10]; + +struct ARGS* parse_command(char *command){ + char** tmp = malloc(sizeof(char*)*16); + int p=0; + if(command[0] == 0) return NULL; + for(int i=0;command[i] != 0;i++){ + if(command[i] == ' ') continue; + char *arg = malloc(sizeof(char[128])); + int p2=0; + for(;command[i] != 0 && command[i] != ' ' && command[i]>=32 && command[i]<=127 ;i++){ + arg[p2++] = command[i]; + } + arg[p2] = 0; + tmp[p++] = arg; + if(command[i] == 0) break; + } + struct ARGS* args; + args = malloc(sizeof(struct ARGS)); + args->argc = p; + args->argv = tmp; + return args; +} + +void temp_func2(){ + uart_printf("2"); +} + +void temp_func3(){ + uart_printf("3"); +} +void temp_func(){ +} + + + +void fork_test(){ + uart_printf("\nFork Test, pid %d\n", getpid1()); + int cnt = 1; + int ret = 0; + if ((ret = fork1()) == 0) { // child + long long cur_sp; + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("first child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + ++cnt; + + if ((ret = fork1()) != 0){ + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("first child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + } + else{ + while (cnt < 5) { + asm volatile("mov %0, sp" : "=r"(cur_sp)); + uart_printf("second child pid: %d, cnt: %d, ptr: %x, sp : %x\n", getpid1(), cnt, &cnt, cur_sp); + delay(5000); + ++cnt; + } + } + exit1(); + } + else { + uart_printf("parent here, pid %d, child %d\n", getpid1(), ret); + } +} + +void check(char *input){ + struct ARGS *cmd = parse_command(input); + if(input[0] == '\0' || input[0] == '\n') return; + if(strcmp(input,"help")==1){ + uart_printf("help : print the help menu\n"); + uart_printf("hello : print Hello World!\n"); + uart_printf("reboot : reboot the device\n"); + }else if(strcmp(input,"hello")==1){ + uart_printf("Hello World!\n"); + }else if(strncmp(input,"reboot",6)==1){ + uart_printf("Rebooting...\n"); + if(input[6] != ' '){ + reset(50); + while(1); + } + int a=0; + for(int i=7;input[i]<='9' && input[i]>='0';i++){ + a *= 10; + a += (input[i]-'0'); + } + reset(a<50? 50:a); + while(1); + }else if(strncmp(input,"ls",2)){ + char name[128]; + memset(name,0,128); + int i=3; + for(;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-3]=input[i]; + } + name[i]='\0'; + vfs_ls(name); + }else if(strncmp(input,"cd ",3)){ + char name[128]; + memset(name,0,128); + int i=3; + for(;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-3]=input[i]; + } + name[i]='\0'; + vfs_cd(name); + }else if(strncmp(input,"cat", 3)){ + vfs_cat(input+4); + }else if(strncmp(input,"./",2)){ + irq_disable(); + char name[128]; + for(int i=0;i<128;i++) name[i] = 0; + int i; + for(i=2;input[i]>=46 && input[i]<=122 && i<128 && input[i]!='\0'; i++){ + name[i-2]=input[i]; + } + char *const argv[] = {name}; + execute(name,argv); + irq_enable(); + }else if(strcmp(input,"timer")){ + int clock_hz,now_time,interval; + asm volatile("mrs %[input0], cntfrq_el0\n" + "mrs %[input1], cntp_tval_el0\n" + :[input0] "=r" (clock_hz), + [input1] "=r" (interval)); + uart_printf("%d\n", interval/clock_hz); + + }else if(strncmp(input,"sleep", 5)){ + char time[5]; + for(int i=0;i<5 && input[i+6]>=32 && input[i+6]<=127;i++) time[i] = input[i+6]; + int times = atoi(time); + sleep(times); + }else if(strcmp(cmd->argv[0],"thread")){ + int t=1; + optind = 1; + while(t){ + char c = getopt(cmd->argc,cmd->argv,":a:r"); + switch (c){ + case 'a': + for(int i=0;i<10;i++) + Thread(temp_func); + break; + case 'r': + break; + case 0: + t=0; + break; + } + } + }else if(strcmp(cmd->argv[0],"mem")){ + int t=1; + optind = 1; + while(t){ + char c = getopt(cmd->argc,cmd->argv,":s:a:p"); + switch (c){ + case 's': + pool_status(); + break; + case 'a': + printf_thread(); + break; + case 'p': + print_node(); + break; + case 0: + t=0; + break; + default: + show_status(); + break; + + } + } + }else if(strcmp(cmd->argv[0],"lp")){ + loadimg(); + }else if(strcmp(cmd->argv[0],"test")){ + char *tmp = malloc(512); + memset(tmp,0,512); + readblock(0,tmp); + for(int i=0;i<32;i++){ + for(int j=i*16;jsig_handler[SIGNAL] = handler; +} + +int sentSignal(int pid, int SIGNAL){ + threads[pid]->signal |= 1<signal & 1<sig_handler[i] != NULL){ + t->signal &= !(1<page_table & ~(uint64_t) 0b11) | 0xffff000000000000; + void *sp = malloc(0x4000); + pagetable_t *tmp_pt = allocate_page(); + t->page_table = ((uint64_t)tmp_pt & ~0xffff000000000000) | 0b11; + SetTaskStackPagetable(t->page_table, sp); + for(int j=0;j<0x1f0;j++) tmp_pt->entries[j] = pt->entries[j]; + set_ttbr0_el1(t->page_table); + sig_handler_assembly(t->sig_handler[i], 0xfffffffff000, NULL); + free(sp); + t->page_table = pt; + set_ttbr0_el1(t->page_table); + } + } + return t; +} \ No newline at end of file diff --git a/lab8/src/start.S b/lab8/src/start.S new file mode 100644 index 000000000..74ac47b35 --- /dev/null +++ b/lab8/src/start.S @@ -0,0 +1,79 @@ + +.section ".text.boot" + +.global _start +.global from_el1_to_el0 +.global user_process +.global boot_rest + + +_start: + // get cpu id + mrs x1, MPIDR_EL1 + and x1, x1, #3 + cbz x1, 2f + // if cpu_id > 0, stop +1: + wfe + b 1b + // if cpu_id == 0 +2: + mov x1, 0x02080000 + str x0, [x1] + bl disable_mmu + + // set stack pointer + ldr x1, =_start + mov sp, x1 + + bl from_el2_to_el1 + bl setup_mmu + +boot_rest: + // clear bss + ldr x1, =__bss_start + ldr x2, =__bss_size +3: cbz x2, 4f + str xzr, [x1], #8 + sub x2, x2, #1 + cbnz x2, 3b + + + +4: bl main + // halt this core if return + b 1b + + +from_el2_to_el1: + ldr x1, =_start + msr sp_el1, x1 + + mov x1, (0b11 << 20) // make el0, el1 can use Floating point and Advanced SIMD + msr CPACR_EL1, x1 + + mov x0, (1 << 31) // EL1 uses aarch64 + msr hcr_el2, x0 + + mov x0, 0x3c5 // EL1h (SPSel = 1) with interrupt disabled + msr spsr_el2, x0 + + msr elr_el2, lr + + + adr x9, exception_table + msr vbar_el1, x9 + + eret + +from_el1_to_el0: + msr elr_el1, x19 + + msr sp_el0, x20 + + ldr x1, =0x3c0 + msr spsr_el1, x1 + + + eret + diff --git a/lab8/src/string.c b/lab8/src/string.c new file mode 100644 index 000000000..a7c36471f --- /dev/null +++ b/lab8/src/string.c @@ -0,0 +1,185 @@ +#include "uint.h" +void itoa(unsigned long long value,char *s) { + int idx = 0; + char tmp[24]; + int tidx = 0; + do { + tmp[tidx++] = '0' + value % 10; + value /= 10; + } while (value != 0 && tidx < 11); + // reverse tmp + int i; + for (i = tidx - 1; i >= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +void ftoa(float *value, int precise, char *s) { + int temp=1; + for(int i=0;i= 0; i--) { + s[idx++] = tmp[i]; + } + s[idx] = '\0'; +} + +int strcmp(char *string1, char *string2){ + while(*string1 && *string2){ + if(*string1!=*string2) return 0; + else{ + string1++; + string2++; + } + } + if(*string1){ + if((*string1>='a' && *string1<='z') || (*string1>='A' && *string1<='Z') || (*string1>='0' && *string1<='9')) + return 0; + else + return 1; + } + if(*string2){ + if((*string2>='a' && *string2<='z') || (*string2>='A' || *string2<='Z') || (*string2>=0 && *string2<=9)) + return 0; + else + return 1; + } + return 1; +} + +int strncmp(char *string1, char *string2, int length){ + char temp1[128],temp2[128]; + for(int i=0;i=32 && s1[i]<=127;i++){ + out[i]=s1[i]; + } + for(;s2[j]>=32 && s2[j]<=127;j++){ + out[i+j]=s2[j]; + } + out[i+j]=0; + +} + +int atoi(char *s){ + int n=0; + for(int i=0;s[i]>=32 && s[i]<=127;i++){ + n*=10; + n += s[i]-'0'; + } + return n; +} + +int a16toi(char *s){ + int n=0; + for(int i=0;(s[i]>='0' && s[i]<='9') || (s[i]>='A' && s[i]<='F') || (s[i]>='a' && s[i]<='f');i++){ + n*=16; + if(s[i]>='0' && s[i]<='9') + n += s[i]-'0'; + else if(s[i]>='A' && s[i]<='F') + n += s[i]-'A'; + else if(s[i]>='a' && s[i]<='f') + n += s[i]-'a'; + } + return n; +} + +int a16ntoi(char *num, int length){ // transform hex string to int + int namesize=0; + for(int i=0;i='0' && num[i]<='9'){ + namesize += (num[i]-'0'); + }else if(num[i]>='A' && num[i]<='F'){ + namesize += (num[i]-'A'+10); + } + } + return namesize; +} + +void *memset(void *str, int c, size_t n){ + unsigned char* string = (unsigned long)str; + for(int i=0;ipage_table); + SwitchTo(t); + } +} + +void UserExit(){ + struct thread *t = get_current(); + t->status = dead; + UserScheduler(); +} + +void* ReadyListPop(){ + void * tmp = ReadyList; + ReadyList = ReadyList->next; + return tmp; +} + +void InitUserTaskScheduler(){ + thread_timer(); + struct thread *t = get_current(); + t->status = dead; + UserScheduler(); +} + +void PushToReadyList(pid_t pid){ + struct thread* item = threads[pid]; + struct thread *tmp = ReadyList; + if(tmp == NULL){ + ReadyList = item; + }else{ + while(tmp->next != NULL) tmp = tmp->next; + tmp->next = item; + } + item->next = NULL; +} + +void RemoveItemFromReadyList(pid_t pid){ + struct thread *tmp = ReadyList; + if(tmp != NULL){ + if(tmp->tid == pid){ + ReadyList = ReadyList->next; + }else{ + while(tmp->next != NULL){ + if(tmp->next->tid == pid){ + tmp->next = tmp->next->next; + } + } + } + } +} + +int UserKill(pid_t pid){ + threads[pid]->status = dead; + RemoveItemFromReadyList(pid); +} + +int UserThread(void* func,void* arg){ + struct thread *t; + t = malloc(sizeof(struct thread)); + for(int i=0;itid = i; + break; + } + } + delete_last_mem(); + unsigned char* kstack = malloc(0x10000); + t->next = NULL; + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + t->sig_handler[9] = call_exit; + t->sig_handler[10] = UserKill; + t->page_table = ((uint64_t)allocate_page() | 0b11) & ~0xffff000000000000; + t->signal = 0; + t->childs = NULL; + t->kstack = kstack; + t->registers[0] = 0x0; + t->registers[1] = 0xfffffffff000; + t->registers[2] = arg; + t->registers[10] = ( (uint64)(t->kstack + 0x10000) & 0xfffffffffffffff0); + t->registers[11] = from_el1_to_el0; + t->registers[12] = t->registers[10]; + memset(t->fd,0,sizeof(struct file*) * 65536); + struct file* tmp; + vfs_open("/dev/uart",64,&tmp); + t->fd[0] = tmp; + t->fd[1] = tmp; + t->fd[2] = tmp; + vfs_lookup("/",&(t->CurWorkDir)); + + struct thread *temp = get_current(); + t->ptid = temp->tid; + t->malloc_table[0] = NULL; + struct thread_sibling *temp2 = temp->childs; + struct thread_sibling *new_child = malloc(sizeof(struct thread_sibling)); + move_last_mem(t->tid); + move_last_mem(t->tid); + move_last_mem(t->tid); + void *a; + new_child->self = t; + new_child->next = NULL; + if(temp2 == NULL){ + temp->childs = new_child; + }else{ + while(temp2->next != NULL){ + temp2 = temp2->next; + } + temp2->next = new_child; + } + PushToReadyList(t->tid); + return t->tid; +} + +int set_fork(void* sp){ + byte *t = get_current(); + tid_t tid = UserThread(return_to_child,NULL); + pagetable_t* pagetable = threads[tid]->page_table; + unsigned char* kstack = threads[tid]->kstack; + + byte *child = threads[tid]; + uint64 gap = (uint64)child - (uint64)t; + for(int i=0;ikstack; + threads[tid]->tid = tid; + threads[tid]->ptid = tmp->tid; + threads[tid]->registers[10] = tf-1; + threads[tid]->registers[11] = return_to_child; + threads[tid]->registers[12] = tf; + threads[tid]->next = NULL; + threads[tid]->kstack = kstack; + threads[tid]->page_table = pagetable; + for(int i=0;i<0x10000;i++) kstack[i] = tmp->kstack[i]; + map_pages(threads[tid]->page_table,tmp->page_table); + set_ttbr0_el1(tmp->page_table); + tf->spsr_el1 = 0; + tf->x[0] = 0; + return tid; +} + +void execute(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0) { + uart_printf("Error: \"%s\" is not an executable file\n",file); + return; + } + int tid = UserThread(code,NULL); + SetTaskCodePagetable(threads[tid]->page_table,code,length); + InitUserTaskScheduler(); +} + +void exec(char *file,char *const argv[]){ + void* code = NULL; + uint64_t length = 0; + copy_content(file, &code, &length); + if(code == NULL || length == 0){ + uart_printf("Error: \"%s\" is not an executable file\n",file); + return; + } + struct thread *t = get_current(); + SetTaskCodePagetable(t->page_table,code,length); + from_el1_to_el0(code, 0xfffffffff000); +} diff --git a/lab8/src/temp.S b/lab8/src/temp.S new file mode 100644 index 000000000..2a2161ba4 --- /dev/null +++ b/lab8/src/temp.S @@ -0,0 +1,49 @@ +.global getpid1 +getpid1: + mov x8, #0 + svc #0 + ret + +.global uart_read1 +uart_read1: + mov x8, #1 + svc #0 + ret + +.global uart_write1 +uart_write1: + mov x8, #2 + svc #0 + ret + +.global exec1 +exec1: + mov x8, #3 + svc #0 + ret + +.global fork1 +fork1: + mov x8, #4 + svc #0 + ret + +.global exit1 +exit1: + mov x8, #5 + svc #0 + ret + +.global mbox_call1 +mbox_call1: + mov x8, #6 + svc #0 + ret + +.global kill1 +kill1: + mov x8, #7 + svc #0 + ret + + diff --git a/lab8/src/thread.c b/lab8/src/thread.c new file mode 100644 index 000000000..3d180fb28 --- /dev/null +++ b/lab8/src/thread.c @@ -0,0 +1,224 @@ +#include "uint.h" +#include "thread.h" +#include "allocator.h" +#include "queue.h" +#include "scheduler.h" +#include "shell.h" +#include "excep.h" +#include "task.h" + +struct thread *threads[thread_numbers]; + + +int Thread(void *func(void),...){ + __builtin_va_list args; + __builtin_va_start(args, func); + void* arg = __builtin_va_arg(args, void*); + struct thread *t; + t = malloc(sizeof(struct thread)); + delete_last_mem(); + t->next = NULL; + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + t->sig_handler[9] = kill; + t->sig_handler[10] = kill; + t->signal = 0; + t->status = starting; + t->childs = NULL; + t->ustack = malloc(0x10000); + t->registers[0] = func; + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); + t->registers[2] = arg; + for(int i=0;i<65536;i++) t->fd[i] = NULL; + vfs_lookup("/",&(t->CurWorkDir)); + struct thread *temp = get_current(); + t->ptid = temp->tid; + t->malloc_table[0] = NULL; + struct thread_sibling *temp2 = temp->childs; + struct thread_sibling *new_child = malloc(sizeof(struct thread_sibling)); + delete_last_mem(); + void *a; + new_child->self = t; + new_child->next = NULL; + if(temp2 == NULL){ + temp->childs = new_child; + }else{ + while(temp2->next != NULL){ + temp2 = temp2->next; + } + temp2->next = new_child; + } + for(int i=0;itid = i; + break; + } + } + move_last_mem(t->tid); + push2run_queue(t); + return t->tid; +} + + +void set_first_thread(){ + struct thread *t; + t = malloc(sizeof(struct thread)); + delete_last_mem(); + t->status = starting; + t->childs = NULL; + t->ptid = 0; + t->tid = 0; + t->signal = 0; + threads[0] = t; + t->malloc_table[0] = NULL; + t->next = NULL; + t->ustack = malloc(0x10000); + delete_last_mem(); + t->registers[0] = idle; + t->registers[1] = ( (uint64)(t->ustack + 0x10000) & 0xfffffffffffffff0); + for(int i=0;i<32;i++) t->sig_handler[i] = NULL; + push2run_queue(t); +} + +void push_first_thread(){ + push2run_queue(threads[0]); +} + +void init_thread(){ + clear_threads(); + asm("mov x0, #0\n" + "msr tpidr_el1, x0\n"); + return ; +} + +void kill_zombies(){ + for(int i=1;istatus == dead){ + free_mem_table(threads[i]); + free(threads[i]); + threads[i] = NULL; + } + } +} + +void idle(){ + while(1){ + handle_child(0); + kill_zombies(); + free_mem_table(threads[0]); + Thread(uart_read_line); + schedule(); + } +} + +void clear_threads(){ + for(int i=0;ichilds; + if(ts == NULL){ + return; + }else{ + while(ts->self->status == dead){ + free(ts); + threads[0]->childs = threads[0]->childs->next; + ts = threads[0]->childs; + if(ts == NULL) return; + } + while(ts->next != NULL){ + if(ts->next->self->status == dead){ + free(ts->next); + ts->next = ts->next->next; + } + ts = ts->next; + } + + } +} + +void free_mem_table(struct thread *t){ + for(int i=0;i<256;i++){ + if(t->malloc_table[i] != NULL){ + free(t->malloc_table[i]); + t->malloc_table[i] = NULL; + }else{ + return; + } + } +} + +void record_mem(void* addr){ + struct thread *t = get_current(); + for(int i=0;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i] = addr; + if(i<255) t->malloc_table[i+1] = NULL; + break; + } + } +} + +void delete_last_mem(){ + struct thread *t = get_current(); + if(t == NULL || t->malloc_table[0] == NULL) return; + for(int i=1;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i-1] = NULL; + break; + } + } +} + +void printf_thread(){ + for(int i=0;i<10;i++){ + if(threads[i] != NULL){ + uart_printf("tid: %d\n",threads[i]->tid); + uart_printf("addr: 0x%x\n",threads[i]); + uart_printf("status: %d\n",threads[i]->status); + uart_printf("ptid: %d\n",threads[i]->ptid); + uart_printf("stack: 0x%x ~ 0x%x\n",threads[i]->ustack,threads[i]->ustack+0x10000); + } + } +} + +int getpid(){ + struct thread *t = get_current(); + return t->tid; +} + +int kill(pid_t pid){ + free_mem_table(threads[pid]); + threads[pid]->status = dead; + threads[pid] = NULL; + remove_from_queue(pid); +} + +int move_last_mem(tid_t tid){ + struct thread *now = get_current(); + void* addr; + for(int i=0;i<256;i++){ + if(now->malloc_table[i] == NULL){ + if(i == 0) return -1; + addr = now->malloc_table[i-1]; + now->malloc_table[i-1] = NULL; + break; + } + } + + + struct thread *t = threads[tid]; + for(int i=0;i<256;i++){ + if(t->malloc_table[i] == NULL){ + t->malloc_table[i] = addr; + if(i<255) t->malloc_table[i+1] = NULL; + return 0; + } + } +} \ No newline at end of file diff --git a/lab8/src/timer.S b/lab8/src/timer.S new file mode 100644 index 000000000..c995ff31b --- /dev/null +++ b/lab8/src/timer.S @@ -0,0 +1,24 @@ +#define CORE0_TIMER_IRQ_CTRL 0xFFFF000040000040 +.global core_timer_enable +.global core_timer_disable + + +core_timer_enable: + mov x0, 1 + msr cntp_ctl_el0, x0 // enable + mrs x0, cntfrq_el0 + msr cntp_tval_el0, x0 // set expired time + mov x0, 2 + ldr x1, =CORE0_TIMER_IRQ_CTRL + str w0, [x1] // unmask timer interrupt + ret + +core_timer_disable: + mov x0, 0 + msr cntp_ctl_el0, x0 // disable + mov x0, 0 + ldr x1, =CORE0_TIMER_IRQ_CTRL + str w0, [x1] // unmask timer interrupt + ret + + \ No newline at end of file diff --git a/lab8/src/tmpfs.c b/lab8/src/tmpfs.c new file mode 100644 index 000000000..24435966e --- /dev/null +++ b/lab8/src/tmpfs.c @@ -0,0 +1,259 @@ +#include "vfs.h" +#include "allocator.h" +#include "string.h" +#include "tmpfs.h" + +struct file_operations *tmpfs_fops; +struct vnode_operations *tmpfs_vops; + +extern struct mount* rootfs; + + +void tmpfs_init(){ + tmpfs_vops = malloc(sizeof(struct vnode_operations)); + delete_last_mem(); + tmpfs_fops = malloc(sizeof(struct file_operations)); + delete_last_mem(); + tmpfs_vops->create = tmpfs_create; + tmpfs_vops->lookup = tmpfs_lookup; + tmpfs_vops->mkdir = tmpfs_mkdir; + tmpfs_vops->mknod = tmpfs_mknod; + tmpfs_vops->sync = do_nothing; + tmpfs_fops->close = tmpfs_close; + tmpfs_fops->lseek64 = tmpfs_lseek64; + tmpfs_fops->open = tmpfs_open; + tmpfs_fops->read = tmpfs_read; + tmpfs_fops->write = tmpfs_write; + struct filesystem *fs = malloc(sizeof(struct filesystem)); + delete_last_mem(); + fs->name = malloc(16); + delete_last_mem(); + memset(fs->name,0,16); + strcpy("tmpfs\0",fs->name,6); + fs->setup_mount = tmpfs_mount; + register_filesystem(fs); + fs->setup_mount(fs,rootfs); + struct vnode* tmp; + + tmpfs_mkdir(rootfs->root,&tmp,"initramfs"); + tmpfs_mkdir(rootfs->root,&tmp,"dev"); + tmpfs_mkdir(rootfs->root,&tmp,"boot"); +} + +int tmpfs_mount(struct filesystem* fs, struct mount* mount){ + mount->fs = fs; + struct vnode *tmp = allo_vnode(); + struct dentry *tmp_child = allo_dentry(), *tmp_parent = allo_dentry(); + tmp->f_ops = tmpfs_fops; + tmp->v_ops = tmpfs_vops; + tmp->mount = mount; + + tmp->dt->name[0] = 0; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + if(mount->root !=NULL){ + tmp->dt->parent = mount->root->dt->parent; + tmp_parent = mount->root->dt->childs->next->entry; + }else{ + tmp->dt->parent = tmp->dt; + + tmp_parent = allo_dentry(); + tmp_parent->name[0] = '.'; + tmp_parent->name[1] = '.'; + tmp_parent->name[2] = 0; + tmp_parent->vnode = tmp; + tmp_parent->childs = tmp->dt->childs; + tmp_parent->type = directory; + tmp_parent->parent = tmp->dt->parent; + } + + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + + mount->root = tmp; + return 0; +} + +int tmpfs_create(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* tmp; + tmpfs_lookup(dir_node,&tmp,component_name); + if(tmp != NULL){ + *target = NULL; + return -1; + } + tmp = allo_vnode(); + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = tmpfs_fops; + tmp->internal = malloc(0x100); + delete_last_mem(); + memset(tmp->internal,0,0x100); + tmp->v_ops = tmpfs_vops; + tmp->f_ops = tmpfs_fops; + tmp->size = 0; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = file; + *target = tmp; + + struct link_list *parent_ll = dir_node->dt->childs; + while(parent_ll->next!=NULL)parent_ll = parent_ll->next; + parent_ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_ll->next->entry = tmp->dt; + parent_ll->next->next = NULL; + return 0; +} + +int tmpfs_mkdir(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* temp; + tmpfs_lookup(dir_node,&temp,component_name); + if(temp != NULL){ + *target = NULL; + return -1; + } + struct vnode *tmp = allo_vnode(); + struct dentry *tmp_child = allo_dentry(),*tmp_parent = allo_dentry(); + + strcpy(component_name,tmp->dt->name,16); + tmp->f_ops = tmpfs_fops; + tmp->v_ops = tmpfs_vops; + tmp->mount = NULL; + tmp->size = 0; + + tmp->dt->parent = dir_node->dt; + tmp->dt->childs = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->entry = tmp_child; + tmp->dt->childs->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp->dt->childs->next->entry = tmp_parent; + tmp->dt->childs->next->next = NULL; + tmp->dt->vnode = tmp; + tmp->dt->type = directory; + *target = tmp; + + tmp_child->name[0] = '.'; + tmp_child->name[1] = 0; + tmp_child->vnode = tmp; + tmp_child->childs = tmp->dt->childs; + tmp_child->type = directory; + tmp_child->parent = tmp->dt->parent; + + tmp_parent->name[0] = '.'; + tmp_parent->name[1] = '.'; + tmp_parent->name[2] = 0; + tmp_parent->vnode = tmp->dt->parent->vnode; + tmp_parent->childs = tmp->dt->parent->childs; + tmp_parent->type = directory; + tmp_parent->parent = tmp->dt->parent->parent; + + struct link_list *tmp_parent_child = tmp_parent->childs; + while(tmp_parent_child->next != NULL) tmp_parent_child = tmp_parent_child->next; + tmp_parent_child->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + tmp_parent_child->next->next = NULL; + tmp_parent_child->next->entry = tmp->dt; + + return 0; +} + +int tmpfs_lookup(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct link_list* tmp = dir_node->dt->childs; + while(tmp != NULL){ + struct dentry* den_tmp = tmp->entry; + if(strcmp(den_tmp->name,component_name)){ + *target = den_tmp->vnode; + return 0; + } + tmp = tmp->next; + } + *target = NULL; + return -1; +} + +int tmpfs_write(struct file* file, const void* buf, size_t len){ + char *internal = file->vnode->internal, *tmp = buf; + for(int i=0;if_pos++] = tmp[i]; + //if(tmp[i] == EOF) return i; + } + return len; +} + +int tmpfs_read(struct file* file, void* buf, size_t len){ + char *internal = file->vnode->internal, *tmp = buf; + for(int i=0;if_pos++]; + if(tmp[i] == EOF) return i; + } + return len; +} + +int tmpfs_open(struct vnode* file_node, struct file** target){ + struct file* tmp = malloc(sizeof(struct file)); + delete_last_mem(); + tmp->f_pos = 0; + tmp->f_ops = tmpfs_fops; + tmp->vnode = file_node; + *target = tmp; + return 0; +} + +int tmpfs_close(struct file* file){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + free(file); + return 0; +} + +long tmpfs_lseek64(struct file* file, long offset, int whence){ + if(file->f_pos > file->vnode->size) file->vnode->size = file->f_pos; + if(whence == SEEK_END){ + file->f_pos = file->vnode->size + offset; + return file->f_pos; + }else if(whence == SEEK_CUR){ + file->f_pos += offset; + return file->f_pos; + }else if(whence == SEEK_SET){ + file->f_pos = offset; + return file->f_pos; + } +} + +int tmpfs_mknod(struct vnode* dir_node, struct vnode** target, const char* component_name){ + struct vnode* tmp; + tmpfs_lookup(dir_node,&tmp,component_name); + if(tmp != NULL){ + *target = NULL; + return -1; + } + tmp = allo_vnode(); + strcpy(component_name,tmp->dt->name,16); + tmp->size = 0; + tmp->dt->type = device; + tmp->dt->vnode = tmp; + tmp->mount = NULL; + *target = tmp; + + struct link_list *parent_ll = dir_node->dt->childs; + while(parent_ll->next!=NULL)parent_ll = parent_ll->next; + parent_ll->next = malloc(sizeof(struct link_list)); + delete_last_mem(); + parent_ll->next->entry = tmp->dt; + parent_ll->next->next = NULL; + return 0; +} diff --git a/lab8/src/vfs.c b/lab8/src/vfs.c new file mode 100644 index 000000000..33249f41a --- /dev/null +++ b/lab8/src/vfs.c @@ -0,0 +1,339 @@ +#include "uint.h" +#include "vfs.h" +#include "allocator.h" +#include "cpio.h" +#include "string.h" +#include "list.h" +#include "mini_uart.h" +#include "thread.h" +#include "scheduler.h" + +struct mount* rootfs; +struct link_list* filesystem_pool = NULL; +struct device *dv[100]; + + +struct filesystem* find_filesystem(const char *name){ + struct link_list* fs_pool = filesystem_pool; + while(fs_pool != NULL){ + struct filesystem *fs = fs_pool->entry; + if(strcmp(fs->name,name)) return fs; + fs_pool = fs_pool->next; + } + return NULL; +} + +struct device* find_device(const char *name){ + for(int i=0;i<100;i++){ + if(strcmp(name,dv[i]->name)){ + return dv[i]; + } + } + return NULL; +} + +void vfs_init(){ + rootfs = malloc(sizeof(struct mount)); + rootfs->root = NULL; + for(int i=0;i<100;i++) dv[i] = NULL; +} + +int register_filesystem(struct filesystem* fs) { + // register the file system to the kernel. + // you can also initialize memory pool of the file system here. + struct link_list *tmp_pool; + if(filesystem_pool == NULL){ + tmp_pool = malloc(sizeof(struct link_list)); + filesystem_pool = tmp_pool; + }else{ + tmp_pool = filesystem_pool; + while(tmp_pool->next != NULL) tmp_pool = tmp_pool->next; + tmp_pool->next = malloc(sizeof(struct link_list)); + tmp_pool = tmp_pool->next; + } + tmp_pool->next = NULL; + tmp_pool->entry = fs; + return 0; +} + +int register_device(struct device* d) { + for(int i=0;i<100;i++){ + if(dv[i] == NULL){ + dv[i] = d; + return 0; + } + } + return -1; +} + +int vfs_open(const char* pathname, int flags, struct file** target) { + // 1. Lookup pathname + // 2. Create a new file handle for this vnode if found. + // 3. Create a new file if O_CREAT is specified in flags and vnode not found + // lookup error code shows if file exist or not or other error occurs + // 4. Return error code if fails + + struct vnode* filenode; + int errno; + if((errno = vfs_lookup(pathname,&filenode)) < 0){ + if(flags & O_CREAT){ + int last_slash = 0; + for(int i=0;pathname[i]!=0 && i<256;i++){ + if(pathname[i] == '/') last_slash = i; + } + char filename[256]; + memset(filename,0,256); + if(last_slash!=0) + for(int i=0;iv_ops->create(parent,&filenode,filename)) <0 ){ + return errno; + } + }else return errno; + } + int return_value = filenode->f_ops->open(filenode,target); + (*target)->flags = flags; + return return_value; +} + +int vfs_close(struct file* file) { + // 1. release the file handle + // 2. Return error code if fails + return file->f_ops->close(file); +} + +int vfs_write(struct file* file, const void* buf, size_t len) { + // 1. write len byte from buf to the opened file. + // 2. return written size or error code if an error occurs. + if(file == NULL) return -1; + return file->f_ops->write(file,buf,len); +} + +int vfs_read(struct file* file, void* buf, size_t len) { + // 1. read min(len, readable size) byte to buf from the opened file. + // 2. block if nothing to read for FIFO type + // 2. return read size or error code if an error occurs. + if(file == NULL) return -1; + return file->f_ops->read(file,buf,len); +} + +int vfs_mkdir(const char* pathname){ + int last_slash = 0; + char path[256], component[256]; + memset(path,0,256); + memset(component,0,256); + for(int i=0;i<256;i++){ + if(pathname[i] == '/' && pathname[i+1]!=0 && pathname[i+1]!=' ') last_slash = i; + if(pathname[i] == 0) break; + } + for(int i=0;iv_ops->mkdir(target,&target2, component); + if(errno >= 0) target2->mount = NULL; + return errno; +} + +int vfs_mount(const char* target, const char* filesystem){ + struct vnode* mountpoint; + int errno; + if((errno = vfs_lookup(target,&mountpoint)) < 0){ + return errno; + } + struct filesystem *fs = find_filesystem(filesystem); + + + if(fs == NULL) return -1; + + if(mountpoint->mount != NULL){ + return -1; + } + + mountpoint->mount = malloc(sizeof(struct mount)); + mountpoint->mount->fs = fs; + mountpoint->mount->root = mountpoint; + + return fs->setup_mount(fs,mountpoint->mount); +} + +int vfs_lookup(const char* pathname, struct vnode** target){ + struct thread *t = get_current(); + struct vnode* CurrWorkDir = t->CurWorkDir; + char *parse = malloc(16); + memset(parse, 0, 16); + int idx = 0; + for(int i=0;i<256;i++){ + if(pathname[i] == '/'){ + if(i == 0){ + CurrWorkDir = rootfs->root; + } + else{ + if(CurrWorkDir->dt->type != directory) return -1; + struct vnode* tmp; + int errno; + if((errno = CurrWorkDir->v_ops->lookup(CurrWorkDir,&tmp,parse)) < 0){ + return errno; + } + if(tmp->mount != NULL && tmp->mount->root!=NULL) tmp = tmp->mount->root; + CurrWorkDir = tmp; + memset(parse, 0, 16); + idx = 0; + } + }else if(pathname[i] == 0){ + if(idx == 0){ + *target = CurrWorkDir; + return 0; + } + else{ + if(CurrWorkDir->dt->type != directory) return -1; + struct vnode* tmp; + int errno; + if((errno = CurrWorkDir->v_ops->lookup(CurrWorkDir,target,parse)) < 0){ + return errno; + } + if((*target)->dt->type == directory && (*target)->mount != NULL && (*target)->mount->root!=NULL) *target = (*target)->mount->root; + return 0; + } + }else{ + parse[idx++] = pathname[i]; + } + } + return -2; +} + +int vfs_mknod(const char* pathname, const char* device){ + int errno; + struct vnode *tmp,*target; + if(vfs_lookup(pathname,&tmp) >= 0){ + return -1; + } + int last_slash = -1; + char path[256], component[256]; + memset(path,0,256); + memset(component,0,256); + for(int i=0;i<256;i++){ + if(pathname[i] == '/' && pathname[i+1]!=0 && pathname[i+1]!=' ') last_slash = i; + if(pathname[i] == 0) break; + } + for(int i=0;iCurWorkDir; + }else{ + if(last_slash == 0)path[0] = '/'; + vfs_lookup(path,&tmp); + } + for(int i=last_slash+1;i<256;i++){ + if(pathname[i] == 0)break; + component[i-last_slash-1] = pathname[i]; + } + errno = tmp->v_ops->mknod(tmp,&target,component); + if(errno < 0) return errno; + struct device *d = find_device(device); + if(d == NULL) return -2; + errno = d->setup(d,target); + return errno; +} + +long vfs_lseek(struct file* f, long offset, int whence){ + return f->f_ops->lseek64(f,offset,whence); +} + +void vfs_ls(const char* pathname){ + struct vnode *tmp; + if(pathname[0] == 0){ + vfs_lookup("/",&tmp); + }else{ + int errno; + if((errno = vfs_lookup(pathname,&tmp)) <0){ + uart_printf("File not found: %s\n",pathname); + return; + } + } + if(tmp->dt->type == directory){ + struct link_list* ll = tmp->dt->childs; + while(ll != NULL){ + struct dentry* tmp2 = ll->entry; + uart_printf("%s ",tmp2->name); + ll = ll->next; + } + uart_printf("\n"); + }else{ + uart_printf("%s\n",tmp->dt->name); + } +} + +void vfs_cd(const char* pathname){ + struct thread *t = get_current(); + + vfs_lookup(pathname, &(t->CurWorkDir)); +} + +void vfs_cat(const char* pathname){ + char buf[512]; + struct file* f; + if(vfs_open(pathname,0,&f) < 0){ + printf("Error. No such file or directory.\n"); + return; + } + while(1){ + int i = vfs_read(f,buf,512); + printf("%s",buf); + if(i!=512) return; + } +} + +struct vnode* allo_vnode(){ + struct vnode* vn = malloc(sizeof(struct vnode)); + delete_last_mem(); + vn->mount = NULL; + vn->dt = allo_dentry(); + return vn; +} + +struct dentry* allo_dentry(){ + struct dentry* de = malloc(sizeof(struct dentry)); + delete_last_mem(); + memset(de->name,0,32); + return de; +} + +int vfs_sync(){ + struct vnode* start; + if(vfs_lookup("/boot",&start) < 0) return -1; + /*else{ + struct link_list *ll = start->dt->childs; + while(ll != NULL){ + struct dentry* d = ll->entry; + if(d->name[0] != '.'){ + d->vnode->v_ops->sync(start, d->vnode); + } + ll = ll->next; + } + return 0; + }*/ + start->v_ops->sync(NULL,start); +} + +int do_nothing(){ + return 0; +} \ No newline at end of file diff --git a/lab8/user/include/system.h b/lab8/user/include/system.h new file mode 100644 index 000000000..9a8aea0de --- /dev/null +++ b/lab8/user/include/system.h @@ -0,0 +1,27 @@ +#include "type.h" +#ifndef __system__ +#define __system__ + +/* +SCN : function +0 : int getpid() +1 : size_t uartread(char buf[], size_t size) +2 : size_t uartwrite(const char buf[], size_t size) +3 : int exec(const char *name, char *const argv[]) +4 : int fork() +5 : void exit(int status) +6 : int mbox_call(unsigned char ch, unsigned int *mbox) +7 : void kill(int pid) +*/ + +int getpid(); +size_t uart_read(char buf[], size_t size); +size_t uart_write(const char buf[], size_t size); +int exec(const char* name, char *const argv[]); +int fork(); +void exit(); +int mbox_call(unsigned char ch, unsigned int *mbox); +void kill(int pid); + + +#endif \ No newline at end of file diff --git a/lab8/user/include/type.h b/lab8/user/include/type.h new file mode 100644 index 000000000..6a773a4ac --- /dev/null +++ b/lab8/user/include/type.h @@ -0,0 +1,15 @@ +#ifndef __type__ +#define __type__ + +#define byte unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned long long +#define size_t uint32_t +#define NULL (void*)0 +#define bool byte +#define false 0 +#define true 1 +#define tid_t uint32_t + +#endif \ No newline at end of file diff --git a/lab8/user/out/main.o b/lab8/user/out/main.o new file mode 100644 index 000000000..d4fb3b0e7 Binary files /dev/null and b/lab8/user/out/main.o differ diff --git a/lab8/user/out/system.o b/lab8/user/out/system.o new file mode 100644 index 000000000..029fe5fb4 Binary files /dev/null and b/lab8/user/out/system.o differ diff --git a/lab8/user/src/main.c b/lab8/user/src/main.c new file mode 100644 index 000000000..886d87da7 --- /dev/null +++ b/lab8/user/src/main.c @@ -0,0 +1,7 @@ +#include "system.h" + +int main(){ + char a[] = "How are you\n"; + uart_write(a,sizeof(a)); + exit(); +} \ No newline at end of file diff --git a/lab8/user/src/system.S b/lab8/user/src/system.S new file mode 100644 index 000000000..fc9734502 --- /dev/null +++ b/lab8/user/src/system.S @@ -0,0 +1,49 @@ +.global getpid +getpid: + mov x8, #0 + svc #0 + ret + +.global uart_read +uart_read: + mov x8, #1 + svc #0 + ret + +.global uart_write +uart_write: + mov x8, #2 + svc #0 + ret + +.global exec +exec: + mov x8, #3 + svc #0 + ret + +.global fork +fork: + mov x8, #4 + svc #0 + ret + +.global exit +exit: + mov x8, #5 + svc #0 + ret + +.global mbox_call +mbox_call: + mov x8, #6 + svc #0 + ret + +.global kill +kill: + mov x8, #7 + svc #0 + ret + +