From 28a1f7d5a2097ff0534950ab0a098039e546c376 Mon Sep 17 00:00:00 2001 From: KAAAsS Date: Sun, 16 May 2021 14:00:20 +0800 Subject: [PATCH] finish exec3.4-8 --- lab3/.gdbinit | 2 +- lab3/kernel/exception/exception_table.S | 2 ++ lab3/kernel/syscall/syscall.c | 9 +++++++ lab3/kernel/syscall/syscall_num.h | 8 +++---- lab3/user/lib/libmain.c | 1 + lab3/user/lib/syscall.c | 31 +++++++++++++++++++++---- note.org | 17 ++++++++++++++ 7 files changed, 61 insertions(+), 9 deletions(-) diff --git a/lab3/.gdbinit b/lab3/.gdbinit index 3070b32..598decb 100644 --- a/lab3/.gdbinit +++ b/lab3/.gdbinit @@ -13,4 +13,4 @@ define add-symbol-file-auto end add-symbol-file-auto ./build/kernel.img -add-symbol-file-auto ./user/build/ramdisk/badinsn.bin +add-symbol-file-auto ./user/build/ramdisk/hello.bin diff --git a/lab3/kernel/exception/exception_table.S b/lab3/kernel/exception/exception_table.S index 5431cf8..547d380 100644 --- a/lab3/kernel/exception/exception_table.S +++ b/lab3/kernel/exception/exception_table.S @@ -180,6 +180,7 @@ sync_el0_64: exception_exit el0_syscall: + // 保存现场 sub sp, sp, #16 * 8 stp x0, x1, [sp, #16 * 0] stp x2, x3, [sp, #16 * 1] @@ -199,6 +200,7 @@ el0_syscall: ldp x14, x15, [sp, #16 * 7] add sp, sp, #16 * 8 + // 系统调用号左移 2 位作为系统调用表偏移 adr x27, syscall_table // syscall table in x27 uxtw x16, w8 // syscall number in x16 ldr x16, [x27, x16, lsl #3] // find the syscall entry diff --git a/lab3/kernel/syscall/syscall.c b/lab3/kernel/syscall/syscall.c index b1c9111..6cc8389 100644 --- a/lab3/kernel/syscall/syscall.c +++ b/lab3/kernel/syscall/syscall.c @@ -29,8 +29,11 @@ void sys_putc(char ch) * Lab3: Your code here * Send ch to the screen in anyway as your like */ + uart_send(ch); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winitializer-overrides" /* * Lab3: Your code here * Update the syscall table as you like to redirect syscalls @@ -38,5 +41,11 @@ void sys_putc(char ch) */ const void *syscall_table[NR_SYSCALL] = { [0 ... NR_SYSCALL - 1] = sys_debug, + [SYS_putc] = sys_putc, + [SYS_exit] = sys_exit, + [SYS_create_pmo] = sys_create_pmo, + [SYS_map_pmo] = sys_map_pmo, + [SYS_handle_brk] = sys_handle_brk, /* lab3 syscalls finished */ }; +#pragma clang diagnostic pop diff --git a/lab3/kernel/syscall/syscall_num.h b/lab3/kernel/syscall/syscall_num.h index 0c5f952..0fbf940 100644 --- a/lab3/kernel/syscall/syscall_num.h +++ b/lab3/kernel/syscall/syscall_num.h @@ -14,10 +14,10 @@ #define NR_SYSCALL 256 -void sys_exit(void); -void sys_create_pmo(void); -void sys_map_pmo(void); -void sys_handle_brk(void); +void sys_exit(int ret); +int sys_create_pmo(u64 size, u64 type); +int sys_map_pmo(u64 target_process_cap, u64 pmo_cap, u64 addr, u64 perm); +u64 sys_handle_brk(u64 addr); /* lab3 syscalls finished */ #define SYS_putc 0 diff --git a/lab3/user/lib/libmain.c b/lab3/user/lib/libmain.c index 7cfcab6..9c6da65 100644 --- a/lab3/user/lib/libmain.c +++ b/lab3/user/lib/libmain.c @@ -13,5 +13,6 @@ void _start_c(long *p) * Lab3: Your code here * Complete the main function */ + usys_exit(ret); return; } diff --git a/lab3/user/lib/syscall.c b/lab3/user/lib/syscall.c index 0bc95c9..22e8185 100644 --- a/lab3/user/lib/syscall.c +++ b/lab3/user/lib/syscall.c @@ -13,7 +13,28 @@ u64 syscall(u64 sys_no, u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, * And finally use svc to execute the system call. After syscall returned, don't forget * to move return value from x0 to the ret variable of this function */ - return ret; + + __asm __volatile("mov x9, %0"::"r"(sys_no)); + + // 参数 +#define SET_ARG(n) __asm __volatile("mov x"#n", %0"::"r"(arg##n)); + SET_ARG(0); + SET_ARG(1); + SET_ARG(2); + SET_ARG(3); + SET_ARG(4); + SET_ARG(5); + SET_ARG(6); + SET_ARG(7); + + // 系统调用 + __asm __volatile("mov x8, x9"); + __asm ("svc #0"); + + // 返回值 + __asm __volatile("mov %0, x0":"=r"(ret)); + + return ret; } /* @@ -22,25 +43,27 @@ u64 syscall(u64 sys_no, u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, */ void usys_putc(char ch) { + syscall(SYS_putc, ch, 0, 0, 0, 0, 0, 0, 0, 0); } void usys_exit(int ret) { + syscall(SYS_exit, ret, 0, 0, 0, 0, 0, 0, 0, 0); } int usys_create_pmo(u64 size, u64 type) { - return 0; + return (int) syscall(SYS_create_pmo, size, type, 0, 0, 0, 0, 0, 0, 0); } int usys_map_pmo(u64 process_cap, u64 pmo_cap, u64 addr, u64 rights) { - return 0; + return (int) syscall(SYS_map_pmo, process_cap, pmo_cap, addr, rights, 0, 0, 0, 0, 0); } u64 usys_handle_brk(u64 addr) { - return 0; + return syscall(SYS_handle_brk, addr, 0, 0, 0, 0, 0, 0, 0, 0); } /* Here finishes all syscalls need by lab3 */ diff --git a/note.org b/note.org index 12725f6..ae49152 100644 --- a/note.org +++ b/note.org @@ -156,3 +156,20 @@ ELF Section、Segment 两个概念。 *** 练习2 process_create_root、thread_create_main 直接写在注释里面了。 + +*** 练习4 + +见注释 + +*** 练习5 + +基本就是移动参数寄存器然后 svc。注意要先保存 x0 寄存器到另一寄存器。 + +*** 练习7 + +主要原因是 libmain 中跳转都是使用 b 指令(没有填写链接寄存器),因此执行到 main 的 ret 时链接寄存器值为 0, +程序就返回到 0x0 处执行了。由此触发指令异常。 + +*** 练习8 + +这个是最离谱的。所谓退出其实就是输出里出现了“breakpoint”。实际上程序并不会退出(评测机倒是会)。