From 2dde56422dcfb94affee2baffc8d240ad16ad4b2 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Thu, 1 Jan 2026 15:04:47 +0800 Subject: dev(device): implement VirtIO See dev log for detail --- include/drivers/virtio.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 include/drivers/virtio.h (limited to 'include/drivers/virtio.h') diff --git a/include/drivers/virtio.h b/include/drivers/virtio.h new file mode 100644 index 0000000..308dae0 --- /dev/null +++ b/include/drivers/virtio.h @@ -0,0 +1,102 @@ +#pragma once +#include "common/types.h" + +// VirtIO MMIO Base Address +#define VIRTIO0 0x10001000 + +// MMIO Registers (Modern / Version 2) +#define VIRTIO_MMIO_MAGIC_VALUE 0x000 +#define VIRTIO_MMIO_VERSION 0x004 +#define VIRTIO_MMIO_DEVICE_ID 0x008 +#define VIRTIO_MMIO_VENDOR_ID 0x00c +#define VIRTIO_MMIO_DEVICE_FEATURES 0x010 +#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014 +#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 +#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024 +#define VIRTIO_MMIO_QUEUE_SEL 0x030 +#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 +#define VIRTIO_MMIO_QUEUE_NUM 0x038 +#define VIRTIO_MMIO_QUEUE_READY 0x044 +#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 +#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 +#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 +#define VIRTIO_MMIO_STATUS 0x070 + +// 64-bit Queue Address Registers (Modern) +#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 +#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 +#define VIRTIO_MMIO_QUEUE_DRIVER_LOW 0x090 +#define VIRTIO_MMIO_QUEUE_DRIVER_HIGH 0x094 +#define VIRTIO_MMIO_QUEUE_DEVICE_LOW 0x0a0 +#define VIRTIO_MMIO_QUEUE_DEVICE_HIGH 0x0a4 + +// Status Bits +#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 +#define VIRTIO_CONFIG_S_DRIVER 2 +#define VIRTIO_CONFIG_S_DRIVER_OK 4 +#define VIRTIO_CONFIG_S_FEATURES_OK 8 + +// Feature Bits +#define VIRTIO_BLK_F_RO 5 +#define VIRTIO_BLK_F_SCSI 7 +#define VIRTIO_BLK_F_CONFIG_WCE 11 +#define VIRTIO_BLK_F_MQ 12 +#define VIRTIO_F_ANY_LAYOUT 27 +#define VIRTIO_RING_F_INDIRECT_DESC 28 +#define VIRTIO_RING_F_EVENT_IDX 29 +#define VIRTIO_F_VERSION_1 32 + +// Descriptor Flags +#define VRING_DESC_F_NEXT 1 +#define VRING_DESC_F_WRITE 2 + +#define NUM_DESCS 8 + +#define VIRTIO_BLK_T_IN 0 +#define VIRTIO_BLK_T_OUT 1 + +// Device Configuration Layout (Offset 0x100) +#define VIRTIO_MMIO_CONFIG 0x100 + +namespace VirtIO +{ + struct VRingDesc + { + uint64 addr; + uint32 len; + uint16 flags; + uint16 next; + }; + + struct VRingAvail + { + uint16 flags; + uint16 idx; + uint16 ring[NUM_DESCS]; + }; + + struct VRingUsedElem + { + uint32 id; + uint32 len; + }; + + struct VRingUsed + { + uint16 flags; + uint16 idx; + struct VRingUsedElem ring[NUM_DESCS]; + }; + + struct __attribute__((packed)) BlockRequest + { + uint32 type; // 0=Read, 1=Write + uint32 reserved; + uint64 sector; + }; + + void init(); + void intr(); + void rw(int write, uint64 blockno, char *buf); + void test_rw(); +} \ No newline at end of file -- cgit v1.2.3 From d8eaa13f2efc1eeca4e5f230d5a2d535aaf27338 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Fri, 2 Jan 2026 00:47:16 +0800 Subject: dev(file-system): establish VFS and Read-only FAT32 File System --- build/kernel.elf | Bin 184056 -> 248784 bytes build/src/drivers/virtio_dist.o | Bin 93248 -> 104488 bytes build/src/fs/fat32.o | Bin 0 -> 165984 bytes build/src/fs/file.o | Bin 0 -> 51760 bytes build/src/fs/fs.o | Bin 0 -> 74136 bytes build/src/kernel/bio.o | Bin 0 -> 53432 bytes build/src/kernel/cxx.o | Bin 0 -> 19936 bytes build/src/kernel/initcode.o | Bin 3952 -> 4368 bytes build/src/kernel/main.o | Bin 19608 -> 21336 bytes build/src/kernel/mm/pmm.o | Bin 90424 -> 90360 bytes build/src/kernel/mm/vm.o | Bin 214608 -> 227848 bytes build/src/kernel/proc/proc.o | Bin 212272 -> 221432 bytes build/src/kernel/syscall.o | Bin 61936 -> 91592 bytes build/src/lib/string.o | Bin 27632 -> 31608 bytes build/user/init.o | Bin 112536 -> 121792 bytes build/user/initcode | Bin 2928 -> 3344 bytes build/user/initcode.asm | 1377 +++++++++++++++++++++------------------ build/user/initcode.out | Bin 22440 -> 23808 bytes fs.img | Bin 1048576 -> 33554432 bytes include/common/fcntl.h | 9 + include/drivers/virtio.h | 1 + include/fs/fat32.h | 111 ++++ include/fs/file.h | 35 + include/fs/fs.h | 92 +++ include/fs/stat.h | 22 + include/kernel/buf.h | 30 + include/kernel/elf.h | 46 ++ include/kernel/exec.h | 6 + include/kernel/mm.h | 1 + include/kernel/proc_def.h | 6 + include/lib/string.h | 3 +- src/drivers/virtio_dist.cc | 36 + src/fs/fat32.cc | 325 +++++++++ src/fs/file.cc | 140 ++++ src/fs/fs.cc | 190 ++++++ src/kernel/bio.cc | 135 ++++ src/kernel/cxx.cc | 68 ++ src/kernel/main.cc | 8 + src/kernel/mm/vm.cc | 47 ++ src/kernel/proc/proc.cc | 33 + src/kernel/syscall.cc | 165 ++++- src/lib/string.cc | 13 + src/user/init.cc | 36 +- 43 files changed, 2253 insertions(+), 682 deletions(-) create mode 100644 build/src/fs/fat32.o create mode 100644 build/src/fs/file.o create mode 100644 build/src/fs/fs.o create mode 100644 build/src/kernel/bio.o create mode 100644 build/src/kernel/cxx.o create mode 100644 include/common/fcntl.h create mode 100644 include/fs/fat32.h create mode 100644 include/fs/file.h create mode 100644 include/fs/fs.h create mode 100644 include/fs/stat.h create mode 100644 include/kernel/buf.h create mode 100644 include/kernel/elf.h create mode 100644 include/kernel/exec.h create mode 100644 src/fs/fat32.cc create mode 100644 src/fs/file.cc create mode 100644 src/fs/fs.cc create mode 100644 src/kernel/bio.cc create mode 100644 src/kernel/cxx.cc (limited to 'include/drivers/virtio.h') diff --git a/build/kernel.elf b/build/kernel.elf index 902f32b..cf12d9c 100755 Binary files a/build/kernel.elf and b/build/kernel.elf differ diff --git a/build/src/drivers/virtio_dist.o b/build/src/drivers/virtio_dist.o index cc608ca..594b0e7 100644 Binary files a/build/src/drivers/virtio_dist.o and b/build/src/drivers/virtio_dist.o differ diff --git a/build/src/fs/fat32.o b/build/src/fs/fat32.o new file mode 100644 index 0000000..978eb14 Binary files /dev/null and b/build/src/fs/fat32.o differ diff --git a/build/src/fs/file.o b/build/src/fs/file.o new file mode 100644 index 0000000..7dc96e9 Binary files /dev/null and b/build/src/fs/file.o differ diff --git a/build/src/fs/fs.o b/build/src/fs/fs.o new file mode 100644 index 0000000..dd6a386 Binary files /dev/null and b/build/src/fs/fs.o differ diff --git a/build/src/kernel/bio.o b/build/src/kernel/bio.o new file mode 100644 index 0000000..578821b Binary files /dev/null and b/build/src/kernel/bio.o differ diff --git a/build/src/kernel/cxx.o b/build/src/kernel/cxx.o new file mode 100644 index 0000000..a115a07 Binary files /dev/null and b/build/src/kernel/cxx.o differ diff --git a/build/src/kernel/initcode.o b/build/src/kernel/initcode.o index a1c9bd8..0bfbd9e 100644 Binary files a/build/src/kernel/initcode.o and b/build/src/kernel/initcode.o differ diff --git a/build/src/kernel/main.o b/build/src/kernel/main.o index df27b46..6b663cd 100644 Binary files a/build/src/kernel/main.o and b/build/src/kernel/main.o differ diff --git a/build/src/kernel/mm/pmm.o b/build/src/kernel/mm/pmm.o index db30140..b0bdecf 100644 Binary files a/build/src/kernel/mm/pmm.o and b/build/src/kernel/mm/pmm.o differ diff --git a/build/src/kernel/mm/vm.o b/build/src/kernel/mm/vm.o index 5d30dcd..8743310 100644 Binary files a/build/src/kernel/mm/vm.o and b/build/src/kernel/mm/vm.o differ diff --git a/build/src/kernel/proc/proc.o b/build/src/kernel/proc/proc.o index ad606f0..7ae741b 100644 Binary files a/build/src/kernel/proc/proc.o and b/build/src/kernel/proc/proc.o differ diff --git a/build/src/kernel/syscall.o b/build/src/kernel/syscall.o index d398c30..bc3200e 100644 Binary files a/build/src/kernel/syscall.o and b/build/src/kernel/syscall.o differ diff --git a/build/src/lib/string.o b/build/src/lib/string.o index 6d50c43..6818c98 100644 Binary files a/build/src/lib/string.o and b/build/src/lib/string.o differ diff --git a/build/user/init.o b/build/user/init.o index aea18f2..6380026 100644 Binary files a/build/user/init.o and b/build/user/init.o differ diff --git a/build/user/initcode b/build/user/initcode index b6ac9a3..ef0eb5a 100755 Binary files a/build/user/initcode and b/build/user/initcode differ diff --git a/build/user/initcode.asm b/build/user/initcode.asm index 1cb4088..99769f6 100644 --- a/build/user/initcode.asm +++ b/build/user/initcode.asm @@ -15,15 +15,15 @@ _start: 2: 4581 li a1,0 call main - 4: 578000ef jal 57c
+ 4: 57a000ef jal 57e
call exit - 8: 648000ef jal 650 + 8: 706000ef jal 70e c: a001 j c <_start+0xc> 000000000000000e <_Z6strlenPKc>: -// ============================================================= +#include "common/fcntl.h" int strlen(const char *s) { @@ -55,7 +55,7 @@ void print(const char *s) { 32: 85aa mv a1,a0 while (s[n]) - 34: cf89 beqz a5,4e <_Z5printPKc+0x20> + 34: cf91 beqz a5,50 <_Z5printPKc+0x22> 36: 00150693 addi a3,a0,1 3a: 87b6 mv a5,a3 3c: 0007c703 lbu a4,0(a5) @@ -67,987 +67,1070 @@ void print(const char *s) 48: 2605 addiw a2,a2,1 write(1, s, strlen(s)); 4a: 4505 li a0,1 - 4c: a515 j 670 + 4c: 6e20006f j 72e int n = 0; - 4e: 4601 li a2,0 + 50: 4601 li a2,0 write(1, s, strlen(s)); - 50: 4505 li a0,1 - 52: ad39 j 670 + 52: 4505 li a0,1 + 54: ade9 j 72e -0000000000000054 <_Z9print_inti>: +0000000000000056 <_Z9print_inti>: void print_int(int n) { char buf[16]; int i = 0; int neg = 0; if (n == 0) - 54: c149 beqz a0,d6 <_Z9print_inti+0x82> + 56: c149 beqz a0,d8 <_Z9print_inti+0x82> { - 56: 7179 addi sp,sp,-48 - 58: f406 sd ra,40(sp) - 5a: f022 sd s0,32(sp) - 5c: ec26 sd s1,24(sp) + 58: 7179 addi sp,sp,-48 + 5a: f406 sd ra,40(sp) + 5c: f022 sd s0,32(sp) + 5e: ec26 sd s1,24(sp) int neg = 0; - 5e: 4801 li a6,0 + 60: 4801 li a6,0 { write(1, "0", 1); return; } if (n < 0) - 60: 04054c63 bltz a0,b8 <_Z9print_inti+0x64> - 64: 840a mv s0,sp + 62: 04054c63 bltz a0,ba <_Z9print_inti+0x64> + 66: 840a mv s0,sp { neg = 1; - 66: 86a2 mv a3,s0 - 68: 4701 li a4,0 + 68: 86a2 mv a3,s0 + 6a: 4701 li a4,0 n = -n; } while (n > 0) { buf[i++] = (n % 10) + '0'; - 6a: 4629 li a2,10 - 6c: 02c567bb remw a5,a0,a2 + 6c: 4629 li a2,10 + 6e: 02c567bb remw a5,a0,a2 while (n > 0) - 70: 0685 addi a3,a3,1 - 72: 85ba mv a1,a4 + 72: 0685 addi a3,a3,1 + 74: 85ba mv a1,a4 buf[i++] = (n % 10) + '0'; - 74: 2705 addiw a4,a4,1 + 76: 2705 addiw a4,a4,1 n /= 10; - 76: 02c5453b divw a0,a0,a2 + 78: 02c5453b divw a0,a0,a2 buf[i++] = (n % 10) + '0'; - 7a: 0307879b addiw a5,a5,48 - 7e: fef68fa3 sb a5,-1(a3) + 7c: 0307879b addiw a5,a5,48 + 80: fef68fa3 sb a5,-1(a3) while (n > 0) - 82: f56d bnez a0,6c <_Z9print_inti+0x18> + 84: f56d bnez a0,6e <_Z9print_inti+0x18> } if (neg) - 84: 02081e63 bnez a6,c0 <_Z9print_inti+0x6c> - 88: fff7079b addiw a5,a4,-1 - 8c: ffe40493 addi s1,s0,-2 - 90: 1782 slli a5,a5,0x20 - 92: fff70693 addi a3,a4,-1 - 96: 94ba add s1,s1,a4 - 98: 9381 srli a5,a5,0x20 - 9a: 9436 add s0,s0,a3 - 9c: 8c9d sub s1,s1,a5 + 86: 02081e63 bnez a6,c2 <_Z9print_inti+0x6c> + 8a: fff7079b addiw a5,a4,-1 + 8e: ffe40493 addi s1,s0,-2 + 92: 1782 slli a5,a5,0x20 + 94: fff70693 addi a3,a4,-1 + 98: 94ba add s1,s1,a4 + 9a: 9381 srli a5,a5,0x20 + 9c: 9436 add s0,s0,a3 + 9e: 8c9d sub s1,s1,a5 buf[i++] = '-'; while (i > 0) write(1, &buf[--i], 1); - 9e: 85a2 mv a1,s0 - a0: 4605 li a2,1 - a2: 4505 li a0,1 + a0: 85a2 mv a1,s0 + a2: 4605 li a2,1 + a4: 4505 li a0,1 while (i > 0) - a4: 147d addi s0,s0,-1 + a6: 147d addi s0,s0,-1 write(1, &buf[--i], 1); - a6: 5ca000ef jal 670 + a8: 686000ef jal 72e while (i > 0) - aa: fe849ae3 bne s1,s0,9e <_Z9print_inti+0x4a> + ac: fe849ae3 bne s1,s0,a0 <_Z9print_inti+0x4a> } - ae: 70a2 ld ra,40(sp) - b0: 7402 ld s0,32(sp) - b2: 64e2 ld s1,24(sp) - b4: 6145 addi sp,sp,48 - b6: 8082 ret + b0: 70a2 ld ra,40(sp) + b2: 7402 ld s0,32(sp) + b4: 64e2 ld s1,24(sp) + b6: 6145 addi sp,sp,48 + b8: 8082 ret n = -n; - b8: 40a0053b negw a0,a0 + ba: 40a0053b negw a0,a0 neg = 1; - bc: 4805 li a6,1 - be: b75d j 64 <_Z9print_inti+0x10> + be: 4805 li a6,1 + c0: b75d j 66 <_Z9print_inti+0x10> buf[i++] = '-'; - c0: 01070793 addi a5,a4,16 - c4: 00278733 add a4,a5,sp - c8: 02d00793 li a5,45 - cc: fef70823 sb a5,-16(a4) - d0: 0025871b addiw a4,a1,2 - d4: bf55 j 88 <_Z9print_inti+0x34> + c2: 01070793 addi a5,a4,16 + c6: 00278733 add a4,a5,sp + ca: 02d00793 li a5,45 + ce: fef70823 sb a5,-16(a4) + d2: 0025871b addiw a4,a1,2 + d6: bf55 j 8a <_Z9print_inti+0x34> write(1, "0", 1); - d6: 4605 li a2,1 - d8: 00000597 auipc a1,0x0 - dc: 62858593 addi a1,a1,1576 # 700 - e0: 4505 li a0,1 - e2: a379 j 670 + d8: 4605 li a2,1 + da: 00000597 auipc a1,0x0 + de: 6e658593 addi a1,a1,1766 # 7c0 + e2: 4505 li a0,1 + e4: a5a9 j 72e -00000000000000e4 <_Z9print_hexy>: +00000000000000e6 <_Z9print_hexy>: void print_hex(uint64 n) { char buf[16]; char digits[] = "0123456789ABCDEF"; - e4: 00000797 auipc a5,0x0 - e8: 62c78793 addi a5,a5,1580 # 710 - ec: 6394 ld a3,0(a5) - ee: 6798 ld a4,8(a5) - f0: 0107c783 lbu a5,16(a5) + e6: 00000797 auipc a5,0x0 + ea: 6ea78793 addi a5,a5,1770 # 7d0 + ee: 6394 ld a3,0(a5) + f0: 6798 ld a4,8(a5) + f2: 0107c783 lbu a5,16(a5) { - f4: 715d addi sp,sp,-80 - f6: fc26 sd s1,56(sp) + f6: 715d addi sp,sp,-80 + f8: fc26 sd s1,56(sp) write(1, "0x", 2); - f8: 4609 li a2,2 + fa: 4609 li a2,2 { - fa: 84aa mv s1,a0 + fc: 84aa mv s1,a0 write(1, "0x", 2); - fc: 00000597 auipc a1,0x0 - 100: 60c58593 addi a1,a1,1548 # 708 - 104: 4505 li a0,1 + fe: 00000597 auipc a1,0x0 + 102: 6ca58593 addi a1,a1,1738 # 7c8 + 106: 4505 li a0,1 { - 106: e486 sd ra,72(sp) + 108: e486 sd ra,72(sp) char digits[] = "0123456789ABCDEF"; - 108: ec36 sd a3,24(sp) - 10a: f03a sd a4,32(sp) - 10c: 02f10423 sb a5,40(sp) + 10a: ec36 sd a3,24(sp) + 10c: f03a sd a4,32(sp) + 10e: 02f10423 sb a5,40(sp) write(1, "0x", 2); - 110: 560000ef jal 670 + 112: 61c000ef jal 72e if (n == 0) - 114: cca1 beqz s1,16c <_Z9print_hexy+0x88> - 116: e0a2 sd s0,64(sp) - 118: 0020 addi s0,sp,8 - 11a: 87a2 mv a5,s0 + 116: cca1 beqz s1,16e <_Z9print_hexy+0x88> + 118: e0a2 sd s0,64(sp) + 11a: 0020 addi s0,sp,8 + 11c: 87a2 mv a5,s0 return; } int i = 0; while (n > 0) { buf[i++] = digits[n % 16]; - 11c: 00f4f713 andi a4,s1,15 - 120: 03070713 addi a4,a4,48 - 124: 970a add a4,a4,sp - 126: fe874683 lbu a3,-24(a4) + 11e: 00f4f713 andi a4,s1,15 + 122: 03070713 addi a4,a4,48 + 126: 970a add a4,a4,sp + 128: fe874683 lbu a3,-24(a4) n /= 16; - 12a: 8091 srli s1,s1,0x4 - 12c: 873e mv a4,a5 + 12c: 8091 srli s1,s1,0x4 + 12e: 873e mv a4,a5 buf[i++] = digits[n % 16]; - 12e: 00d78023 sb a3,0(a5) + 130: 00d78023 sb a3,0(a5) while (n > 0) - 132: 0785 addi a5,a5,1 - 134: f4e5 bnez s1,11c <_Z9print_hexy+0x38> - 136: 9f01 subw a4,a4,s0 - 138: 0017079b addiw a5,a4,1 - 13c: fff7871b addiw a4,a5,-1 - 140: ffe40493 addi s1,s0,-2 - 144: 1702 slli a4,a4,0x20 - 146: fff78693 addi a3,a5,-1 - 14a: 94be add s1,s1,a5 - 14c: 9301 srli a4,a4,0x20 - 14e: 9436 add s0,s0,a3 - 150: 8c99 sub s1,s1,a4 + 134: 0785 addi a5,a5,1 + 136: f4e5 bnez s1,11e <_Z9print_hexy+0x38> + 138: 9f01 subw a4,a4,s0 + 13a: 0017079b addiw a5,a4,1 + 13e: fff7871b addiw a4,a5,-1 + 142: ffe40493 addi s1,s0,-2 + 146: 1702 slli a4,a4,0x20 + 148: fff78693 addi a3,a5,-1 + 14c: 94be add s1,s1,a5 + 14e: 9301 srli a4,a4,0x20 + 150: 9436 add s0,s0,a3 + 152: 8c99 sub s1,s1,a4 } while (i > 0) write(1, &buf[--i], 1); - 152: 85a2 mv a1,s0 - 154: 4605 li a2,1 - 156: 4505 li a0,1 + 154: 85a2 mv a1,s0 + 156: 4605 li a2,1 + 158: 4505 li a0,1 while (i > 0) - 158: 147d addi s0,s0,-1 + 15a: 147d addi s0,s0,-1 write(1, &buf[--i], 1); - 15a: 516000ef jal 670 + 15c: 5d2000ef jal 72e while (i > 0) - 15e: fe941ae3 bne s0,s1,152 <_Z9print_hexy+0x6e> - 162: 6406 ld s0,64(sp) + 160: fe941ae3 bne s0,s1,154 <_Z9print_hexy+0x6e> + 164: 6406 ld s0,64(sp) } - 164: 60a6 ld ra,72(sp) - 166: 74e2 ld s1,56(sp) - 168: 6161 addi sp,sp,80 - 16a: 8082 ret - 16c: 60a6 ld ra,72(sp) - 16e: 74e2 ld s1,56(sp) + 166: 60a6 ld ra,72(sp) + 168: 74e2 ld s1,56(sp) + 16a: 6161 addi sp,sp,80 + 16c: 8082 ret + 16e: 60a6 ld ra,72(sp) + 170: 74e2 ld s1,56(sp) write(1, "0", 1); - 170: 4605 li a2,1 - 172: 00000597 auipc a1,0x0 - 176: 58e58593 addi a1,a1,1422 # 700 - 17a: 4505 li a0,1 + 172: 4605 li a2,1 + 174: 00000597 auipc a1,0x0 + 178: 64c58593 addi a1,a1,1612 # 7c0 + 17c: 4505 li a0,1 } - 17c: 6161 addi sp,sp,80 + 17e: 6161 addi sp,sp,80 write(1, "0", 1); - 17e: a9cd j 670 + 180: a37d j 72e -0000000000000180 <_Z13test_syscallsv>: -// ============================================================= -// 系统调用测试套件 -// ============================================================= +0000000000000182 <_Z13test_syscallsv>: void test_syscalls() { - 180: 1101 addi sp,sp,-32 - 182: 00000697 auipc a3,0x0 - 186: 5a668693 addi a3,a3,1446 # 728 - 18a: ec06 sd ra,24(sp) - 18c: e822 sd s0,16(sp) - 18e: e426 sd s1,8(sp) - 190: 87b6 mv a5,a3 + 182: 1101 addi sp,sp,-32 + 184: 00000697 auipc a3,0x0 + 188: 66468693 addi a3,a3,1636 # 7e8 + 18c: ec06 sd ra,24(sp) + 18e: e822 sd s0,16(sp) + 190: e426 sd s1,8(sp) + 192: 87b6 mv a5,a3 while (s[n]) - 192: 0017c703 lbu a4,1(a5) - 196: 863e mv a2,a5 - 198: 0785 addi a5,a5,1 - 19a: ff65 bnez a4,192 <_Z13test_syscallsv+0x12> + 194: 0017c703 lbu a4,1(a5) + 198: 863e mv a2,a5 + 19a: 0785 addi a5,a5,1 + 19c: ff65 bnez a4,194 <_Z13test_syscallsv+0x12> n++; - 19c: 9e15 subw a2,a2,a3 + 19e: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 19e: 2605 addiw a2,a2,1 - 1a0: 00000597 auipc a1,0x0 - 1a4: 58858593 addi a1,a1,1416 # 728 - 1a8: 4505 li a0,1 - 1aa: 4c6000ef jal 670 + 1a0: 2605 addiw a2,a2,1 + 1a2: 00000597 auipc a1,0x0 + 1a6: 64658593 addi a1,a1,1606 # 7e8 + 1aa: 4505 li a0,1 + 1ac: 582000ef jal 72e while (s[n]) - 1ae: 00000697 auipc a3,0x0 - 1b2: 5aa68693 addi a3,a3,1450 # 758 + 1b0: 00000697 auipc a3,0x0 + 1b4: 66868693 addi a3,a3,1640 # 818 write(1, s, strlen(s)); - 1b6: 87b6 mv a5,a3 + 1b8: 87b6 mv a5,a3 while (s[n]) - 1b8: 0017c703 lbu a4,1(a5) - 1bc: 863e mv a2,a5 - 1be: 0785 addi a5,a5,1 - 1c0: ff65 bnez a4,1b8 <_Z13test_syscallsv+0x38> + 1ba: 0017c703 lbu a4,1(a5) + 1be: 863e mv a2,a5 + 1c0: 0785 addi a5,a5,1 + 1c2: ff65 bnez a4,1ba <_Z13test_syscallsv+0x38> n++; - 1c2: 9e15 subw a2,a2,a3 + 1c4: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 1c4: 2605 addiw a2,a2,1 - 1c6: 00000597 auipc a1,0x0 - 1ca: 59258593 addi a1,a1,1426 # 758 - 1ce: 4505 li a0,1 - 1d0: 4a0000ef jal 670 + 1c6: 2605 addiw a2,a2,1 + 1c8: 00000597 auipc a1,0x0 + 1cc: 65058593 addi a1,a1,1616 # 818 + 1d0: 4505 li a0,1 + 1d2: 55c000ef jal 72e print("\n=== [Test] Starting System Call Check ===\n"); - // 1. 测试 getpid print("[1/4] Checking getpid()... "); int my_pid = getpid(); - 1d4: 4fc000ef jal 6d0 - 1d8: 842a mv s0,a0 + 1d6: 5b8000ef jal 78e + 1da: 842a mv s0,a0 if (my_pid > 0) - 1da: 2aa05463 blez a0,482 <_Z13test_syscallsv+0x302> - 1de: 00000697 auipc a3,0x0 - 1e2: 59a68693 addi a3,a3,1434 # 778 - 1e6: 87b6 mv a5,a3 + 1dc: 2aa05463 blez a0,484 <_Z13test_syscallsv+0x302> + 1e0: 00000697 auipc a3,0x0 + 1e4: 65868693 addi a3,a3,1624 # 838 + 1e8: 87b6 mv a5,a3 while (s[n]) - 1e8: 0017c703 lbu a4,1(a5) - 1ec: 863e mv a2,a5 - 1ee: 0785 addi a5,a5,1 - 1f0: ff65 bnez a4,1e8 <_Z13test_syscallsv+0x68> + 1ea: 0017c703 lbu a4,1(a5) + 1ee: 863e mv a2,a5 + 1f0: 0785 addi a5,a5,1 + 1f2: ff65 bnez a4,1ea <_Z13test_syscallsv+0x68> n++; - 1f2: 9e15 subw a2,a2,a3 + 1f4: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 1f4: 2605 addiw a2,a2,1 - 1f6: 00000597 auipc a1,0x0 - 1fa: 58258593 addi a1,a1,1410 # 778 - 1fe: 4505 li a0,1 - 200: 470000ef jal 670 + 1f6: 2605 addiw a2,a2,1 + 1f8: 00000597 auipc a1,0x0 + 1fc: 64058593 addi a1,a1,1600 # 838 + 200: 4505 li a0,1 + 202: 52c000ef jal 72e { print("PASS (PID="); print_int(my_pid); - 204: 8522 mv a0,s0 - 206: e4fff0ef jal 54 <_Z9print_inti> + 206: 8522 mv a0,s0 + 208: e4fff0ef jal 56 <_Z9print_inti> while (s[n]) - 20a: 00000697 auipc a3,0x0 - 20e: 57e68693 addi a3,a3,1406 # 788 + 20c: 00000697 auipc a3,0x0 + 210: 63c68693 addi a3,a3,1596 # 848 print_int(my_pid); - 212: 87b6 mv a5,a3 + 214: 87b6 mv a5,a3 while (s[n]) - 214: 0017c703 lbu a4,1(a5) - 218: 863e mv a2,a5 - 21a: 0785 addi a5,a5,1 - 21c: ff65 bnez a4,214 <_Z13test_syscallsv+0x94> + 216: 0017c703 lbu a4,1(a5) + 21a: 863e mv a2,a5 + 21c: 0785 addi a5,a5,1 + 21e: ff65 bnez a4,216 <_Z13test_syscallsv+0x94> n++; - 21e: 9e15 subw a2,a2,a3 + 220: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 220: 2605 addiw a2,a2,1 - 222: 00000597 auipc a1,0x0 - 226: 56658593 addi a1,a1,1382 # 788 - 22a: 4505 li a0,1 - 22c: 444000ef jal 670 + 222: 2605 addiw a2,a2,1 + 224: 00000597 auipc a1,0x0 + 228: 62458593 addi a1,a1,1572 # 848 + 22c: 4505 li a0,1 + 22e: 500000ef jal 72e while (s[n]) - 230: 00000697 auipc a3,0x0 - 234: 57868693 addi a3,a3,1400 # 7a8 + 232: 00000697 auipc a3,0x0 + 236: 63668693 addi a3,a3,1590 # 868 if (my_pid > 0) - 238: 87b6 mv a5,a3 + 23a: 87b6 mv a5,a3 while (s[n]) - 23a: 0017c703 lbu a4,1(a5) - 23e: 863e mv a2,a5 - 240: 0785 addi a5,a5,1 - 242: ff65 bnez a4,23a <_Z13test_syscallsv+0xba> + 23c: 0017c703 lbu a4,1(a5) + 240: 863e mv a2,a5 + 242: 0785 addi a5,a5,1 + 244: ff65 bnez a4,23c <_Z13test_syscallsv+0xba> n++; - 244: 9e15 subw a2,a2,a3 + 246: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 246: 2605 addiw a2,a2,1 - 248: 00000597 auipc a1,0x0 - 24c: 56058593 addi a1,a1,1376 # 7a8 - 250: 4505 li a0,1 - 252: 41e000ef jal 670 + 248: 2605 addiw a2,a2,1 + 24a: 00000597 auipc a1,0x0 + 24e: 61e58593 addi a1,a1,1566 # 868 + 252: 4505 li a0,1 + 254: 4da000ef jal 72e + { print("FAIL (Invalid PID)\n"); } - // 2. 测试 sbrk (内存分配) print("[2/4] Checking sbrk() heap allocation... "); - char *p = sbrk(4096); // 分配 4KB - 256: 6505 lui a0,0x1 - 258: 480000ef jal 6d8 + char *p = sbrk(4096); + 258: 6505 lui a0,0x1 + 25a: 53c000ef jal 796 if (p == (char *)-1) - 25c: 57fd li a5,-1 - char *p = sbrk(4096); // 分配 4KB - 25e: 84aa mv s1,a0 + 25e: 57fd li a5,-1 + char *p = sbrk(4096); + 260: 84aa mv s1,a0 if (p == (char *)-1) - 260: 24f50563 beq a0,a5,4aa <_Z13test_syscallsv+0x32a> + 262: 24f50563 beq a0,a5,4ac <_Z13test_syscallsv+0x32a> + { print("FAIL (sbrk returned error)\n"); } else { - // 写入测试,确保映射了物理页 p[0] = 'A'; - 264: 04100793 li a5,65 - 268: 00f50023 sb a5,0(a0) # 1000 + 266: 04100793 li a5,65 + 26a: 00f50023 sb a5,0(a0) # 1000 p[4095] = 'Z'; - 26c: 6785 lui a5,0x1 - 26e: 97aa add a5,a5,a0 - 270: 00000697 auipc a3,0x0 - 274: 58868693 addi a3,a3,1416 # 7f8 - 278: 05a00713 li a4,90 - 27c: fee78fa3 sb a4,-1(a5) # fff - 280: 87b6 mv a5,a3 + 26e: 6785 lui a5,0x1 + 270: 97aa add a5,a5,a0 + 272: 00000697 auipc a3,0x0 + 276: 64668693 addi a3,a3,1606 # 8b8 + 27a: 05a00713 li a4,90 + 27e: fee78fa3 sb a4,-1(a5) # fff + 282: 87b6 mv a5,a3 while (s[n]) - 282: 0017c703 lbu a4,1(a5) - 286: 863e mv a2,a5 - 288: 0785 addi a5,a5,1 - 28a: ff65 bnez a4,282 <_Z13test_syscallsv+0x102> + 284: 0017c703 lbu a4,1(a5) + 288: 863e mv a2,a5 + 28a: 0785 addi a5,a5,1 + 28c: ff65 bnez a4,284 <_Z13test_syscallsv+0x102> n++; - 28c: 9e15 subw a2,a2,a3 + 28e: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 28e: 2605 addiw a2,a2,1 - 290: 00000597 auipc a1,0x0 - 294: 56858593 addi a1,a1,1384 # 7f8 - 298: 4505 li a0,1 - 29a: 3d6000ef jal 670 + 290: 2605 addiw a2,a2,1 + 292: 00000597 auipc a1,0x0 + 296: 62658593 addi a1,a1,1574 # 8b8 + 29a: 4505 li a0,1 + 29c: 492000ef jal 72e if (p[0] == 'A' && p[4095] == 'Z') { print("PASS (Allocated at "); print_hex((uint64)p); - 29e: 8526 mv a0,s1 - 2a0: e45ff0ef jal e4 <_Z9print_hexy> + 2a0: 8526 mv a0,s1 + 2a2: e45ff0ef jal e6 <_Z9print_hexy> while (s[n]) - 2a4: 00000697 auipc a3,0x0 - 2a8: 4e468693 addi a3,a3,1252 # 788 + 2a6: 00000697 auipc a3,0x0 + 2aa: 5a268693 addi a3,a3,1442 # 848 print_hex((uint64)p); - 2ac: 87b6 mv a5,a3 + 2ae: 87b6 mv a5,a3 while (s[n]) - 2ae: 0017c703 lbu a4,1(a5) - 2b2: 863e mv a2,a5 - 2b4: 0785 addi a5,a5,1 - 2b6: ff65 bnez a4,2ae <_Z13test_syscallsv+0x12e> + 2b0: 0017c703 lbu a4,1(a5) + 2b4: 863e mv a2,a5 + 2b6: 0785 addi a5,a5,1 + 2b8: ff65 bnez a4,2b0 <_Z13test_syscallsv+0x12e> n++; - 2b8: 9e15 subw a2,a2,a3 + 2ba: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 2ba: 2605 addiw a2,a2,1 - 2bc: 00000597 auipc a1,0x0 - 2c0: 4cc58593 addi a1,a1,1228 # 788 - 2c4: 4505 li a0,1 - 2c6: 3aa000ef jal 670 + 2bc: 2605 addiw a2,a2,1 + 2be: 00000597 auipc a1,0x0 + 2c2: 58a58593 addi a1,a1,1418 # 848 + 2c6: 4505 li a0,1 + 2c8: 466000ef jal 72e while (s[n]) - 2ca: 00000697 auipc a3,0x0 - 2ce: 54668693 addi a3,a3,1350 # 810 + 2cc: 00000697 auipc a3,0x0 + 2d0: 60468693 addi a3,a3,1540 # 8d0 print_hex((uint64)p); - 2d2: 87b6 mv a5,a3 + 2d4: 87b6 mv a5,a3 while (s[n]) - 2d4: 0017c703 lbu a4,1(a5) - 2d8: 863e mv a2,a5 - 2da: 0785 addi a5,a5,1 - 2dc: ff65 bnez a4,2d4 <_Z13test_syscallsv+0x154> + 2d6: 0017c703 lbu a4,1(a5) + 2da: 863e mv a2,a5 + 2dc: 0785 addi a5,a5,1 + 2de: ff65 bnez a4,2d6 <_Z13test_syscallsv+0x154> n++; - 2de: 9e15 subw a2,a2,a3 + 2e0: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 2e0: 2605 addiw a2,a2,1 - 2e2: 00000597 auipc a1,0x0 - 2e6: 52e58593 addi a1,a1,1326 # 810 - 2ea: 4505 li a0,1 - 2ec: 384000ef jal 670 + 2e2: 2605 addiw a2,a2,1 + 2e4: 00000597 auipc a1,0x0 + 2e8: 5ec58593 addi a1,a1,1516 # 8d0 + 2ec: 4505 li a0,1 + 2ee: 440000ef jal 72e + print("FAIL (Memory read/write check failed)\n"); } } - // 3. 测试 fork 和 wait print("[3/4] Checking fork() and wait()...\n"); int pid = fork(); - 2f0: 358000ef jal 648 - 2f4: 84aa mv s1,a0 + 2f2: 414000ef jal 706 + 2f6: 84aa mv s1,a0 if (pid < 0) - 2f6: 1c054e63 bltz a0,4d2 <_Z13test_syscallsv+0x352> + 2f8: 1c054e63 bltz a0,4d4 <_Z13test_syscallsv+0x352> { print(" FAIL: fork error\n"); } else if (pid == 0) - 2fa: e179 bnez a0,3c0 <_Z13test_syscallsv+0x240> + 2fc: e179 bnez a0,3c2 <_Z13test_syscallsv+0x240> { - // --- 子进程 --- int child_pid = getpid(); - 2fc: 3d4000ef jal 6d0 - 300: 84aa mv s1,a0 + 2fe: 490000ef jal 78e + 302: 84aa mv s1,a0 if (child_pid == my_pid) - 302: 24a40563 beq s0,a0,54c <_Z13test_syscallsv+0x3cc> + 304: 24a40563 beq s0,a0,54e <_Z13test_syscallsv+0x3cc> while (s[n]) - 306: 00000697 auipc a3,0x0 - 30a: 57a68693 addi a3,a3,1402 # 880 + 308: 00000697 auipc a3,0x0 + 30c: 63868693 addi a3,a3,1592 # 940 if (child_pid == my_pid) - 30e: 87b6 mv a5,a3 + 310: 87b6 mv a5,a3 while (s[n]) - 310: 0017c703 lbu a4,1(a5) - 314: 863e mv a2,a5 - 316: 0785 addi a5,a5,1 - 318: ff65 bnez a4,310 <_Z13test_syscallsv+0x190> + 312: 0017c703 lbu a4,1(a5) + 316: 863e mv a2,a5 + 318: 0785 addi a5,a5,1 + 31a: ff65 bnez a4,312 <_Z13test_syscallsv+0x190> n++; - 31a: 9e15 subw a2,a2,a3 + 31c: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 31c: 2605 addiw a2,a2,1 - 31e: 00000597 auipc a1,0x0 - 322: 56258593 addi a1,a1,1378 # 880 - 326: 4505 li a0,1 - 328: 348000ef jal 670 + 31e: 2605 addiw a2,a2,1 + 320: 00000597 auipc a1,0x0 + 324: 62058593 addi a1,a1,1568 # 940 + 328: 4505 li a0,1 + 32a: 404000ef jal 72e { print(" FAIL: Child has same PID as parent\n"); exit(1); } print(" [Child] I am alive. PID="); print_int(child_pid); - 32c: 8526 mv a0,s1 - 32e: d27ff0ef jal 54 <_Z9print_inti> + 32e: 8526 mv a0,s1 + 330: d27ff0ef jal 56 <_Z9print_inti> write(1, s, strlen(s)); - 332: 4605 li a2,1 - 334: 00000597 auipc a1,0x0 - 338: 56c58593 addi a1,a1,1388 # 8a0 - 33c: 4505 li a0,1 - 33e: 332000ef jal 670 + 334: 4605 li a2,1 + 336: 00000597 auipc a1,0x0 + 33a: 62a58593 addi a1,a1,1578 # 960 + 33e: 4505 li a0,1 + 340: 3ee000ef jal 72e while (s[n]) - 342: 00000697 auipc a3,0x0 - 346: 56668693 addi a3,a3,1382 # 8a8 + 344: 00000697 auipc a3,0x0 + 348: 62468693 addi a3,a3,1572 # 968 write(1, s, strlen(s)); - 34a: 87b6 mv a5,a3 + 34c: 87b6 mv a5,a3 while (s[n]) - 34c: 0017c703 lbu a4,1(a5) - 350: 863e mv a2,a5 - 352: 0785 addi a5,a5,1 - 354: ff65 bnez a4,34c <_Z13test_syscallsv+0x1cc> + 34e: 0017c703 lbu a4,1(a5) + 352: 863e mv a2,a5 + 354: 0785 addi a5,a5,1 + 356: ff65 bnez a4,34e <_Z13test_syscallsv+0x1cc> n++; - 356: 9e15 subw a2,a2,a3 + 358: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 358: 2605 addiw a2,a2,1 - 35a: 00000597 auipc a1,0x0 - 35e: 54e58593 addi a1,a1,1358 # 8a8 - 362: 4505 li a0,1 - 364: 30c000ef jal 670 + 35a: 2605 addiw a2,a2,1 + 35c: 00000597 auipc a1,0x0 + 360: 60c58593 addi a1,a1,1548 # 968 + 364: 4505 li a0,1 + 366: 3c8000ef jal 72e print("\n"); print(" [Child] Exiting now.\n"); exit(0); - 368: 4501 li a0,0 - 36a: 2e6000ef jal 650 + 36a: 4501 li a0,0 + 36c: 3a2000ef jal 70e while (s[n]) - 36e: 00000697 auipc a3,0x0 - 372: 60a68693 addi a3,a3,1546 # 978 + 370: 00000697 auipc a3,0x0 + 374: 6c868693 addi a3,a3,1736 # a38 print("PASS (Fork/Wait cycle)\n"); } else { print("FAIL (Wait returned "); print_int(waited_pid); - 376: 87b6 mv a5,a3 + 378: 87b6 mv a5,a3 while (s[n]) - 378: 0017c703 lbu a4,1(a5) - 37c: 863e mv a2,a5 - 37e: 0785 addi a5,a5,1 - 380: ff65 bnez a4,378 <_Z13test_syscallsv+0x1f8> + 37a: 0017c703 lbu a4,1(a5) + 37e: 863e mv a2,a5 + 380: 0785 addi a5,a5,1 + 382: ff65 bnez a4,37a <_Z13test_syscallsv+0x1f8> n++; - 382: 9e15 subw a2,a2,a3 + 384: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 384: 2605 addiw a2,a2,1 - 386: 00000597 auipc a1,0x0 - 38a: 5f258593 addi a1,a1,1522 # 978 - 38e: 4505 li a0,1 - 390: 2e0000ef jal 670 + 386: 2605 addiw a2,a2,1 + 388: 00000597 auipc a1,0x0 + 38c: 6b058593 addi a1,a1,1712 # a38 + 390: 4505 li a0,1 + 392: 39c000ef jal 72e while (s[n]) - 394: 00000697 auipc a3,0x0 - 398: 61468693 addi a3,a3,1556 # 9a8 + 396: 00000697 auipc a3,0x0 + 39a: 6d268693 addi a3,a3,1746 # a68 write(1, s, strlen(s)); - 39c: 87b6 mv a5,a3 + 39e: 87b6 mv a5,a3 while (s[n]) - 39e: 0017c703 lbu a4,1(a5) - 3a2: 863e mv a2,a5 - 3a4: 0785 addi a5,a5,1 - 3a6: ff65 bnez a4,39e <_Z13test_syscallsv+0x21e> + 3a0: 0017c703 lbu a4,1(a5) + 3a4: 863e mv a2,a5 + 3a6: 0785 addi a5,a5,1 + 3a8: ff65 bnez a4,3a0 <_Z13test_syscallsv+0x21e> + } - // 4. 测试 write (如果是能看到这些输出,说明 write 已经正常了) print("[4/4] Checking write()... PASS (Self-evident)\n"); print("=== [Test] All Tests Finished ===\n"); } - 3a8: 6442 ld s0,16(sp) - 3aa: 60e2 ld ra,24(sp) - 3ac: 64a2 ld s1,8(sp) + 3aa: 6442 ld s0,16(sp) + 3ac: 60e2 ld ra,24(sp) + 3ae: 64a2 ld s1,8(sp) n++; - 3ae: 9e15 subw a2,a2,a3 + 3b0: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 3b0: 2605 addiw a2,a2,1 - 3b2: 00000597 auipc a1,0x0 - 3b6: 5f658593 addi a1,a1,1526 # 9a8 - 3ba: 4505 li a0,1 + 3b2: 2605 addiw a2,a2,1 + 3b4: 00000597 auipc a1,0x0 + 3b8: 6b458593 addi a1,a1,1716 # a68 + 3bc: 4505 li a0,1 } - 3bc: 6105 addi sp,sp,32 + 3be: 6105 addi sp,sp,32 write(1, s, strlen(s)); - 3be: ac4d j 670 - 3c0: 00000697 auipc a3,0x0 - 3c4: 50868693 addi a3,a3,1288 # 8c8 + 3c0: a6bd j 72e + 3c2: 00000697 auipc a3,0x0 + 3c6: 5c668693 addi a3,a3,1478 # 988 else if (pid == 0) - 3c8: 87b6 mv a5,a3 + 3ca: 87b6 mv a5,a3 while (s[n]) - 3ca: 0017c703 lbu a4,1(a5) - 3ce: 863e mv a2,a5 - 3d0: 0785 addi a5,a5,1 - 3d2: ff65 bnez a4,3ca <_Z13test_syscallsv+0x24a> + 3cc: 0017c703 lbu a4,1(a5) + 3d0: 863e mv a2,a5 + 3d2: 0785 addi a5,a5,1 + 3d4: ff65 bnez a4,3cc <_Z13test_syscallsv+0x24a> n++; - 3d4: 9e15 subw a2,a2,a3 + 3d6: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 3d6: 2605 addiw a2,a2,1 - 3d8: 00000597 auipc a1,0x0 - 3dc: 4f058593 addi a1,a1,1264 # 8c8 - 3e0: 4505 li a0,1 - 3e2: 28e000ef jal 670 + 3d8: 2605 addiw a2,a2,1 + 3da: 00000597 auipc a1,0x0 + 3de: 5ae58593 addi a1,a1,1454 # 988 + 3e2: 4505 li a0,1 + 3e4: 34a000ef jal 72e print_int(pid); - 3e6: 8526 mv a0,s1 - 3e8: c6dff0ef jal 54 <_Z9print_inti> + 3e8: 8526 mv a0,s1 + 3ea: c6dff0ef jal 56 <_Z9print_inti> write(1, s, strlen(s)); - 3ec: 4605 li a2,1 - 3ee: 00000597 auipc a1,0x0 - 3f2: 4b258593 addi a1,a1,1202 # 8a0 - 3f6: 4505 li a0,1 - 3f8: 278000ef jal 670 + 3ee: 4605 li a2,1 + 3f0: 00000597 auipc a1,0x0 + 3f4: 57058593 addi a1,a1,1392 # 960 + 3f8: 4505 li a0,1 + 3fa: 334000ef jal 72e while (s[n]) - 3fc: 00000697 auipc a3,0x0 - 400: 4f468693 addi a3,a3,1268 # 8f0 + 3fe: 00000697 auipc a3,0x0 + 402: 5b268693 addi a3,a3,1458 # 9b0 write(1, s, strlen(s)); - 404: 87b6 mv a5,a3 + 406: 87b6 mv a5,a3 while (s[n]) - 406: 0017c703 lbu a4,1(a5) - 40a: 863e mv a2,a5 - 40c: 0785 addi a5,a5,1 - 40e: ff65 bnez a4,406 <_Z13test_syscallsv+0x286> + 408: 0017c703 lbu a4,1(a5) + 40c: 863e mv a2,a5 + 40e: 0785 addi a5,a5,1 + 410: ff65 bnez a4,408 <_Z13test_syscallsv+0x286> n++; - 410: 9e15 subw a2,a2,a3 + 412: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 412: 2605 addiw a2,a2,1 - 414: 00000597 auipc a1,0x0 - 418: 4dc58593 addi a1,a1,1244 # 8f0 - 41c: 4505 li a0,1 - 41e: 252000ef jal 670 + 414: 2605 addiw a2,a2,1 + 416: 00000597 auipc a1,0x0 + 41a: 59a58593 addi a1,a1,1434 # 9b0 + 41e: 4505 li a0,1 + 420: 30e000ef jal 72e int waited_pid = wait(0); - 422: 4501 li a0,0 - 424: 234000ef jal 658 - 428: 00000697 auipc a3,0x0 - 42c: 53868693 addi a3,a3,1336 # 960 - 430: 842a mv s0,a0 + 424: 4501 li a0,0 + 426: 2f0000ef jal 716 + 42a: 00000697 auipc a3,0x0 + 42e: 5f668693 addi a3,a3,1526 # a20 + 432: 842a mv s0,a0 if (waited_pid == pid) - 432: 87b6 mv a5,a3 - 434: 0ca48363 beq s1,a0,4fa <_Z13test_syscallsv+0x37a> + 434: 87b6 mv a5,a3 + 436: 0ca48363 beq s1,a0,4fc <_Z13test_syscallsv+0x37a> while (s[n]) - 438: 0017c703 lbu a4,1(a5) - 43c: 863e mv a2,a5 - 43e: 0785 addi a5,a5,1 - 440: ff65 bnez a4,438 <_Z13test_syscallsv+0x2b8> + 43a: 0017c703 lbu a4,1(a5) + 43e: 863e mv a2,a5 + 440: 0785 addi a5,a5,1 + 442: ff65 bnez a4,43a <_Z13test_syscallsv+0x2b8> n++; - 442: 9e15 subw a2,a2,a3 + 444: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 444: 2605 addiw a2,a2,1 - 446: 00000597 auipc a1,0x0 - 44a: 51a58593 addi a1,a1,1306 # 960 - 44e: 4505 li a0,1 - 450: 220000ef jal 670 + 446: 2605 addiw a2,a2,1 + 448: 00000597 auipc a1,0x0 + 44c: 5d858593 addi a1,a1,1496 # a20 + 450: 4505 li a0,1 + 452: 2dc000ef jal 72e print_int(waited_pid); - 454: 8522 mv a0,s0 - 456: bffff0ef jal 54 <_Z9print_inti> + 456: 8522 mv a0,s0 + 458: bffff0ef jal 56 <_Z9print_inti> while (s[n]) - 45a: 00000697 auipc a3,0x0 - 45e: 32e68693 addi a3,a3,814 # 788 + 45c: 00000697 auipc a3,0x0 + 460: 3ec68693 addi a3,a3,1004 # 848 print_int(waited_pid); - 462: 87b6 mv a5,a3 + 464: 87b6 mv a5,a3 while (s[n]) - 464: 0017c703 lbu a4,1(a5) - 468: 863e mv a2,a5 - 46a: 0785 addi a5,a5,1 - 46c: ff65 bnez a4,464 <_Z13test_syscallsv+0x2e4> + 466: 0017c703 lbu a4,1(a5) + 46a: 863e mv a2,a5 + 46c: 0785 addi a5,a5,1 + 46e: ff65 bnez a4,466 <_Z13test_syscallsv+0x2e4> n++; - 46e: 9e15 subw a2,a2,a3 + 470: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 470: 2605 addiw a2,a2,1 - 472: 00000597 auipc a1,0x0 - 476: 31658593 addi a1,a1,790 # 788 - 47a: 4505 li a0,1 - 47c: 1f4000ef jal 670 + 472: 2605 addiw a2,a2,1 + 474: 00000597 auipc a1,0x0 + 478: 3d458593 addi a1,a1,980 # 848 + 47c: 4505 li a0,1 + 47e: 2b0000ef jal 72e } - 480: b5fd j 36e <_Z13test_syscallsv+0x1ee> - 482: 00000697 auipc a3,0x0 - 486: 30e68693 addi a3,a3,782 # 790 + 482: b5fd j 370 <_Z13test_syscallsv+0x1ee> + 484: 00000697 auipc a3,0x0 + 488: 3cc68693 addi a3,a3,972 # 850 if (my_pid > 0) - 48a: 87b6 mv a5,a3 + 48c: 87b6 mv a5,a3 while (s[n]) - 48c: 0017c703 lbu a4,1(a5) - 490: 863e mv a2,a5 - 492: 0785 addi a5,a5,1 - 494: ff65 bnez a4,48c <_Z13test_syscallsv+0x30c> + 48e: 0017c703 lbu a4,1(a5) + 492: 863e mv a2,a5 + 494: 0785 addi a5,a5,1 + 496: ff65 bnez a4,48e <_Z13test_syscallsv+0x30c> n++; - 496: 9e15 subw a2,a2,a3 + 498: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 498: 2605 addiw a2,a2,1 - 49a: 00000597 auipc a1,0x0 - 49e: 2f658593 addi a1,a1,758 # 790 - 4a2: 4505 li a0,1 - 4a4: 1cc000ef jal 670 + 49a: 2605 addiw a2,a2,1 + 49c: 00000597 auipc a1,0x0 + 4a0: 3b458593 addi a1,a1,948 # 850 + 4a4: 4505 li a0,1 + 4a6: 288000ef jal 72e } - 4a8: b361 j 230 <_Z13test_syscallsv+0xb0> - 4aa: 00000697 auipc a3,0x0 - 4ae: 32e68693 addi a3,a3,814 # 7d8 + 4aa: b361 j 232 <_Z13test_syscallsv+0xb0> + 4ac: 00000697 auipc a3,0x0 + 4b0: 3ec68693 addi a3,a3,1004 # 898 if (p == (char *)-1) - 4b2: 87b6 mv a5,a3 + 4b4: 87b6 mv a5,a3 while (s[n]) - 4b4: 0017c703 lbu a4,1(a5) - 4b8: 863e mv a2,a5 - 4ba: 0785 addi a5,a5,1 - 4bc: ff65 bnez a4,4b4 <_Z13test_syscallsv+0x334> + 4b6: 0017c703 lbu a4,1(a5) + 4ba: 863e mv a2,a5 + 4bc: 0785 addi a5,a5,1 + 4be: ff65 bnez a4,4b6 <_Z13test_syscallsv+0x334> n++; - 4be: 9e15 subw a2,a2,a3 + 4c0: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 4c0: 2605 addiw a2,a2,1 - 4c2: 00000597 auipc a1,0x0 - 4c6: 31658593 addi a1,a1,790 # 7d8 - 4ca: 4505 li a0,1 - 4cc: 1a4000ef jal 670 + 4c2: 2605 addiw a2,a2,1 + 4c4: 00000597 auipc a1,0x0 + 4c8: 3d458593 addi a1,a1,980 # 898 + 4cc: 4505 li a0,1 + 4ce: 260000ef jal 72e } - 4d0: bbed j 2ca <_Z13test_syscallsv+0x14a> - 4d2: 00000697 auipc a3,0x0 - 4d6: 36668693 addi a3,a3,870 # 838 + 4d2: bbed j 2cc <_Z13test_syscallsv+0x14a> + 4d4: 00000697 auipc a3,0x0 + 4d8: 42468693 addi a3,a3,1060 # 8f8 if (pid < 0) - 4da: 87b6 mv a5,a3 + 4dc: 87b6 mv a5,a3 while (s[n]) - 4dc: 0017c703 lbu a4,1(a5) - 4e0: 863e mv a2,a5 - 4e2: 0785 addi a5,a5,1 - 4e4: ff65 bnez a4,4dc <_Z13test_syscallsv+0x35c> + 4de: 0017c703 lbu a4,1(a5) + 4e2: 863e mv a2,a5 + 4e4: 0785 addi a5,a5,1 + 4e6: ff65 bnez a4,4de <_Z13test_syscallsv+0x35c> n++; - 4e6: 9e15 subw a2,a2,a3 + 4e8: 9e15 subw a2,a2,a3 write(1, s, strlen(s)); - 4e8: 2605 addiw a2,a2,1 - 4ea: 00000597 auipc a1,0x0 - 4ee: 34e58593 addi a1,a1,846 # 838 - 4f2: 4505 li a0,1 - 4f4: 17c000ef jal 670 + 4ea: 2605 addiw a2,a2,1 + 4ec: 00000597 auipc a1,0x0 + 4f0: 40c58593 addi a1,a1,1036 # 8f8 + 4f4: 4505 li a0,1 + 4f6: 238000ef jal 72e } - 4f8: bd9d j 36e <_Z13test_syscallsv+0x1ee> - 4fa: 00000617 auipc a2,0x0 - 4fe: 41e60613 addi a2,a2,1054 # 918 + 4fa: bd9d j 370 <_Z13test_syscallsv+0x1ee> + 4fc: 00000617 auipc a2,0x0 + 500: 4dc60613 addi a2,a2,1244 # 9d8 if (waited_pid == pid) - 502: 87b2 mv a5,a2 + 504: 87b2 mv a5,a2 while (s[n]) - 504: 0017c703 lbu a4,1(a5) - 508: 86be mv a3,a5 - 50a: 0785 addi a5,a5,1 - 50c: ff65 bnez a4,504 <_Z13test_syscallsv+0x384> + 506: 0017c703 lbu a4,1(a5) + 50a: 86be mv a3,a5 + 50c: 0785 addi a5,a5,1 + 50e: ff65 bnez a4,506 <_Z13test_syscallsv+0x384> n++; - 50e: 40c6863b subw a2,a3,a2 + 510: 40c6863b subw a2,a3,a2 write(1, s, strlen(s)); - 512: 2605 addiw a2,a2,1 - 514: 00000597 auipc a1,0x0 - 518: 40458593 addi a1,a1,1028 # 918 - 51c: 4505 li a0,1 - 51e: 152000ef jal 670 + 514: 2605 addiw a2,a2,1 + 516: 00000597 auipc a1,0x0 + 51a: 4c258593 addi a1,a1,1218 # 9d8 + 51e: 4505 li a0,1 + 520: 20e000ef jal 72e while (s[n]) - 522: 00000617 auipc a2,0x0 - 526: 42660613 addi a2,a2,1062 # 948 + 524: 00000617 auipc a2,0x0 + 528: 4e460613 addi a2,a2,1252 # a08 write(1, s, strlen(s)); - 52a: 87b2 mv a5,a2 + 52c: 87b2 mv a5,a2 while (s[n]) - 52c: 0017c703 lbu a4,1(a5) - 530: 86be mv a3,a5 - 532: 0785 addi a5,a5,1 - 534: ff65 bnez a4,52c <_Z13test_syscallsv+0x3ac> + 52e: 0017c703 lbu a4,1(a5) + 532: 86be mv a3,a5 + 534: 0785 addi a5,a5,1 + 536: ff65 bnez a4,52e <_Z13test_syscallsv+0x3ac> n++; - 536: 40c6863b subw a2,a3,a2 + 538: 40c6863b subw a2,a3,a2 write(1, s, strlen(s)); - 53a: 2605 addiw a2,a2,1 - 53c: 00000597 auipc a1,0x0 - 540: 40c58593 addi a1,a1,1036 # 948 - 544: 4505 li a0,1 - 546: 12a000ef jal 670 + 53c: 2605 addiw a2,a2,1 + 53e: 00000597 auipc a1,0x0 + 542: 4ca58593 addi a1,a1,1226 # a08 + 546: 4505 li a0,1 + 548: 1e6000ef jal 72e } - 54a: b515 j 36e <_Z13test_syscallsv+0x1ee> - 54c: 00000617 auipc a2,0x0 - 550: 30460613 addi a2,a2,772 # 850 + 54c: b515 j 370 <_Z13test_syscallsv+0x1ee> + 54e: 00000617 auipc a2,0x0 + 552: 3c260613 addi a2,a2,962 # 910 if (child_pid == my_pid) - 554: 87b2 mv a5,a2 + 556: 87b2 mv a5,a2 while (s[n]) - 556: 0017c703 lbu a4,1(a5) - 55a: 86be mv a3,a5 - 55c: 0785 addi a5,a5,1 - 55e: ff65 bnez a4,556 <_Z13test_syscallsv+0x3d6> + 558: 0017c703 lbu a4,1(a5) + 55c: 86be mv a3,a5 + 55e: 0785 addi a5,a5,1 + 560: ff65 bnez a4,558 <_Z13test_syscallsv+0x3d6> n++; - 560: 40c6863b subw a2,a3,a2 + 562: 40c6863b subw a2,a3,a2 write(1, s, strlen(s)); - 564: 2605 addiw a2,a2,1 - 566: 00000597 auipc a1,0x0 - 56a: 2ea58593 addi a1,a1,746 # 850 - 56e: 4505 li a0,1 - 570: 100000ef jal 670 + 566: 2605 addiw a2,a2,1 + 568: 00000597 auipc a1,0x0 + 56c: 3a858593 addi a1,a1,936 # 910 + 570: 4505 li a0,1 + 572: 1bc000ef jal 72e exit(1); - 574: 4505 li a0,1 - 576: 0da000ef jal 650 - 57a: b371 j 306 <_Z13test_syscallsv+0x186> + 576: 4505 li a0,1 + 578: 196000ef jal 70e + 57c: b371 j 308 <_Z13test_syscallsv+0x186> + +000000000000057e
: -000000000000057c
: -// ============================================================= -// Shell 主循环 -// ============================================================= int main() { - 57c: 715d addi sp,sp,-80 - print("\n[Lume Shell] Ready.\n"); - 57e: 00000517 auipc a0,0x0 - 582: 45250513 addi a0,a0,1106 # 9d0 + 57e: 7119 addi sp,sp,-128 + print("\n[Lume Shell] Init process started.\n"); + 580: 00000517 auipc a0,0x0 + 584: 51050513 addi a0,a0,1296 # a90 { - 586: e486 sd ra,72(sp) - 588: e0a2 sd s0,64(sp) - 58a: fc26 sd s1,56(sp) - 58c: f84a sd s2,48(sp) - 58e: f44e sd s3,40(sp) - 590: f052 sd s4,32(sp) - 592: ec56 sd s5,24(sp) - 594: e85a sd s6,16(sp) - print("\n[Lume Shell] Ready.\n"); - 596: a99ff0ef jal 2e <_Z5printPKc> + 588: fc86 sd ra,120(sp) + 58a: f8a2 sd s0,112(sp) + 58c: f4a6 sd s1,104(sp) + 58e: f0ca sd s2,96(sp) + 590: ecce sd s3,88(sp) + 592: e8d2 sd s4,80(sp) + 594: e4d6 sd s5,72(sp) + 596: e0da sd s6,64(sp) + print("\n[Lume Shell] Init process started.\n"); + 598: a97ff0ef jal 2e <_Z5printPKc> + print("[Test] Opening test.txt...\n"); + 59c: 00000517 auipc a0,0x0 + 5a0: 51c50513 addi a0,a0,1308 # ab8 + 5a4: a8bff0ef jal 2e <_Z5printPKc> + int fd = open("test.txt", O_RDONLY); + 5a8: 4581 li a1,0 + 5aa: 00000517 auipc a0,0x0 + 5ae: 52e50513 addi a0,a0,1326 # ad8 + 5b2: 19c000ef jal 74e + if (fd < 0) + 5b6: 14054063 bltz a0,6f6 + 5ba: 84aa mv s1,a0 + { + print("[Test] Open failed (Is test.txt in fs.img?)\n"); + } + else + { + print("[Test] Open success! fd="); + 5bc: 00000517 auipc a0,0x0 + 5c0: 55c50513 addi a0,a0,1372 # b18 + 5c4: a6bff0ef jal 2e <_Z5printPKc> + print_int(fd); + 5c8: 8526 mv a0,s1 + 5ca: a8dff0ef jal 56 <_Z9print_inti> + print("\n"); + 5ce: 00000517 auipc a0,0x0 + 5d2: 39250513 addi a0,a0,914 # 960 + 5d6: a59ff0ef jal 2e <_Z5printPKc> + + char buf[64]; + int n = read(fd, buf, 63); + 5da: 840a mv s0,sp + 5dc: 03f00613 li a2,63 + 5e0: 85a2 mv a1,s0 + 5e2: 8526 mv a0,s1 + 5e4: 142000ef jal 726 + 5e8: 892a mv s2,a0 + if (n > 0) + 5ea: 0ca05663 blez a0,6b6 + { + buf[n] = 0; + 5ee: 04050793 addi a5,a0,64 + 5f2: 00278933 add s2,a5,sp + print("[Test] Read content:\n---\n"); + 5f6: 00000517 auipc a0,0x0 + 5fa: 54250513 addi a0,a0,1346 # b38 + buf[n] = 0; + 5fe: fc090023 sb zero,-64(s2) + print("[Test] Read content:\n---\n"); + 602: a2dff0ef jal 2e <_Z5printPKc> + print(buf); + 606: 8522 mv a0,s0 + 608: a27ff0ef jal 2e <_Z5printPKc> + print("\n---\n"); + 60c: 00000517 auipc a0,0x0 + 610: 54c50513 addi a0,a0,1356 # b58 + 614: a1bff0ef jal 2e <_Z5printPKc> + { + print("[Test] Read returned "); + print_int(n); + print("\n"); + } + close(fd); + 618: 8526 mv a0,s1 + 61a: 11c000ef jal 736 + print("[Test] File closed.\n"); + 61e: 00000517 auipc a0,0x0 + 622: 55a50513 addi a0,a0,1370 # b78 + 626: a09ff0ef jal 2e <_Z5printPKc> + } + + + print("Commands:\n"); - 59a: 00000517 auipc a0,0x0 - 59e: 44e50513 addi a0,a0,1102 # 9e8 - 5a2: a8dff0ef jal 2e <_Z5printPKc> + 62a: 00000517 auipc a0,0x0 + 62e: 56650513 addi a0,a0,1382 # b90 + 632: 9fdff0ef jal 2e <_Z5printPKc> print(" s: Run System Call Tests (fork, wait, mm)\n"); - 5a6: 00000517 auipc a0,0x0 - 5aa: 45250513 addi a0,a0,1106 # 9f8 - 5ae: a81ff0ef jal 2e <_Z5printPKc> + 636: 00000517 auipc a0,0x0 + 63a: 56a50513 addi a0,a0,1386 # ba0 + 63e: 9f1ff0ef jal 2e <_Z5printPKc> print(" t: Run Disk Driver Test (VirtIO)\n"); - 5b2: 00000517 auipc a0,0x0 - 5b6: 47650513 addi a0,a0,1142 # a28 - 5ba: 00000b17 auipc s6,0x0 - 5be: 49eb0b13 addi s6,s6,1182 # a58 + 642: 00000517 auipc a0,0x0 + 646: 58e50513 addi a0,a0,1422 # bd0 + 64a: 00000b17 auipc s6,0x0 + 64e: 5b6b0b13 addi s6,s6,1462 # c00 n++; - 5c2: 4a85 li s5,1 + 652: 4a85 li s5,1 print(" t: Run Disk Driver Test (VirtIO)\n"); - 5c4: a6bff0ef jal 2e <_Z5printPKc> - 5c8: 848a mv s1,sp + 654: 9dbff0ef jal 2e <_Z5printPKc> while (1) { char buf[16]; write(1, "$ ", 2); - 5ca: 00000417 auipc s0,0x0 - 5ce: 48640413 addi s0,s0,1158 # a50 + 658: 00000497 auipc s1,0x0 + 65c: 5a048493 addi s1,s1,1440 # bf8 int n = read(0, buf, sizeof(buf)); if (n <= 0) continue; if (buf[0] == 's') - 5d2: 07300913 li s2,115 + 660: 07300913 li s2,115 { test_syscalls(); } else if (buf[0] == 't') - 5d6: 07400993 li s3,116 + 664: 07400993 li s3,116 disk_test(); exit(0); } wait(0); } else if (buf[0] != '\n') - 5da: 4a29 li s4,10 + 668: 4a29 li s4,10 n++; - 5dc: 416a8abb subw s5,s5,s6 + 66a: 416a8abb subw s5,s5,s6 write(1, "$ ", 2); - 5e0: 4609 li a2,2 - 5e2: 85a2 mv a1,s0 - 5e4: 4505 li a0,1 - 5e6: 08a000ef jal 670 + 66e: 4609 li a2,2 + 670: 85a6 mv a1,s1 + 672: 4505 li a0,1 + 674: 0ba000ef jal 72e int n = read(0, buf, sizeof(buf)); - 5ea: 4641 li a2,16 - 5ec: 85a6 mv a1,s1 - 5ee: 4501 li a0,0 - 5f0: 078000ef jal 668 + 678: 4641 li a2,16 + 67a: 85a2 mv a1,s0 + 67c: 4501 li a0,0 + 67e: 0a8000ef jal 726 if (n <= 0) - 5f4: fea056e3 blez a0,5e0 + 682: fea056e3 blez a0,66e if (buf[0] == 's') - 5f8: 00014783 lbu a5,0(sp) - 5fc: 03278663 beq a5,s2,628 + 686: 00014783 lbu a5,0(sp) + 68a: 05278663 beq a5,s2,6d6 else if (buf[0] == 't') - 600: 03378763 beq a5,s3,62e + 68e: 05378763 beq a5,s3,6dc else if (buf[0] != '\n') - 604: fd478ee3 beq a5,s4,5e0 - 608: 00000797 auipc a5,0x0 - 60c: 45078793 addi a5,a5,1104 # a58 + 692: fd478ee3 beq a5,s4,66e + 696: 00000797 auipc a5,0x0 + 69a: 56a78793 addi a5,a5,1386 # c00 while (s[n]) - 610: 0017c703 lbu a4,1(a5) - 614: 863e mv a2,a5 - 616: 0785 addi a5,a5,1 - 618: ff65 bnez a4,610 + 69e: 0017c703 lbu a4,1(a5) + 6a2: 863e mv a2,a5 + 6a4: 0785 addi a5,a5,1 + 6a6: ff65 bnez a4,69e write(1, s, strlen(s)); - 61a: 00ca863b addw a2,s5,a2 - 61e: 85da mv a1,s6 - 620: 4505 li a0,1 - 622: 04e000ef jal 670 + 6a8: 00ca863b addw a2,s5,a2 + 6ac: 85da mv a1,s6 + 6ae: 4505 li a0,1 + 6b0: 07e000ef jal 72e } - 626: bf6d j 5e0 + 6b4: bf6d j 66e + print("[Test] Read returned "); + 6b6: 00000517 auipc a0,0x0 + 6ba: 4aa50513 addi a0,a0,1194 # b60 + 6be: 971ff0ef jal 2e <_Z5printPKc> + print_int(n); + 6c2: 854a mv a0,s2 + 6c4: 993ff0ef jal 56 <_Z9print_inti> + print("\n"); + 6c8: 00000517 auipc a0,0x0 + 6cc: 29850513 addi a0,a0,664 # 960 + 6d0: 95fff0ef jal 2e <_Z5printPKc> + 6d4: b791 j 618 test_syscalls(); - 628: b59ff0ef jal 180 <_Z13test_syscallsv> - 62c: bf55 j 5e0 + 6d6: aadff0ef jal 182 <_Z13test_syscallsv> + 6da: bf51 j 66e if (fork() == 0) - 62e: 01a000ef jal 648 - 632: c509 beqz a0,63c + 6dc: 02a000ef jal 706 + 6e0: c509 beqz a0,6ea wait(0); - 634: 4501 li a0,0 - 636: 022000ef jal 658 - 63a: b75d j 5e0 + 6e2: 4501 li a0,0 + 6e4: 032000ef jal 716 + 6e8: b759 j 66e disk_test(); - 63c: 0bc000ef jal 6f8 + 6ea: 0cc000ef jal 7b6 exit(0); - 640: 4501 li a0,0 - 642: 00e000ef jal 650 - 646: b7fd j 634 + 6ee: 4501 li a0,0 + 6f0: 01e000ef jal 70e + 6f4: b7fd j 6e2 + print("[Test] Open failed (Is test.txt in fs.img?)\n"); + 6f6: 00000517 auipc a0,0x0 + 6fa: 3f250513 addi a0,a0,1010 # ae8 + 6fe: 931ff0ef jal 2e <_Z5printPKc> + 702: 840a mv s0,sp + 704: b71d j 62a -0000000000000648 : +0000000000000706 : name: \ li a7, SYS_ ## name; \ ecall; \ ret SYSCALL(fork) - 648: 4889 li a7,2 - 64a: 00000073 ecall - 64e: 8082 ret + 706: 4889 li a7,2 + 708: 00000073 ecall + 70c: 8082 ret -0000000000000650 : +000000000000070e : SYSCALL(exit) - 650: 488d li a7,3 - 652: 00000073 ecall - 656: 8082 ret + 70e: 488d li a7,3 + 710: 00000073 ecall + 714: 8082 ret -0000000000000658 : +0000000000000716 : SYSCALL(wait) - 658: 4891 li a7,4 - 65a: 00000073 ecall - 65e: 8082 ret + 716: 4891 li a7,4 + 718: 00000073 ecall + 71c: 8082 ret -0000000000000660 : +000000000000071e : SYSCALL(pipe) - 660: 4895 li a7,5 - 662: 00000073 ecall - 666: 8082 ret + 71e: 4895 li a7,5 + 720: 00000073 ecall + 724: 8082 ret -0000000000000668 : +0000000000000726 : SYSCALL(read) - 668: 4899 li a7,6 - 66a: 00000073 ecall - 66e: 8082 ret + 726: 4899 li a7,6 + 728: 00000073 ecall + 72c: 8082 ret -0000000000000670 : +000000000000072e : SYSCALL(write) - 670: 48c5 li a7,17 - 672: 00000073 ecall - 676: 8082 ret + 72e: 48c5 li a7,17 + 730: 00000073 ecall + 734: 8082 ret -0000000000000678 : +0000000000000736 : SYSCALL(close) - 678: 48d9 li a7,22 - 67a: 00000073 ecall - 67e: 8082 ret + 736: 48d9 li a7,22 + 738: 00000073 ecall + 73c: 8082 ret -0000000000000680 : +000000000000073e : SYSCALL(kill) - 680: 489d li a7,7 - 682: 00000073 ecall - 686: 8082 ret + 73e: 489d li a7,7 + 740: 00000073 ecall + 744: 8082 ret -0000000000000688 : +0000000000000746 : SYSCALL(exec) - 688: 48a1 li a7,8 - 68a: 00000073 ecall - 68e: 8082 ret + 746: 48a1 li a7,8 + 748: 00000073 ecall + 74c: 8082 ret -0000000000000690 : +000000000000074e : SYSCALL(open) - 690: 48c1 li a7,16 - 692: 00000073 ecall - 696: 8082 ret + 74e: 48c1 li a7,16 + 750: 00000073 ecall + 754: 8082 ret -0000000000000698 : +0000000000000756 : SYSCALL(mknod) - 698: 48c9 li a7,18 - 69a: 00000073 ecall - 69e: 8082 ret + 756: 48c9 li a7,18 + 758: 00000073 ecall + 75c: 8082 ret -00000000000006a0 : +000000000000075e : SYSCALL(unlink) - 6a0: 48cd li a7,19 - 6a2: 00000073 ecall - 6a6: 8082 ret + 75e: 48cd li a7,19 + 760: 00000073 ecall + 764: 8082 ret -00000000000006a8 : +0000000000000766 : SYSCALL(fstat) - 6a8: 48a5 li a7,9 - 6aa: 00000073 ecall - 6ae: 8082 ret + 766: 48a5 li a7,9 + 768: 00000073 ecall + 76c: 8082 ret -00000000000006b0 : +000000000000076e : SYSCALL(link) - 6b0: 48d1 li a7,20 - 6b2: 00000073 ecall - 6b6: 8082 ret + 76e: 48d1 li a7,20 + 770: 00000073 ecall + 774: 8082 ret -00000000000006b8 : +0000000000000776 : SYSCALL(mkdir) - 6b8: 48d5 li a7,21 - 6ba: 00000073 ecall - 6be: 8082 ret + 776: 48d5 li a7,21 + 778: 00000073 ecall + 77c: 8082 ret -00000000000006c0 : +000000000000077e : SYSCALL(chdir) - 6c0: 48a9 li a7,10 - 6c2: 00000073 ecall - 6c6: 8082 ret + 77e: 48a9 li a7,10 + 780: 00000073 ecall + 784: 8082 ret -00000000000006c8 : +0000000000000786 : SYSCALL(dup) - 6c8: 48ad li a7,11 - 6ca: 00000073 ecall - 6ce: 8082 ret + 786: 48ad li a7,11 + 788: 00000073 ecall + 78c: 8082 ret -00000000000006d0 : +000000000000078e : SYSCALL(getpid) - 6d0: 48b1 li a7,12 - 6d2: 00000073 ecall - 6d6: 8082 ret + 78e: 48b1 li a7,12 + 790: 00000073 ecall + 794: 8082 ret -00000000000006d8 : +0000000000000796 : SYSCALL(sbrk) - 6d8: 48b5 li a7,13 - 6da: 00000073 ecall - 6de: 8082 ret + 796: 48b5 li a7,13 + 798: 00000073 ecall + 79c: 8082 ret -00000000000006e0 : +000000000000079e : SYSCALL(sleep) - 6e0: 48b9 li a7,14 - 6e2: 00000073 ecall - 6e6: 8082 ret + 79e: 48b9 li a7,14 + 7a0: 00000073 ecall + 7a4: 8082 ret -00000000000006e8 : +00000000000007a6 : SYSCALL(uptime) - 6e8: 48bd li a7,15 - 6ea: 00000073 ecall - 6ee: 8082 ret + 7a6: 48bd li a7,15 + 7a8: 00000073 ecall + 7ac: 8082 ret -00000000000006f0 : +00000000000007ae : SYSCALL(putc) - 6f0: 4885 li a7,1 - 6f2: 00000073 ecall - 6f6: 8082 ret + 7ae: 4885 li a7,1 + 7b0: 00000073 ecall + 7b4: 8082 ret -00000000000006f8 : - 6f8: 48dd li a7,23 - 6fa: 00000073 ecall - 6fe: 8082 ret +00000000000007b6 : + 7b6: 48dd li a7,23 + 7b8: 00000073 ecall + 7bc: 8082 ret diff --git a/build/user/initcode.out b/build/user/initcode.out index c8d8b7f..78c9958 100755 Binary files a/build/user/initcode.out and b/build/user/initcode.out differ diff --git a/fs.img b/fs.img index fada73c..1709788 100644 Binary files a/fs.img and b/fs.img differ diff --git a/include/common/fcntl.h b/include/common/fcntl.h new file mode 100644 index 0000000..24d40fa --- /dev/null +++ b/include/common/fcntl.h @@ -0,0 +1,9 @@ +#pragma once + +#define O_RDONLY 0x000 +#define O_WRONLY 0x001 +#define O_RDWR 0x002 +#define O_CREATE 0x200 +#define O_TRUNC 0x400 + +#define NOFILE 16 \ No newline at end of file diff --git a/include/drivers/virtio.h b/include/drivers/virtio.h index 308dae0..ea2c9a6 100644 --- a/include/drivers/virtio.h +++ b/include/drivers/virtio.h @@ -99,4 +99,5 @@ namespace VirtIO void intr(); void rw(int write, uint64 blockno, char *buf); void test_rw(); + void test_bio(); } \ No newline at end of file diff --git a/include/fs/fat32.h b/include/fs/fat32.h new file mode 100644 index 0000000..c794bd7 --- /dev/null +++ b/include/fs/fat32.h @@ -0,0 +1,111 @@ +#pragma once +#include "fs/fs.h" +#include "kernel/buf.h" + +// Disk Layout Structures (On-Disk) + +// FAT32 Boot Sector (BPB) +struct FAT32_BPB +{ + uint8 jmpBoot[3]; + char oemName[8]; + uint16 bytesPerSector; + uint8 secPerClus; + uint16 reservedSecCnt; + uint8 numFATs; + uint16 rootEntCnt; + uint16 totSec16; + uint8 media; + uint16 FATSz16; + uint16 secPerTrk; + uint16 numHeads; + uint32 hiddSec; + uint32 totSec32; + uint32 FATSz32; + uint16 extFlags; + uint16 FSVer; + uint32 rootClus; + uint16 FSInfo; + uint16 bkBootSec; + uint8 reserved[12]; + uint8 drvNum; + uint8 reserved1; + uint8 bootSig; + uint32 volID; + char volLab[11]; + char filSysType[8]; +} __attribute__((packed)); + +// FAT32 Directory Entry (32 bytes) +struct FAT32_DirEnt +{ + char name[11]; // 8.3 filename + uint8 attr; // File attributes + uint8 ntRes; + uint8 crtTimeTenth; + uint16 crtTime; + uint16 crtDate; + uint16 lstAccDate; + uint16 fstClusHI; // High 16 bits of first cluster + uint16 wrtTime; + uint16 wrtDate; + uint16 fstClusLO; // Low 16 bits of first cluster + uint32 fileSize; +} __attribute__((packed)); + +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_LONG_NAME 0x0F + +// In-Memory Classes + +class FAT32FileSystem; + +class FAT32Inode : public Inode +{ +public: + FAT32FileSystem *fs; + + // FAT32 Private Data + uint32 first_clus; // The starting cluster number of the file + uint32 parent_clus; // Starting cluster number of the parent directory + uint32 dir_offset; // The byte offset of this directory entry in the parent directory + + FAT32Inode() : fs(nullptr), first_clus(0) {} + // Implement VFS Interface + void update() override; + int read(char *dst, uint32 off, uint32 n, int isUser) override; + int write(const char *src, uint32 off, uint32 n, int isUser) override; + Inode *lookup(const char *name) override; + Inode *create(const char *name, short type, short major, short minor) override; + void truncate() override; +}; + +class FAT32FileSystem : public FileSystem +{ +public: + uint32 fat_start_sector; + uint32 data_start_sector; + uint32 root_cluster; + uint32 sectors_per_cluster; + uint32 bytes_per_cluster; + + void init() override; + Inode* root() override; + + // Helper functions + uint32 next_cluster(uint32 cluster); // Check the FAT table for the next cluster + uint32 alloc_cluster(); // Assign a new cluster + uint32 cluster_to_sector(uint32 cluster); + + // directory entry parsing + void read_dir_ent(struct FAT32_DirEnt *de, char *filename); +}; + +extern FAT32FileSystem fat32_fs; + +void fat32_test(); \ No newline at end of file diff --git a/include/fs/file.h b/include/fs/file.h new file mode 100644 index 0000000..fc0c5d9 --- /dev/null +++ b/include/fs/file.h @@ -0,0 +1,35 @@ +#pragma once +#include "common/types.h" +#include "fs/fs.h" + +enum FileType +{ + FD_NONE, + FD_INODE, + FD_DEVICE, + FD_PIPE +}; + +struct file +{ + enum FileType type; + int ref; + char readable; + char writable; + + struct pipe *pipe; // pipeline pointer + Inode *ip; // VFS Inode + uint32 off; // Current Offset +}; + +namespace FileTable +{ + void init(); + struct file *alloc(); // Allocate a free file handle + struct file *dup(struct file *f); // Duplicate handle (sys_dup) + void close(struct file *f); // Close handle + + int stat(struct file *f, uint64 addr); + int read(struct file *f, uint64 addr, int n); + int write(struct file *f, uint64 addr, int n); +} // namespace FileTable diff --git a/include/fs/fs.h b/include/fs/fs.h new file mode 100644 index 0000000..6e4ec4b --- /dev/null +++ b/include/fs/fs.h @@ -0,0 +1,92 @@ +#pragma once +#include "common/types.h" +#include "kernel/spinlock.h" +#include "fs/stat.h" + +class FileSystem; + +// VFS Inode (Abstract Base Class) + +class Inode +{ +private: + ; +public: + // VFS Common Fields + uint32 dev; // Device number (VirtIO Block ID) + uint32 inum; // Inode number + int ref_cnt; // Memory reference count (number of struct file or processes referencing it) + int valid; // Whether the data is valid (whether metadata has been read from disk) + + Mutex lock; // Sleep lock: protects internal Inode data and atomicity of read/write operations + + // Metadata Cache (for speeding up getattr) + short type; // T_DIR, T_FILE, T_DEVICE + short major; // Major device number (only for T_DEVICE) + short minor; // Minor device number (only for T_DEVICE) + short nlink; // Number of hard links + uint32 size; // File size + + Inode() : ref_cnt(0), valid(0) + { + lock.init("inode"); + } + virtual ~Inode() {} + + /* Core Operation Interface (Subclass Must Implement) */ + // Update metadata + // Sync size, type, links, etc. from memory back to disk + virtual void update() = 0; + // Read content + // Read n bytes from the file at offset into dst + // Returns the actual number of bytes read, returns -1 on error + virtual int read(char *dst, uint32 off, uint32 n, int isUser) = 0; + // 3. Write content + // Write n bytes from src to the file at the given offset + // Need to handle file growth + virtual int write(const char *src, uint32 off, uint32 n, int isUser) = 0; + // Directory Lookup (only valid when type == T_DIR) + // Search for a file named 'name' in the current directory and return its Inode pointer (locked) + // Return nullptr if not found + virtual Inode *lookup(const char *name) = 0; + // Create file/directory (only effective when type == T_DIR) + // Create a new entry in the current directory + virtual Inode *create(const char *name, short type, short major, short minor) = 0; + // Get file status (populate the stat structure) + // Default implementation, subclasses can override to provide more detailed information + virtual void getattr(struct kstat *st); + // Truncate file (set size to 0, release all data blocks) + virtual void truncate() = 0; +}; + +// File System Abstraction (SuperBlock) +class FileSystem +{ +private: + ; +public: + virtual void init() = 0; + virtual Inode* root() = 0; + virtual ~FileSystem() {}; +}; + +// Inode Cache Interface (Global Function) +namespace VFS +{ + void init(); + + // Decrease the reference count, and if it reaches 0, free the memory + void iput(Inode *ip); + // Increase reference count + Inode *idup(Inode *ip); + // lock and load data + void ilock(Inode *ip); + // unlock + void iunlock(Inode *ip); + // Mount the root filesystem + void mount_root(Inode *root); + // Get system root node + Inode *get_root(); + // Path Analysis + Inode *namei(const char *path); +} // namespace VFS diff --git a/include/fs/stat.h b/include/fs/stat.h new file mode 100644 index 0000000..cdce05a --- /dev/null +++ b/include/fs/stat.h @@ -0,0 +1,22 @@ +#pragma once +#include "common/types.h" + +#define T_DIR 1 // Directory +#define T_FILE 2 // File +#define T_DEVICE 3 // Device + +struct kstat +{ + int dev; // File System's disk device + uint32 ino; // Inode number + short type; //Type of file + short nlink; // Number of links to file + uint64 size; // Size of file in bytes + + uint32 mode; // Protection: rwx + uint32 uid; // User ID + uint32 gid; // Group ID + uint32 atime; // Access time + uint32 mtime; // Modified time + uint32 ctime; // Change time +}; diff --git a/include/kernel/buf.h b/include/kernel/buf.h new file mode 100644 index 0000000..099523d --- /dev/null +++ b/include/kernel/buf.h @@ -0,0 +1,30 @@ +#pragma once +#include "common/types.h" +#include "kernel/spinlock.h" + +#define BSIZE 1024 +#define NBUF 30 + +struct Buf +{ + int valid; // Whether the data has been read from the disk (1=valid, 0=invalid) + int disk; // Whether it has been held by the driver (dirty bit/write-back flag is usually extended here) + uint32 dev; // Device Number + uint32 blockno; // Block number + uint32 refcnt; // Reference Counting + struct Buf *prev; // LRU linked list + struct Buf *next; + uchar data[BSIZE]; + + Mutex lock; // Sleep Lock +}; + +namespace BufferCache +{ + void init(); + struct Buf *bread(uint32 dev, uint32 blockno); + void bwrite(struct Buf *b); + void brelse(struct Buf *b); + void bpin(struct Buf *b); + void bunpin(struct Buf *b); +} // namespace BufferCache diff --git a/include/kernel/elf.h b/include/kernel/elf.h new file mode 100644 index 0000000..c216f1c --- /dev/null +++ b/include/kernel/elf.h @@ -0,0 +1,46 @@ +#pragma once +#include "common/types.h" + +#define ELF_MAGIC 0x464C457F // "\x7FELF" in little endian + +// ELF File Header +struct elfhdr +{ + uint32 magic; // Must equal ELF_MAGIC + uint8 elf[12]; + uint16 type; + uint16 machine; + uint32 version; + uint64 entry; // Program Entry Point (Virtual Address) + uint64 phoff; // File offset of the Program Header Table + uint64 shoff; + uint32 flags; + uint16 ehsize; + uint16 phentsize; + uint16 phnum; // Number of Program Headers + uint16 shentsize; + uint16 shnum; + uint16 shstrndx; +}; + +// Program Header +// Describes how to load segments from a file into memory +struct proghdr +{ + uint32 type; + uint32 flags; + uint64 off; // Offset of the section in the file + uint64 vaddr; // Virtual address of the segment in memory + uint64 paddr; + uint64 filesz; // Size of the section in the file + uint64 memsz; // The size of the segment in memory (memsz >= filesz) + uint64 align; +}; + +// Values for Proghdr type +#define ELF_PROG_LOAD 1 + +// Flag bits for Proghdr flags +#define ELF_PROG_FLAG_EXEC 1 +#define ELF_PROG_FLAG_WRITE 2 +#define ELF_PROG_FLAG_READ 4 \ No newline at end of file diff --git a/include/kernel/exec.h b/include/kernel/exec.h new file mode 100644 index 0000000..964e3bb --- /dev/null +++ b/include/kernel/exec.h @@ -0,0 +1,6 @@ +#pragma once + +namespace Exec +{ + int exec(char *path, char **argv); +} \ No newline at end of file diff --git a/include/kernel/mm.h b/include/kernel/mm.h index 363ce74..1850574 100644 --- a/include/kernel/mm.h +++ b/include/kernel/mm.h @@ -18,6 +18,7 @@ namespace VM int copyout(uint64 *pagetable, uint64 dstva, char *src, uint64 len); int copyin(uint64 *pagetable, char *dst, uint64 srcva, uint64 len); + int copyinstr(uint64 *pagetable, char *dst, uint64 srcva, uint64 max); int handle_cow_fault(uint64 *pagetable, uint64 va); int mappages(uint64 *pagetable, uint64 va, uint64 size, uint64 pa, int perm); diff --git a/include/kernel/proc_def.h b/include/kernel/proc_def.h index e5a2cbc..06c80aa 100644 --- a/include/kernel/proc_def.h +++ b/include/kernel/proc_def.h @@ -1,8 +1,11 @@ #pragma once #include "common/types.h" +#include "common/fcntl.h" struct cpu; struct Trapframe; +class Inode; +struct file; enum ProcState { @@ -51,6 +54,9 @@ struct Proc void *chan; int xstate; + Inode *cwd; + struct file *ofile[NOFILE]; + struct Proc *next; struct Proc *prev; int priority; diff --git a/include/lib/string.h b/include/lib/string.h index aa87489..309bf02 100644 --- a/include/lib/string.h +++ b/include/lib/string.h @@ -10,4 +10,5 @@ void *memcpy(void *dst, const void *src, uint n); void strcpy(char *dst, const char *src); int strlen(const char *s); -int strcmp(const char *s1, const char *s2); \ No newline at end of file +int strcmp(const char *s1, const char *s2); +int strcasecmp(const char *s1, const char *s2); \ No newline at end of file diff --git a/src/drivers/virtio_dist.cc b/src/drivers/virtio_dist.cc index 99d100f..9c981d4 100644 --- a/src/drivers/virtio_dist.cc +++ b/src/drivers/virtio_dist.cc @@ -5,6 +5,7 @@ #include "lib/string.h" #include "drivers/uart.h" #include "kernel/proc.h" +#include "kernel/buf.h" static uint64 virtio_base = 0x10001000; @@ -335,4 +336,39 @@ namespace VirtIO PMM::free_page(buf); } + + void test_bio() + { + Drivers::uart_puts(ANSI_BLUE "[Bio] Starting Buffer Cache Test...\n" ANSI_RESET); + + struct Buf *b = BufferCache::bread(0, 100); + + Drivers::uart_puts("[Bio] Bread block 100 (1st time).\n"); + + b->data[0] = 'L'; + b->data[1] = 'u'; + b->data[2] = 'm'; + b->data[3] = 'e'; + b->data[4] = '\0'; + + BufferCache::bwrite(b); + Drivers::uart_puts("[Bio] Bwrite block 100.\n"); + + BufferCache::brelse(b); + Drivers::uart_puts("[Bio] Brelease block 100.\n"); + + struct Buf *b2 = BufferCache::bread(0, 100); + Drivers::uart_puts("[Bio] Bread block 100 (2nd time).\n"); + + if (b2->data[0] == 'L' && b2->data[1] == 'u' && b2->data[3] == 'e') + { + Drivers::uart_puts(ANSI_GREEN "[Bio] Data verification PASSED.\n" ANSI_RESET); + } + else + { + Drivers::uart_puts(ANSI_RED "[Bio] Data verification FAILED.\n" ANSI_RESET); + } + + BufferCache::brelse(b2); + } } \ No newline at end of file diff --git a/src/fs/fat32.cc b/src/fs/fat32.cc new file mode 100644 index 0000000..7ef829a --- /dev/null +++ b/src/fs/fat32.cc @@ -0,0 +1,325 @@ +#include "fs/fat32.h" +#include "lib/string.h" +#include "drivers/uart.h" +#include "kernel/mm.h" +#include "kernel/proc.h" + +FAT32FileSystem fat32_fs; + +// FAT32 FileSystem Implementation + +void FAT32FileSystem::init() +{ + struct Buf *b = BufferCache::bread(0, 0); + uint8 *data = (uint8 *)b->data; + struct FAT32_BPB *bpb = (struct FAT32_BPB *)data; + + uint32 partition_lba = 0; + + bool is_valid_bpb = (bpb->bytesPerSector == 512) && (bpb->rootClus != 0); + + if (!is_valid_bpb) + { + Drivers::uart_puts("[FAT32] Sector 0 is not a valid BPB. Checking MBR...\n"); + + if (data[510] != 0x55 || data[511] != 0xAA) + { + Drivers::uart_puts("[FAT32] Panic: Invalid Disk Signature!\n"); + while (1) + ; + } + + uint32 lba = *(uint32 *)(data + 446 + 8); + + if (lba > 0) + { + Drivers::uart_puts("[FAT32] MBR Partition 1 found @ Sector "); + Drivers::uart_put_int(lba); + Drivers::uart_puts("\n"); + partition_lba = lba; + } + else + { + Drivers::uart_puts("[FAT32] Panic: No partition found.\n"); + while (1) + ; + } + + BufferCache::brelse(b); + + b = BufferCache::bread(0, partition_lba / 2); + bpb = (struct FAT32_BPB *)b->data; + } + + if (bpb->bytesPerSector != 512) + { + Drivers::uart_puts("[FAT32] Panic: Invalid FAT32 BPB in partition.\n"); + while (1) + ; + } + + uint32 fat_sz = bpb->FATSz32; + uint32 reserved_sec = bpb->reservedSecCnt; + uint8 num_fats = bpb->numFATs; + + sectors_per_cluster = bpb->secPerClus; + bytes_per_cluster = sectors_per_cluster * 512; + root_cluster = bpb->rootClus; + + fat_start_sector = partition_lba + reserved_sec; + data_start_sector = partition_lba + reserved_sec + (fat_sz * num_fats); + + Drivers::uart_puts("[FAT32] Init Success: RootClus="); + Drivers::uart_put_int(root_cluster); + Drivers::uart_puts(", DataStart="); + Drivers::uart_put_int(data_start_sector); + Drivers::uart_puts("\n"); + + BufferCache::brelse(b); +} + +Inode *FAT32FileSystem::root() +{ + FAT32Inode *ip = new FAT32Inode(); + + ip->fs = this; + ip->dev = 0; + ip->inum = root_cluster; + ip->ref_cnt = 1; + ip->valid = 1; + ip->type = T_DIR; + ip->size = 0; + ip->nlink = 1; + + ip->first_clus = root_cluster; + ip->parent_clus = 0; + + return ip; +} + +uint32 FAT32FileSystem::cluster_to_sector(uint32 cluster) +{ + return data_start_sector + (cluster - 2) * sectors_per_cluster; +} + +uint32 FAT32FileSystem::next_cluster(uint32 cluster) +{ + uint32 fat_offset = cluster * 4; + uint32 fat_sector = fat_start_sector + (fat_offset / 512); + uint32 ent_offset = fat_offset % 512; + + // block = sector / 2 + // offset in block = (sector % 2) * 512 + ent_offset + + struct Buf *b = BufferCache::bread(0, fat_sector / 2); + + uint32 block_offset = (fat_sector % 2) * 512 + ent_offset; + uint32 next = *(uint32 *)(b->data + block_offset); + + BufferCache::brelse(b); + + return next & 0x0FFFFFFF; +} + +// FAT32 Inode Implementation + +static bool match_name(const char *disk_name, const char *target) +{ + char temp[13]; + int i, j; + + for (i = 0; i < 8 && disk_name[i] != ' '; i++) + temp[i] = disk_name[i]; + if (disk_name[8] != ' ') + { + temp[i++] = '.'; + for (j = 0; j < 3 && disk_name[8 + j] != ' '; j++) + temp[i++] = disk_name[8 + j]; + } + temp[i] = 0; + return strcasecmp(temp, target) == 0; +} + +int FAT32Inode::read(char *dst, uint32 off, uint32 n, int isUser) +{ + if (first_clus == 0) + return 0; + + uint32 tot = 0; + uint32 clus = first_clus; + uint32 clus_sz = fs->bytes_per_cluster; + + uint32 skip = off / clus_sz; + uint32 current_off = off % clus_sz; + + while (skip > 0) + { + clus = fs->next_cluster(clus); + if (clus >= 0x0FFFFFF8) + return 0; + skip--; + } + + while (tot < n) + { + uint32 sec_in_clus = current_off / 512; + + if (sec_in_clus >= fs->sectors_per_cluster) + { + clus = fs->next_cluster(clus); + if (clus >= 0x0FFFFFF8) + break; + current_off = 0; + continue; + } + + uint32 sec = fs->cluster_to_sector(clus) + sec_in_clus; + uint32 off_in_sec = current_off % 512; + + uint32 m = 512 - off_in_sec; + if (n - tot < m) + m = n - tot; + + struct Buf *b = BufferCache::bread(dev, sec / 2); + uint32 block_offset = (sec % 2) * 512 + off_in_sec; + + if (isUser) + { + if (VM::copyout(myproc()->pagetable, (uint64)dst, (char *)(b->data + block_offset), m) < 0) + { + BufferCache::brelse(b); + return -1; + } + } + else + { + memmove(dst, b->data + block_offset, m); + } + BufferCache::brelse(b); + + tot += m; + dst += m; + current_off += m; + } + return tot; +} + +Inode *FAT32Inode::lookup(const char *name) +{ + if (type != T_DIR) + return nullptr; + + uint32 clus = first_clus; + struct FAT32_DirEnt de; + + while (clus < 0x0FFFFFF8) + { + uint32 sec = fs->cluster_to_sector(clus); + + for (int i = 0; i < fs->sectors_per_cluster; i++) + { + uint32 current_sec = sec + i; + struct Buf *b = BufferCache::bread(dev, current_sec / 2); + uint32 block_base = (current_sec % 2) * 512; + + for (int off = 0; off < 512; off += 32) + { + memmove(&de, b->data + block_base + off, 32); + + if (de.name[0] == 0x00) + { + BufferCache::brelse(b); + return nullptr; + } + if (de.name[0] == 0xE5) + continue; + if (de.attr & ATTR_LONG_NAME) + continue; + + if (match_name(de.name, name)) + { + FAT32Inode *ip = new FAT32Inode(); + ip->fs = fs; + ip->dev = dev; + ip->type = (de.attr & ATTR_DIRECTORY) ? T_DIR : T_FILE; + ip->size = de.fileSize; + ip->first_clus = (de.fstClusHI << 16) | de.fstClusLO; + ip->inum = ip->first_clus; + ip->nlink = 1; + ip->ref_cnt = 1; + ip->valid = 1; + + BufferCache::brelse(b); + return ip; + } + } + BufferCache::brelse(b); + } + clus = fs->next_cluster(clus); + } + return nullptr; +} + +// Placeholder +void FAT32Inode::update() {} +int FAT32Inode::write(const char *src, uint32 off, uint32 n, int isUser) { return -1; } +Inode *FAT32Inode::create(const char *name, short type, short major, short minor) { return nullptr; } +void FAT32Inode::truncate() {} +uint32 FAT32FileSystem::alloc_cluster() { return 0; } + +// Test Function +void fat32_test() +{ + static bool inited = false; + if (!inited) + { + fat32_fs.init(); + inited = true; + } + + Drivers::uart_puts("\n[FAT32] Starting Test via Syscall...\n"); + + Inode *root = fat32_fs.root(); + if (root) + { + Drivers::uart_puts("[FAT32] Root Inode retrieved. Inum: "); + Drivers::uart_put_int(root->inum); + Drivers::uart_puts("\n"); + + Drivers::uart_puts("[FAT32] Looking for TEST.TXT...\n"); + Inode *node = root->lookup("test.txt"); + + if (node) + { + Drivers::uart_puts("[FAT32] Found TEST.TXT! Size: "); + Drivers::uart_put_int(node->size); + Drivers::uart_puts("\n"); + + char buf[128]; + int n = node->read(buf, 0, 127, 0); + if (n > 0) + { + buf[n] = 0; + Drivers::uart_puts("[FAT32] Content:\n>> "); + Drivers::uart_puts(buf); + Drivers::uart_puts("\n"); + } + else + { + Drivers::uart_puts("[FAT32] Read returned 0.\n"); + } + VFS::iput(node); + } + else + { + Drivers::uart_puts("[FAT32] TEST.TXT not found.\n"); + } + VFS::iput(root); + } + else + { + Drivers::uart_puts("[FAT32] Failed to get root inode.\n"); + } + + Drivers::uart_puts("[FAT32] Test Finished.\n"); +} \ No newline at end of file diff --git a/src/fs/file.cc b/src/fs/file.cc new file mode 100644 index 0000000..48af49e --- /dev/null +++ b/src/fs/file.cc @@ -0,0 +1,140 @@ +#include "fs/file.h" +#include "kernel/spinlock.h" +#include "kernel/mm.h" +#include "drivers/uart.h" +#include "kernel/proc.h" + +#define NFILE 100 + +namespace FileTable +{ + struct + { + Spinlock lock; + struct file files[NFILE]; + } ftable; + + void init() + { + ftable.lock.init("file_table"); + } + + struct file *alloc() + { + struct file *f; + ftable.lock.acquire(); + for (f = ftable.files; f < ftable.files + NFILE; f++) + { + if (f->ref == 0) + { + f->ref = 1; + ftable.lock.release(); + return f; + } + } + ftable.lock.release(); + return nullptr; + } + + struct file *dup(struct file *f) + { + ftable.lock.acquire(); + if (f->ref < 1) + { + Drivers::uart_puts("panic: file dup\n"); + while (1) + ; + } + f->ref++; + ftable.lock.release(); + return f; + } + + void close(struct file *f) + { + struct file ff; + + ftable.lock.acquire(); + if(f->ref < 1) + { + Drivers::uart_puts("panic: file close\n"); + while (1) + ; + } + f->ref--; + if (f->ref > 0) + { + ftable.lock.release(); + return; + } + + ff = *f; + f->ref = 0; + f->type = FD_NONE; + ftable.lock.release(); + if (ff.type == FD_INODE) + { + // Release the corresponding Inode + VFS::iput(ff.ip); + } + else if (ff.type == FD_PIPE) + { + // pipeclose(ff.pipe, ff.writable); + } + } + + int read(struct file *f, uint64 addr, int n) + { + if (f->readable == 0) + return -1; + if (f->type == FD_INODE) + { + VFS::ilock(f->ip); + int r = f->ip->read((char*)addr, f->off, n, 1); + if(r > 0) + { + f->off += r; + } + VFS::iunlock(f->ip); + return r; + } + return -1; + } + + int write(struct file *f, uint64 addr, int n) + { + if (f->writable == 0) + return -1; + if (f->type == FD_INODE) + { + VFS::ilock(f->ip); + int r = f->ip->write((char *)addr, f->off, n, 1); + if (r > 0) + { + f->off += r; + } + VFS::iunlock(f->ip); + return r; + } + // else if (f->type == FD_PIPE) ... + + return -1; + } + + int stat(struct file *f, uint64 addr) + { + if (f->type == FD_INODE) + { + struct kstat st; + VFS::ilock(f->ip); + f->ip->getattr(&st); + VFS::iunlock(f->ip); + + struct Proc *p = myproc(); + if (VM::copyout(p->pagetable, addr, (char *)&st, sizeof(st)) < 0) + return -1; + return 0; + } + return -1; + } +} // namespace FileTable diff --git a/src/fs/fs.cc b/src/fs/fs.cc new file mode 100644 index 0000000..b2b91c2 --- /dev/null +++ b/src/fs/fs.cc @@ -0,0 +1,190 @@ +#include "fs/fs.h" +#include "kernel/riscv.h" +#include "drivers/uart.h" +#include "kernel/spinlock.h" +#include "kernel/proc.h" +#include "fs/fat32.h" +#include "lib/string.h" + +static Inode *global_root_inode = nullptr; + +static const char *skipelem(const char *path, char *name) +{ + const char *s; + int len; + + while (*path == '/') + path++; + if (*path == 0) + return nullptr; + + s = path; + while (*path != '/' && *path != 0) + path++; + + len = path - s; + if (len >= 128) + len = 127; + + memmove(name, s, len); + name[len] = 0; + + while (*path == '/') + path++; + return path; +} + +void Inode::getattr(struct kstat *st) +{ + st->dev = dev; + st->ino = inum; + st->type = type; + st->nlink = nlink; + st->size = size; + + st->uid = 0; + st->gid = 0; + st->mode = 0; +} + +namespace VFS +{ + void init() + { + Drivers::uart_puts("[VFS] Inode subsystem initialized.\n"); + } + + void iput(Inode *ip) + { + if (ip == nullptr) + return; + + ip->lock.acquire(); + if(ip->ref_cnt < 1) + { + Drivers::uart_puts("panic: iput ref\n"); + while (1) + ; + } + ip->ref_cnt--; + int ref = ip->ref_cnt; + ip->lock.release(); + + if (ref == 0) + { + delete ip; + } + } + + Inode* idup(Inode *ip) + { + if (ip == nullptr) + return nullptr; + + ip->lock.acquire(); + ip->ref_cnt++; + ip->lock.release(); + return ip; + } + + void ilock(Inode *ip) + { + if (ip == 0 || ip->ref_cnt < 1) + { + Drivers::uart_puts("panic: ilock\n"); + while (1) + ; + } + + ip->lock.acquire(); + + } + + void iunlock(Inode *ip) + { + if (ip == 0 || !ip->lock.holding() || ip->ref_cnt < 1) + { + Drivers::uart_puts("panic: iunlock\n"); + while (1) + ; + } + ip->lock.release(); + } + + static void iunlockput(Inode *ip) + { + iunlock(ip); + iput(ip); + } + + void mount_root(Inode *root) + { + if (global_root_inode) + { + Drivers::uart_puts("VFS: Root already mounted!\n"); + return; + } + global_root_inode = root; + Drivers::uart_puts("[VFS] Root filesystem mounted.\n"); + } + + Inode *get_root() + { + if (global_root_inode == nullptr) + { + Drivers::uart_puts("[VFS] Lazy init: Mounting FAT32...\n"); + fat32_fs.init(); + mount_root(fat32_fs.root()); + } + if (!global_root_inode) + return nullptr; + return idup(global_root_inode); + } + + Inode *namei(const char *path) + { + char name[128]; + Inode *ip, *next; + struct Proc *p = myproc(); + + if (*path == '/') + { + ip = get_root(); + } + else + { + if (p->cwd == nullptr) + { + ip = get_root(); + } + else + { + ip = idup(p->cwd); + } + } + + if (ip == nullptr) + return nullptr; + + while ((path = skipelem(path, name)) != nullptr) + { + ilock(ip); + + if (ip->type != T_DIR) + { + iunlockput(ip); + return nullptr; + } + + next = ip->lookup(name); + iunlockput(ip); + + ip = next; + if (ip == nullptr) + return nullptr; + } + + return ip; + } + +} // namespace VFS diff --git a/src/kernel/bio.cc b/src/kernel/bio.cc new file mode 100644 index 0000000..6e63d60 --- /dev/null +++ b/src/kernel/bio.cc @@ -0,0 +1,135 @@ +#include "kernel/buf.h" +#include "kernel/spinlock.h" +#include "kernel/riscv.h" +#include "drivers/virtio.h" +#include "drivers/uart.h" + +namespace BufferCache +{ + struct + { + Spinlock lock; + struct Buf buf[NBUF]; + struct Buf head; + } bcache; + + void init() + { + bcache.lock.init("bcache"); + // Initialize LRU doubly circular linked list + bcache.head.prev = &bcache.head; + bcache.head.next = &bcache.head; + for (struct Buf *b = bcache.buf; b < bcache.buf + NBUF; ++b) + { + b->lock.init("buffer"); + b->next = bcache.head.next; + b->prev = &bcache.head; + bcache.head.next->prev = b; + bcache.head.next = b; + } + Drivers::uart_puts("[Bio] Buffer cache initialized.\n"); + } + + static struct Buf* bget(uint32 dev, uint32 blockno) + { + struct Buf* b; + bcache.lock.acquire(); + + // Attempt to hit the cache + for (b = bcache.head.next; b != &bcache.head; b = b->next) + { + if (b->dev == dev && b->blockno == blockno) + { + b->refcnt++; + bcache.lock.release(); + b->lock.acquire(); // Acquire Sleep Lock + return b; + } + } + + // Cache miss, evicting LRU + for (b = bcache.head.prev; b != &bcache.head; b = b->prev) + { + if (b->refcnt == 0) + { + b->dev = dev; + b->blockno = blockno; + b->valid = 0; + b->refcnt = 1; + bcache.lock.release(); + b->lock.acquire(); + return b; + } + } + + Drivers::uart_puts("panic: bget: no buffers\n"); + while (1) + ; + } + + struct Buf* bread(uint32 dev, uint32 blockno) + { + struct Buf *b = bget(dev, blockno); + + if (!b->valid) + { + VirtIO::rw(0, b->blockno, (char *)b->data); + b->valid = 1; + } + + return b; + } + + void bwrite(struct Buf *b) + { + if (!b->lock.holding()) + { + Drivers::uart_puts("panic: bwrite\n"); + while (1) + ; + } + VirtIO::rw(1, b->blockno, (char *)b->data); + } + + void brelse(struct Buf *b) + { + if (!b->lock.holding()) + { + Drivers::uart_puts("panic: brelse\n"); + while (1) + ; + } + b->lock.release(); + + bcache.lock.acquire(); + b->refcnt--; + + if (b->refcnt == 0) + { + b->next->prev = b->prev; + b->prev->next = b->next; + + b->next = bcache.head.next; + b->prev = &bcache.head; + bcache.head.next->prev = b; + bcache.head.next = b; + } + + bcache.lock.release(); + } + + void bpin(struct Buf *b) + { + bcache.lock.acquire(); + b->refcnt++; + bcache.lock.release(); + } + + void bunpin(struct Buf* b) + { + bcache.lock.acquire(); + b->refcnt --; + bcache.lock.release(); + } + +} // namespace BufferCache diff --git a/src/kernel/cxx.cc b/src/kernel/cxx.cc new file mode 100644 index 0000000..f9541b5 --- /dev/null +++ b/src/kernel/cxx.cc @@ -0,0 +1,68 @@ +#include "common/types.h" +#include "kernel/pmm.h" +#include "drivers/uart.h" + +/* + * C++ Kernel Runtime Support + * + * * Strategy: Map directly to PMM::alloc_page(). + * Pros: Simple, works immediately for VFS. + * Cons: Allocates 4KB for every object (wasteful for small objects), + * but acceptable for current stage. + */ + +void *operator new(unsigned long size) +{ + // Safety check: PMM allocates 4096 bytes max per call + if (size > 4096) + { + Drivers::uart_puts("panic: new allocation too big (max 4096)\n"); + while (1) + ; + } + + void *p = PMM::alloc_page(); + if (!p) + { + Drivers::uart_puts("panic: new out of memory\n"); + while (1) + ; + } + // PMM::alloc_page returns zeroed memory usually, + // but standard 'new' doesn't guarantee it. + // The constructor will handle initialization. + return p; +} + +void *operator new[](unsigned long size) +{ + return operator new(size); +} + +void operator delete(void *p) +{ + if (p) + PMM::free_page(p); +} + +void operator delete[](void *p) +{ + if (p) + PMM::free_page(p); +} + +// C++14 Sized Deallocation (Required by modern compilers) +// The compiler optimizes 'delete' calls to pass the size of the object +void operator delete(void *p, unsigned long size) +{ + (void)size; // We ignore size because PMM always frees a full page + if (p) + PMM::free_page(p); +} + +void operator delete[](void *p, unsigned long size) +{ + (void)size; + if (p) + PMM::free_page(p); +} \ No newline at end of file diff --git a/src/kernel/main.cc b/src/kernel/main.cc index 6e3bdde..9654c18 100644 --- a/src/kernel/main.cc +++ b/src/kernel/main.cc @@ -9,6 +9,11 @@ #include "kernel/trap.h" #include "kernel/timer.h" #include "kernel/cpu.h" +#include "kernel/buf.h" +#include "fs/fs.h" +#include "fs/file.h" +#include "fs/fat32.h" +#include "lib/string.h" extern void fdt_init(uint64 dtb); extern uint64 g_dtb_addr; @@ -34,6 +39,9 @@ extern "C" void kernel_main(uint64 hartid, uint64 dtb) PLIC::init(); PLIC::inithart(); VirtIO::init(); + BufferCache::init(); + VFS::init(); + FileTable::init(); Timer::init(); ProcManager::init(); // Process Management ProcManager::user_init(); // Initialize first user process diff --git a/src/kernel/mm/vm.cc b/src/kernel/mm/vm.cc index 7057d88..29e9eb7 100644 --- a/src/kernel/mm/vm.cc +++ b/src/kernel/mm/vm.cc @@ -313,6 +313,53 @@ namespace VM return 0; } + int copyinstr(uint64 *pagetable, char *dst, uint64 srcva, uint64 max) + { + uint64 n, va0, pa0; + uint64 *pte; + int got_null = 0; + uint64 len = 0; + + while (len < max) + { + va0 = PGROUNDDOWN(srcva); + pte = walk(pagetable, va0, 0); + + if (pte == nullptr || (*pte & PTE_V) == 0 || (*pte & PTE_U) == 0) + return -1; + + pa0 = PTE2PA(*pte); + + n = PGSIZE - (srcva - va0); + if (n > max - len) + n = max - len; + + char *p = (char *)(pa0 + (srcva - va0)); + while (n > 0) + { + if (*p == '\0') + { + *dst = '\0'; + got_null = 1; + break; + } + *dst = *p; + n--; + srcva++; + dst++; + p++; + len++; + } + if (got_null) + break; + } + + if (got_null) + return 0; + + return -1; + } + int handle_cow_fault(uint64 *pagetable, uint64 va) { if (va >= MAXVA) diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc index c8b6d1d..f1f1c1d 100644 --- a/src/kernel/proc/proc.cc +++ b/src/kernel/proc/proc.cc @@ -8,6 +8,8 @@ #include "kernel/trap.h" #include "kernel/riscv.h" #include "drivers/uart.h" +#include "fs/fs.h" +#include "fs/file.h" #include "lib/string.h" #define NPROC 64 @@ -172,6 +174,9 @@ found: p->pid = nextpid++; p->priority = 0; p->cpu = mycpu(); + p->cwd = nullptr; + for (int i = 0; i < NOFILE; i++) + p->ofile[i] = nullptr; if ((p->tf = (struct Trapframe *)PMM::alloc_page()) == 0) { @@ -206,6 +211,19 @@ static void freeproc(struct Proc *p) p->kstack = 0; if (p->pagetable) VM::uvmfree(p->pagetable, p->sz); + for (int i = 0; i < NOFILE; i++) + { + if (p->ofile[i]) + { + FileTable::close(p->ofile[i]); + p->ofile[i] = nullptr; + } + } + if (p->cwd) + { + VFS::iput(p->cwd); + p->cwd = nullptr; + } p->pagetable = 0; p->sz = 0; p->pid = 0; @@ -245,6 +263,19 @@ int fork() np->parent = p; np->priority = p->priority; + for (int i = 0; i < NOFILE; i++) + { + if (p->ofile[i]) + { + np->ofile[i] = FileTable::dup(p->ofile[i]); + } + } + + if (p->cwd) + { + np->cwd = VFS::idup(p->cwd); + } + proc_mem_lock.release(); struct cpu *c = mycpu(); @@ -394,6 +425,8 @@ namespace ProcManager p->sz = stack_va + PGSIZE; strcpy(p->name, "initcode"); + p->cwd = nullptr; + proc_mem_lock.release(); struct cpu *c = &cpus[0]; diff --git a/src/kernel/syscall.cc b/src/kernel/syscall.cc index 837ac2c..afa20a1 100644 --- a/src/kernel/syscall.cc +++ b/src/kernel/syscall.cc @@ -1,5 +1,6 @@ #include "kernel/syscall.h" #include "common/types.h" +#include "common/fcntl.h" #include "kernel/proc.h" #include "kernel/riscv.h" #include "drivers/uart.h" @@ -7,6 +8,8 @@ #include "kernel/timer.h" #include "kernel/mm.h" #include "kernel/trap.h" +#include "fs/fat32.h" +#include "fs/file.h" extern "C++" int fork(); @@ -45,47 +48,126 @@ static int argint(int n, int *ip) return 0; } +static int argstr(int n, char *buf, int max) +{ + uint64 addr = argraw(n); + return VM::copyinstr(myproc()->pagetable, buf, addr, max); +} + +static int fdalloc(struct file *f) +{ + struct Proc *p = myproc(); + for (int i = 0; i < NOFILE; i++) + { + if (p->ofile[i] == 0) + { + p->ofile[i] = f; + return i; + } + } + return -1; +} + +static uint64 sys_open() +{ + char path[128]; + int omode; + int fd; + struct file *f; + Inode *ip; + + if (argstr(0, path, 128) < 0 || argint(1, &omode) < 0) + return -1; + + ip = VFS::namei(path); + if (ip == nullptr) + { + return -1; + } + + f = FileTable::alloc(); + if (f == nullptr) + { + VFS::iput(ip); + return -1; + } + + fd = fdalloc(f); + if (fd < 0) + { + f->ref = 0; + f->type = FD_NONE; + VFS::iput(ip); + return -1; + } + + f->type = FD_INODE; + f->ip = ip; + f->off = 0; + f->readable = !(omode & O_WRONLY); + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); -static uint64_t sys_exit() + return fd; +} + +static uint64 sys_close() +{ + int fd; + if (argint(0, &fd) < 0) + return -1; + + struct Proc *p = myproc(); + if (fd < 0 || fd >= NOFILE || p->ofile[fd] == 0) + return -1; + + FileTable::close(p->ofile[fd]); + p->ofile[fd] = 0; + return 0; +} + +static uint64 sys_exit() { int n; if (argint(0, &n) < 0) - return static_cast(-1); + return static_cast(-1); ProcManager::exit(n); return 0; } -static uint64_t sys_fork() +static uint64 sys_fork() { - return static_cast(fork()); + return static_cast(fork()); } -static uint64_t sys_wait() +static uint64 sys_wait() { - uint64_t p = argraw(0); - return static_cast(ProcManager::wait(p)); + uint64 p = argraw(0); + return static_cast(ProcManager::wait(p)); } -static uint64_t sys_getpid() +static uint64 sys_getpid() { - return static_cast(myproc()->pid); + return static_cast(myproc()->pid); } -static uint64_t sys_putc() +static uint64 sys_putc() { char c = static_cast(argraw(0)); Drivers::uart_putc(c); return 0; } -static uint64_t sys_write() +static uint64 sys_write() { - int fd; + struct file *f; int n; - uint64_t p; + uint64 p; + int fd; - if (argint(0, &fd) < 0 || argint(2, &n) < 0) - return static_cast(-1); + if (argint(0, &fd) < 0 || argint(2, &n) < 0 || argint(1, (int *)&p) < 0) + return -1; + + struct Proc *proc = myproc(); p = argraw(1); @@ -95,9 +177,8 @@ static uint64_t sys_write() // Drivers::uart_put_int(n); // Drivers::uart_puts("\n"); - if (fd == 1) // stdout + if (fd == 1 && proc->ofile[fd] == nullptr) // stdout { - Proc *proc = myproc(); constexpr int MAX_WRITE_BUF = 128; char buf[MAX_WRITE_BUF]; int i = 0; @@ -108,10 +189,10 @@ static uint64_t sys_write() if (len > MAX_WRITE_BUF) len = MAX_WRITE_BUF; - if (VM::copyin(proc->pagetable, buf, p + i, static_cast(len)) < 0) + if (VM::copyin(proc->pagetable, buf, p + i, static_cast(len)) < 0) { Drivers::uart_puts("sys_write: copyin failed\n"); - return static_cast(-1); + return static_cast(-1); } for (int j = 0; j < len; j++) @@ -120,45 +201,57 @@ static uint64_t sys_write() } i += len; } - return static_cast(n); + return static_cast(n); } - return static_cast(-1); + if (fd < 0 || fd >= NOFILE || (f = proc->ofile[fd]) == 0) + return static_cast(-1); + + return FileTable::write(f, p, n); } static uint64_t sys_read() { - int fd; + struct file *f; int n; - uint64_t p; + uint64 p; + int fd; // get param: fd, buf, len - if (argint(0, &fd) < 0 || argint(2, &n) < 0) + if (argint(0, &fd) < 0 || argint(2, &n) < 0 || argint(1, (int *)&p) < 0) return -1; - p = argraw(1); - - if (fd == 0) // stdin + + struct Proc* proc = myproc(); + if (fd == 0 && proc->ofile[fd] == nullptr) { return Drivers::console_read(p, n); } + + if (fd < 0 || fd >= NOFILE || (f = proc->ofile[fd]) == 0) + return -1; + + return FileTable::read(f, p, n); + return -1; } -static uint64_t sys_sbrk() +static uint64 sys_sbrk() { int n; if (argint(0, &n) < 0) return -1; - uint64_t addr = myproc()->sz; + uint64 addr = myproc()->sz; if (ProcManager::growproc(n) < 0) return -1; return addr; } -static uint64_t sys_disk_test() +static uint64 sys_disk_test() { - VirtIO::test_rw(); + // VirtIO::test_rw(); + // VirtIO::test_bio(); + fat32_test(); return 0; } @@ -166,7 +259,7 @@ void syscall() { Proc *p = myproc(); int num = p->tf->a7; - uint64_t ret = static_cast(-1); + uint64 ret = static_cast(-1); /* Just For Debug */ // Drivers::uart_puts("Syscall: "); @@ -175,6 +268,12 @@ void syscall() switch (num) { + case SYS_open: + ret = sys_open(); + break; + case SYS_close: + ret = sys_close(); + break; case SYS_write: ret = sys_write(); break; @@ -206,7 +305,7 @@ void syscall() Drivers::uart_puts("Unknown Syscall ID: "); Drivers::print_hex(num); Drivers::uart_puts("\n"); - ret = static_cast(-1); + ret = static_cast(-1); break; } diff --git a/src/lib/string.cc b/src/lib/string.cc index bbd079d..a302fc6 100644 --- a/src/lib/string.cc +++ b/src/lib/string.cc @@ -69,3 +69,16 @@ int strcmp(const char *s1, const char *s2) } return *(const unsigned char *)s1 - *(const unsigned char *)s2; } + +int strcasecmp(const char *s1, const char *s2) +{ + while (*s1) + { + if(*s1 == *s2 || *s1 + 32 == *s2 || *s1 == *s2 + 32){ + s1++; + s2++; + } + else break; + } + return *(const unsigned char *)s1 - *(const unsigned char *)s2; +} \ No newline at end of file diff --git a/src/user/init.cc b/src/user/init.cc index 1646f6b..27c1e2f 100644 --- a/src/user/init.cc +++ b/src/user/init.cc @@ -1,4 +1,5 @@ #include "user/user.h" +#include "common/fcntl.h" int strlen(const char *s) { @@ -149,7 +150,40 @@ void test_syscalls() int main() { - print("\n[Lume Shell] Ready.\n"); + print("\n[Lume Shell] Init process started.\n"); + print("[Test] Opening test.txt...\n"); + int fd = open("test.txt", O_RDONLY); + if (fd < 0) + { + print("[Test] Open failed (Is test.txt in fs.img?)\n"); + } + else + { + print("[Test] Open success! fd="); + print_int(fd); + print("\n"); + + char buf[64]; + int n = read(fd, buf, 63); + if (n > 0) + { + buf[n] = 0; + print("[Test] Read content:\n---\n"); + print(buf); + print("\n---\n"); + } + else + { + print("[Test] Read returned "); + print_int(n); + print("\n"); + } + close(fd); + print("[Test] File closed.\n"); + } + + + print("Commands:\n"); print(" s: Run System Call Tests (fork, wait, mm)\n"); print(" t: Run Disk Driver Test (VirtIO)\n"); -- cgit v1.2.3