summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rwxr-xr-xbuild/kernel.elfbin156920 -> 184056 bytes
-rw-r--r--build/src/drivers/plic.obin13800 -> 19656 bytes
-rw-r--r--build/src/drivers/uart.obin57352 -> 92888 bytes
-rw-r--r--build/src/drivers/virtio_dist.obin0 -> 93248 bytes
-rw-r--r--build/src/kernel/initcode.obin2448 -> 3952 bytes
-rw-r--r--build/src/kernel/main.obin17744 -> 19608 bytes
-rw-r--r--build/src/kernel/mm/pmm.obin90424 -> 90424 bytes
-rw-r--r--build/src/kernel/mm/slab.obin67304 -> 67664 bytes
-rw-r--r--build/src/kernel/mm/vm.obin213776 -> 214608 bytes
-rw-r--r--build/src/kernel/proc/proc.obin205000 -> 212272 bytes
-rw-r--r--build/src/kernel/spinlock.obin99920 -> 99920 bytes
-rw-r--r--build/src/kernel/syscall.obin47560 -> 61936 bytes
-rw-r--r--build/src/kernel/trap/handler.obin66984 -> 70200 bytes
-rw-r--r--build/user/entry.obin0 -> 3344 bytes
-rw-r--r--build/user/init.obin45880 -> 112536 bytes
-rwxr-xr-xbuild/user/initcodebin1424 -> 2928 bytes
-rw-r--r--build/user/initcode.asm1326
-rwxr-xr-xbuild/user/initcode.outbin14168 -> 22440 bytes
-rw-r--r--build/user/usys.obin5160 -> 5280 bytes
-rw-r--r--docs/dev/dev_device.md23
-rw-r--r--docs/dev/dev_memory.md (renamed from docs/dev/dev_memoty.md)0
-rw-r--r--fs.imgbin0 -> 1048576 bytes
-rw-r--r--include/drivers/plic.h2
-rw-r--r--include/drivers/uart.h26
-rw-r--r--include/drivers/virtio.h102
-rw-r--r--include/kernel/proc.h2
-rw-r--r--include/kernel/syscall.h1
-rw-r--r--include/user/user.h3
-rw-r--r--src/drivers/plic.cc55
-rw-r--r--src/drivers/uart.cc226
-rw-r--r--src/drivers/virtio_dist.cc338
-rw-r--r--src/kernel/main.cc7
-rw-r--r--src/kernel/mm/pmm.cc67
-rw-r--r--src/kernel/mm/slab.cc11
-rw-r--r--src/kernel/mm/vm.cc3
-rw-r--r--src/kernel/proc/proc.cc33
-rw-r--r--src/kernel/syscall.cc53
-rw-r--r--src/kernel/trap/handler.cc13
-rw-r--r--src/user/entry.S12
-rw-r--r--src/user/init.cc191
-rw-r--r--src/user/usys.S3
42 files changed, 1897 insertions, 619 deletions
diff --git a/Makefile b/Makefile
index 7c3de2d..715fff8 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ CXXFLAGS := $(CFLAGS) -fno-exceptions -fno-rtti -fno-use-cxa-atexit
LINKER_SCRIPT := linker.ld
UPROGS_SRC := $(SRC_DIR)/user/init.cc
-UPROGS_OBJ := $(BUILD_DIR)/user/init.o
+UPROGS_OBJ := $(BUILD_DIR)/user/entry.o $(BUILD_DIR)/user/init.o
ULIB_OBJ := $(BUILD_DIR)/user/usys.o
USER_LD := $(SRC_DIR)/user/user.ld
INITCODE_BIN := $(BUILD_DIR)/user/initcode
@@ -24,6 +24,9 @@ OBJS := $(SRCS_S:%.S=$(BUILD_DIR)/%.o) $(SRCS_CXX:%.cc=$(BUILD_DIR)/%.o)
TARGET := $(BUILD_DIR)/kernel.elf
+QEMUOPTS = -drive file=fs.img,if=none,format=raw,id=x0
+QEMUOPTS += -device virtio-blk-device,drive=x0 -global virtio-mmio.force-legacy=false
+
.PHONY: all clean run debug
all: $(TARGET)
@@ -63,15 +66,19 @@ $(BUILD_DIR)/%.o: %.cc
@echo " CXX $<"
@$(CXX) $(CXXFLAGS) -c $< -o $@
-run: $(TARGET)
+fs.img:
+ @echo " IMG Generating fs.img (1MB)"
+ @dd if=/dev/zero of=fs.img bs=1M count=1 2>/dev/null
+
+run: $(TARGET) fs.img
@echo " QEMU Running..."
@qemu-system-riscv64 -machine virt -nographic \
- -kernel $(TARGET) -m 128M
+ -kernel $(TARGET) -m 128M $(QEMUOPTS)
-debug: $(TARGET)
+debug: $(TARGET) fs.img
@echo " QEMU (DEBUG) Waiting for GDB..."
@qemu-system-riscv64 -machine virt -nographic \
- -kernel $(TARGET) -m 128M -s -S
+ -kernel $(TARGET) -m 128M -s -S $(QEMUOPTS)
clean:
- rm -rf $(BUILD_DIR)
+ rm -rf $(BUILD_DIR) fs.img
diff --git a/build/kernel.elf b/build/kernel.elf
index db7f94d..902f32b 100755
--- a/build/kernel.elf
+++ b/build/kernel.elf
Binary files differ
diff --git a/build/src/drivers/plic.o b/build/src/drivers/plic.o
index 846035b..cf2c85d 100644
--- a/build/src/drivers/plic.o
+++ b/build/src/drivers/plic.o
Binary files differ
diff --git a/build/src/drivers/uart.o b/build/src/drivers/uart.o
index 34a0840..e771c9f 100644
--- a/build/src/drivers/uart.o
+++ b/build/src/drivers/uart.o
Binary files differ
diff --git a/build/src/drivers/virtio_dist.o b/build/src/drivers/virtio_dist.o
new file mode 100644
index 0000000..cc608ca
--- /dev/null
+++ b/build/src/drivers/virtio_dist.o
Binary files differ
diff --git a/build/src/kernel/initcode.o b/build/src/kernel/initcode.o
index e29dda3..a1c9bd8 100644
--- a/build/src/kernel/initcode.o
+++ b/build/src/kernel/initcode.o
Binary files differ
diff --git a/build/src/kernel/main.o b/build/src/kernel/main.o
index 54ee210..df27b46 100644
--- a/build/src/kernel/main.o
+++ b/build/src/kernel/main.o
Binary files differ
diff --git a/build/src/kernel/mm/pmm.o b/build/src/kernel/mm/pmm.o
index c77cdc9..db30140 100644
--- a/build/src/kernel/mm/pmm.o
+++ b/build/src/kernel/mm/pmm.o
Binary files differ
diff --git a/build/src/kernel/mm/slab.o b/build/src/kernel/mm/slab.o
index 23305aa..2d97ca1 100644
--- a/build/src/kernel/mm/slab.o
+++ b/build/src/kernel/mm/slab.o
Binary files differ
diff --git a/build/src/kernel/mm/vm.o b/build/src/kernel/mm/vm.o
index 2e3c0de..5d30dcd 100644
--- a/build/src/kernel/mm/vm.o
+++ b/build/src/kernel/mm/vm.o
Binary files differ
diff --git a/build/src/kernel/proc/proc.o b/build/src/kernel/proc/proc.o
index 63506e7..ad606f0 100644
--- a/build/src/kernel/proc/proc.o
+++ b/build/src/kernel/proc/proc.o
Binary files differ
diff --git a/build/src/kernel/spinlock.o b/build/src/kernel/spinlock.o
index f4a24bf..769f5e7 100644
--- a/build/src/kernel/spinlock.o
+++ b/build/src/kernel/spinlock.o
Binary files differ
diff --git a/build/src/kernel/syscall.o b/build/src/kernel/syscall.o
index a3df126..d398c30 100644
--- a/build/src/kernel/syscall.o
+++ b/build/src/kernel/syscall.o
Binary files differ
diff --git a/build/src/kernel/trap/handler.o b/build/src/kernel/trap/handler.o
index 43346a1..9949470 100644
--- a/build/src/kernel/trap/handler.o
+++ b/build/src/kernel/trap/handler.o
Binary files differ
diff --git a/build/user/entry.o b/build/user/entry.o
new file mode 100644
index 0000000..0130c78
--- /dev/null
+++ b/build/user/entry.o
Binary files differ
diff --git a/build/user/init.o b/build/user/init.o
index 13021f2..aea18f2 100644
--- a/build/user/init.o
+++ b/build/user/init.o
Binary files differ
diff --git a/build/user/initcode b/build/user/initcode
index 7d139ad..b6ac9a3 100755
--- a/build/user/initcode
+++ b/build/user/initcode
Binary files differ
diff --git a/build/user/initcode.asm b/build/user/initcode.asm
index c04fbab..1cb4088 100644
--- a/build/user/initcode.asm
+++ b/build/user/initcode.asm
@@ -4,482 +4,1050 @@ build/user/initcode.out: file format elf64-littleriscv
Disassembly of section .text:
-0000000000000000 <_Z6strlenPKc>:
-#include "user/user.h"
+0000000000000000 <_start>:
+.section .text
+.global _start
+
+_start:
+ li a0, 0
+ 0: 4501 li a0,0
+ li a1, 0
+ 2: 4581 li a1,0
+
+ call main
+ 4: 578000ef jal 57c <main>
+
+ call exit
+ 8: 648000ef jal 650 <exit>
+
+ c: a001 j c <_start+0xc>
+
+000000000000000e <_Z6strlenPKc>:
+// =============================================================
int strlen(const char *s)
{
int n = 0;
while (s[n])
- 0: 00054783 lbu a5,0(a0)
- 4: cf81 beqz a5,1c <_Z6strlenPKc+0x1c>
- 6: 0505 addi a0,a0,1
- 8: 87aa mv a5,a0
- a: 0007c703 lbu a4,0(a5)
- e: 86be mv a3,a5
- 10: 0785 addi a5,a5,1
- 12: ff65 bnez a4,a <_Z6strlenPKc+0xa>
+ e: 00054783 lbu a5,0(a0)
+ 12: cf81 beqz a5,2a <_Z6strlenPKc+0x1c>
+ 14: 0505 addi a0,a0,1
+ 16: 87aa mv a5,a0
+ 18: 0007c703 lbu a4,0(a5)
+ 1c: 86be mv a3,a5
+ 1e: 0785 addi a5,a5,1
+ 20: ff65 bnez a4,18 <_Z6strlenPKc+0xa>
n++;
- 14: 40a6853b subw a0,a3,a0
- 18: 2505 addiw a0,a0,1
- 1a: 8082 ret
+ 22: 40a6853b subw a0,a3,a0
+ 26: 2505 addiw a0,a0,1
+ 28: 8082 ret
int n = 0;
- 1c: 4501 li a0,0
+ 2a: 4501 li a0,0
return n;
}
- 1e: 8082 ret
+ 2c: 8082 ret
-0000000000000020 <_Z5printPKc>:
+000000000000002e <_Z5printPKc>:
while (s[n])
- 20: 00054783 lbu a5,0(a0)
+ 2e: 00054783 lbu a5,0(a0)
void print(const char *s)
{
- 24: 85aa mv a1,a0
- while (s[n])
- 26: cf89 beqz a5,40 <_Z5printPKc+0x20>
- 28: 00150693 addi a3,a0,1
- 2c: 87b6 mv a5,a3
- 2e: 0007c703 lbu a4,0(a5)
- 32: 863e mv a2,a5
- 34: 0785 addi a5,a5,1
- 36: ff65 bnez a4,2e <_Z5printPKc+0xe>
+ 32: 85aa mv a1,a0
+ while (s[n])
+ 34: cf89 beqz a5,4e <_Z5printPKc+0x20>
+ 36: 00150693 addi a3,a0,1
+ 3a: 87b6 mv a5,a3
+ 3c: 0007c703 lbu a4,0(a5)
+ 40: 863e mv a2,a5
+ 42: 0785 addi a5,a5,1
+ 44: ff65 bnez a4,3c <_Z5printPKc+0xe>
n++;
- 38: 9e15 subw a2,a2,a3
- 3a: 2605 addiw a2,a2,1
+ 46: 9e15 subw a2,a2,a3
+ 48: 2605 addiw a2,a2,1
write(1, s, strlen(s));
- 3c: 4505 li a0,1
- 3e: a491 j 282 <write>
+ 4a: 4505 li a0,1
+ 4c: a515 j 670 <write>
int n = 0;
- 40: 4601 li a2,0
+ 4e: 4601 li a2,0
write(1, s, strlen(s));
- 42: 4505 li a0,1
- 44: ac3d j 282 <write>
-
-0000000000000046 <_Z9print_inti>:
+ 50: 4505 li a0,1
+ 52: ad39 j 670 <write>
-void print_int(int val)
+0000000000000054 <_Z9print_inti>:
+void print_int(int n)
{
char buf[16];
int i = 0;
- if (val == 0)
- 46: c159 beqz a0,cc <_Z9print_inti+0x86>
+ int neg = 0;
+ if (n == 0)
+ 54: c149 beqz a0,d6 <_Z9print_inti+0x82>
{
- 48: 7139 addi sp,sp,-64
- 4a: f822 sd s0,48(sp)
- 4c: fc06 sd ra,56(sp)
- 4e: f426 sd s1,40(sp)
- 50: f04a sd s2,32(sp)
- 52: 842a mv s0,a0
+ 56: 7179 addi sp,sp,-48
+ 58: f406 sd ra,40(sp)
+ 5a: f022 sd s0,32(sp)
+ 5c: ec26 sd s1,24(sp)
+ int neg = 0;
+ 5e: 4801 li a6,0
{
- print("0");
+ write(1, "0", 1);
return;
}
- if (val < 0)
- 54: 06054163 bltz a0,b6 <_Z9print_inti+0x70>
- 58: 081c addi a5,sp,16
-{
- 5a: 873e mv a4,a5
- print("-");
- val = -val;
+ if (n < 0)
+ 60: 04054c63 bltz a0,b8 <_Z9print_inti+0x64>
+ 64: 840a mv s0,sp
+ {
+ neg = 1;
+ 66: 86a2 mv a3,s0
+ 68: 4701 li a4,0
+ n = -n;
}
- while (val > 0)
+ while (n > 0)
{
- buf[i++] = (val % 10) + '0';
- 5c: 4629 li a2,10
- 5e: 02c466bb remw a3,s0,a2
- 62: 85ba mv a1,a4
- while (val > 0)
- 64: 0705 addi a4,a4,1
- val /= 10;
- 66: 02c4443b divw s0,s0,a2
- buf[i++] = (val % 10) + '0';
- 6a: 0306869b addiw a3,a3,48
- 6e: fed70fa3 sb a3,-1(a4)
- while (val > 0)
- 72: f475 bnez s0,5e <_Z9print_inti+0x18>
- 74: 9d9d subw a1,a1,a5
- 76: 0015871b addiw a4,a1,1
- 7a: fff7059b addiw a1,a4,-1
- 7e: fff78493 addi s1,a5,-1
- 82: 1582 slli a1,a1,0x20
- 84: 94ba add s1,s1,a4
- 86: 9181 srli a1,a1,0x20
- 88: 00e78433 add s0,a5,a4
- 8c: 8c8d sub s1,s1,a1
- 8e: 00f10913 addi s2,sp,15
+ buf[i++] = (n % 10) + '0';
+ 6a: 4629 li a2,10
+ 6c: 02c567bb remw a5,a0,a2
+ while (n > 0)
+ 70: 0685 addi a3,a3,1
+ 72: 85ba mv a1,a4
+ buf[i++] = (n % 10) + '0';
+ 74: 2705 addiw a4,a4,1
+ n /= 10;
+ 76: 02c5453b divw a0,a0,a2
+ buf[i++] = (n % 10) + '0';
+ 7a: 0307879b addiw a5,a5,48
+ 7e: fef68fa3 sb a5,-1(a3)
+ while (n > 0)
+ 82: f56d bnez a0,6c <_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
+ buf[i++] = '-';
while (i > 0)
- {
- char c = buf[--i];
- 92: fff44783 lbu a5,-1(s0)
- write(1, &c, 1);
- 96: 4605 li a2,1
- 98: 85ca mv a1,s2
- 9a: 4505 li a0,1
+ write(1, &buf[--i], 1);
+ 9e: 85a2 mv a1,s0
+ a0: 4605 li a2,1
+ a2: 4505 li a0,1
while (i > 0)
- 9c: 147d addi s0,s0,-1
- char c = buf[--i];
- 9e: 00f107a3 sb a5,15(sp)
- write(1, &c, 1);
- a2: 1e0000ef jal 282 <write>
+ a4: 147d addi s0,s0,-1
+ write(1, &buf[--i], 1);
+ a6: 5ca000ef jal 670 <write>
while (i > 0)
- a6: fe9416e3 bne s0,s1,92 <_Z9print_inti+0x4c>
- }
+ aa: fe849ae3 bne s1,s0,9e <_Z9print_inti+0x4a>
}
- aa: 70e2 ld ra,56(sp)
- ac: 7442 ld s0,48(sp)
- ae: 74a2 ld s1,40(sp)
- b0: 7902 ld s2,32(sp)
- b2: 6121 addi sp,sp,64
- b4: 8082 ret
- write(1, s, strlen(s));
- b6: 4605 li a2,1
- b8: 00000597 auipc a1,0x0
- bc: 26058593 addi a1,a1,608 # 318 <putc+0x16>
- c0: 4505 li a0,1
- c2: 1c0000ef jal 282 <write>
- val = -val;
- c6: 4080043b negw s0,s0
- while (val > 0)
- ca: b779 j 58 <_Z9print_inti+0x12>
- write(1, s, strlen(s));
- cc: 4605 li a2,1
- ce: 00000597 auipc a1,0x0
- d2: 24258593 addi a1,a1,578 # 310 <putc+0xe>
- d6: 4505 li a0,1
- d8: a26d j 282 <write>
-
-00000000000000da <_Z4passv>:
- while (s[n])
- da: 00000697 auipc a3,0x0
- de: 24668693 addi a3,a3,582 # 320 <putc+0x1e>
-
-void pass() { print(" -> [PASS]\n"); }
- e2: 87b6 mv a5,a3
- while (s[n])
- e4: 0017c703 lbu a4,1(a5)
- e8: 863e mv a2,a5
- ea: 0785 addi a5,a5,1
- ec: ff65 bnez a4,e4 <_Z4passv+0xa>
- n++;
- ee: 9e15 subw a2,a2,a3
- write(1, s, strlen(s));
- f0: 2605 addiw a2,a2,1
- f2: 00000597 auipc a1,0x0
- f6: 22e58593 addi a1,a1,558 # 320 <putc+0x1e>
- fa: 4505 li a0,1
- fc: a259 j 282 <write>
+ 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
+ n = -n;
+ b8: 40a0053b negw a0,a0
+ neg = 1;
+ bc: 4805 li a6,1
+ be: b75d j 64 <_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>
+ write(1, "0", 1);
+ d6: 4605 li a2,1
+ d8: 00000597 auipc a1,0x0
+ dc: 62858593 addi a1,a1,1576 # 700 <disk_test+0x8>
+ e0: 4505 li a0,1
+ e2: a379 j 670 <write>
-00000000000000fe <_Z4failv>:
-void fail()
+00000000000000e4 <_Z9print_hexy>:
+
+void print_hex(uint64 n)
{
- fe: 1141 addi sp,sp,-16
- 100: 00000697 auipc a3,0x0
- 104: 23068693 addi a3,a3,560 # 330 <putc+0x2e>
- 108: e406 sd ra,8(sp)
- 10a: 87b6 mv a5,a3
- while (s[n])
- 10c: 0017c703 lbu a4,1(a5)
- 110: 863e mv a2,a5
- 112: 0785 addi a5,a5,1
- 114: ff65 bnez a4,10c <_Z4failv+0xe>
- n++;
- 116: 9e15 subw a2,a2,a3
- write(1, s, strlen(s));
- 118: 2605 addiw a2,a2,1
- 11a: 00000597 auipc a1,0x0
- 11e: 21658593 addi a1,a1,534 # 330 <putc+0x2e>
- 122: 4505 li a0,1
- 124: 15e000ef jal 282 <write>
- print(" -> [FAIL]\n");
- exit(1);
+ char buf[16];
+ char digits[] = "0123456789ABCDEF";
+ e4: 00000797 auipc a5,0x0
+ e8: 62c78793 addi a5,a5,1580 # 710 <disk_test+0x18>
+ ec: 6394 ld a3,0(a5)
+ ee: 6798 ld a4,8(a5)
+ f0: 0107c783 lbu a5,16(a5)
+{
+ f4: 715d addi sp,sp,-80
+ f6: fc26 sd s1,56(sp)
+ write(1, "0x", 2);
+ f8: 4609 li a2,2
+{
+ fa: 84aa mv s1,a0
+ write(1, "0x", 2);
+ fc: 00000597 auipc a1,0x0
+ 100: 60c58593 addi a1,a1,1548 # 708 <disk_test+0x10>
+ 104: 4505 li a0,1
+{
+ 106: 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)
+ write(1, "0x", 2);
+ 110: 560000ef jal 670 <write>
+ 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
+ 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)
+ n /= 16;
+ 12a: 8091 srli s1,s1,0x4
+ 12c: 873e mv a4,a5
+ buf[i++] = digits[n % 16];
+ 12e: 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
+ }
+ while (i > 0)
+ write(1, &buf[--i], 1);
+ 152: 85a2 mv a1,s0
+ 154: 4605 li a2,1
+ 156: 4505 li a0,1
+ while (i > 0)
+ 158: 147d addi s0,s0,-1
+ write(1, &buf[--i], 1);
+ 15a: 516000ef jal 670 <write>
+ while (i > 0)
+ 15e: fe941ae3 bne s0,s1,152 <_Z9print_hexy+0x6e>
+ 162: 6406 ld s0,64(sp)
}
- 128: 60a2 ld ra,8(sp)
- exit(1);
- 12a: 4505 li a0,1
+ 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)
+ write(1, "0", 1);
+ 170: 4605 li a2,1
+ 172: 00000597 auipc a1,0x0
+ 176: 58e58593 addi a1,a1,1422 # 700 <disk_test+0x8>
+ 17a: 4505 li a0,1
}
- 12c: 0141 addi sp,sp,16
- exit(1);
- 12e: aa15 j 262 <exit>
+ 17c: 6161 addi sp,sp,80
+ write(1, "0", 1);
+ 17e: a9cd j 670 <write>
-0000000000000130 <main>:
+0000000000000180 <_Z13test_syscallsv>:
+// =============================================================
+// 系统调用测试套件
+// =============================================================
-int main()
+void test_syscalls()
{
- 130: 1141 addi sp,sp,-16
- print("\n=== Lume OS Full Validation ===\n");
- 132: 00000517 auipc a0,0x0
- 136: 20e50513 addi a0,a0,526 # 340 <putc+0x3e>
-{
- 13a: e406 sd ra,8(sp)
- 13c: e022 sd s0,0(sp)
- print("\n=== Lume OS Full Validation ===\n");
- 13e: ee3ff0ef jal 20 <_Z5printPKc>
-
- print("[TEST 1] Write\n");
- 142: 00000517 auipc a0,0x0
- 146: 22650513 addi a0,a0,550 # 368 <putc+0x66>
- 14a: ed7ff0ef jal 20 <_Z5printPKc>
- print(" System call write is working.");
- 14e: 00000517 auipc a0,0x0
- 152: 22a50513 addi a0,a0,554 # 378 <putc+0x76>
- 156: ecbff0ef jal 20 <_Z5printPKc>
-void pass() { print(" -> [PASS]\n"); }
- 15a: 00000517 auipc a0,0x0
- 15e: 1c650513 addi a0,a0,454 # 320 <putc+0x1e>
- 162: ebfff0ef jal 20 <_Z5printPKc>
- pass();
-
- print("[TEST 2] GetPID\n");
- 166: 00000517 auipc a0,0x0
- 16a: 23250513 addi a0,a0,562 # 398 <putc+0x96>
- 16e: eb3ff0ef jal 20 <_Z5printPKc>
- int parent_pid = getpid();
- 172: 170000ef jal 2e2 <getpid>
- 176: 842a mv s0,a0
- print(" Parent PID: ");
- 178: 00000517 auipc a0,0x0
- 17c: 23850513 addi a0,a0,568 # 3b0 <putc+0xae>
- 180: ea1ff0ef jal 20 <_Z5printPKc>
- print_int(parent_pid);
- 184: 8522 mv a0,s0
- 186: ec1ff0ef jal 46 <_Z9print_inti>
- if (parent_pid > 0)
- 18a: 0c805563 blez s0,254 <main+0x124>
-void pass() { print(" -> [PASS]\n"); }
- 18e: 00000517 auipc a0,0x0
- 192: 19250513 addi a0,a0,402 # 320 <putc+0x1e>
- 196: e8bff0ef jal 20 <_Z5printPKc>
- pass();
+ 180: 1101 addi sp,sp,-32
+ 182: 00000697 auipc a3,0x0
+ 186: 5a668693 addi a3,a3,1446 # 728 <disk_test+0x30>
+ 18a: ec06 sd ra,24(sp)
+ 18c: e822 sd s0,16(sp)
+ 18e: e426 sd s1,8(sp)
+ 190: 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>
+ n++;
+ 19c: 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 <disk_test+0x30>
+ 1a8: 4505 li a0,1
+ 1aa: 4c6000ef jal 670 <write>
+ while (s[n])
+ 1ae: 00000697 auipc a3,0x0
+ 1b2: 5aa68693 addi a3,a3,1450 # 758 <disk_test+0x60>
+ write(1, s, strlen(s));
+ 1b6: 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>
+ n++;
+ 1c2: 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 <disk_test+0x60>
+ 1ce: 4505 li a0,1
+ 1d0: 4a0000ef jal 670 <write>
+ print("\n=== [Test] Starting System Call Check ===\n");
+
+ // 1. 测试 getpid
+ print("[1/4] Checking getpid()... ");
+ int my_pid = getpid();
+ 1d4: 4fc000ef jal 6d0 <getpid>
+ 1d8: 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 <disk_test+0x80>
+ 1e6: 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>
+ n++;
+ 1f2: 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 <disk_test+0x80>
+ 1fe: 4505 li a0,1
+ 200: 470000ef jal 670 <write>
+ {
+ print("PASS (PID=");
+ print_int(my_pid);
+ 204: 8522 mv a0,s0
+ 206: e4fff0ef jal 54 <_Z9print_inti>
+ while (s[n])
+ 20a: 00000697 auipc a3,0x0
+ 20e: 57e68693 addi a3,a3,1406 # 788 <disk_test+0x90>
+ print_int(my_pid);
+ 212: 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>
+ n++;
+ 21e: 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 <disk_test+0x90>
+ 22a: 4505 li a0,1
+ 22c: 444000ef jal 670 <write>
+ while (s[n])
+ 230: 00000697 auipc a3,0x0
+ 234: 57868693 addi a3,a3,1400 # 7a8 <disk_test+0xb0>
+ if (my_pid > 0)
+ 238: 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>
+ n++;
+ 244: 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 <disk_test+0xb0>
+ 250: 4505 li a0,1
+ 252: 41e000ef jal 670 <write>
+ 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 <sbrk>
+ if (p == (char *)-1)
+ 25c: 57fd li a5,-1
+ char *p = sbrk(4096); // 分配 4KB
+ 25e: 84aa mv s1,a0
+ if (p == (char *)-1)
+ 260: 24f50563 beq a0,a5,4aa <_Z13test_syscallsv+0x32a>
+ print("FAIL (sbrk returned error)\n");
+ }
else
- fail();
+ {
+ // 写入测试,确保映射了物理页
+ p[0] = 'A';
+ 264: 04100793 li a5,65
+ 268: 00f50023 sb a5,0(a0) # 1000 <disk_test+0x908>
+ 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 <disk_test+0x100>
+ 278: 05a00713 li a4,90
+ 27c: fee78fa3 sb a4,-1(a5) # fff <disk_test+0x907>
+ 280: 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>
+ n++;
+ 28c: 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 <disk_test+0x100>
+ 298: 4505 li a0,1
+ 29a: 3d6000ef jal 670 <write>
+ 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>
+ while (s[n])
+ 2a4: 00000697 auipc a3,0x0
+ 2a8: 4e468693 addi a3,a3,1252 # 788 <disk_test+0x90>
+ print_hex((uint64)p);
+ 2ac: 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>
+ n++;
+ 2b8: 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 <disk_test+0x90>
+ 2c4: 4505 li a0,1
+ 2c6: 3aa000ef jal 670 <write>
+ while (s[n])
+ 2ca: 00000697 auipc a3,0x0
+ 2ce: 54668693 addi a3,a3,1350 # 810 <disk_test+0x118>
+ print_hex((uint64)p);
+ 2d2: 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>
+ n++;
+ 2de: 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 <disk_test+0x118>
+ 2ea: 4505 li a0,1
+ 2ec: 384000ef jal 670 <write>
+ }
+ }
- print("[TEST 3] Fork, Wait & COW\n");
- 19a: 00000517 auipc a0,0x0
- 19e: 22650513 addi a0,a0,550 # 3c0 <putc+0xbe>
- 1a2: e7fff0ef jal 20 <_Z5printPKc>
- int val = 100;
+ // 3. 测试 fork 和 wait
+ print("[3/4] Checking fork() and wait()...\n");
int pid = fork();
- 1a6: 0b4000ef jal 25a <fork>
+ 2f0: 358000ef jal 648 <fork>
+ 2f4: 84aa mv s1,a0
if (pid < 0)
- 1aa: 04054363 bltz a0,1f0 <main+0xc0>
+ 2f6: 1c054e63 bltz a0,4d2 <_Z13test_syscallsv+0x352>
{
- print(" Fork Failed\n");
- fail();
+ print(" FAIL: fork error\n");
}
-
- if (pid == 0)
- 1ae: e929 bnez a0,200 <main+0xd0>
+ else if (pid == 0)
+ 2fa: e179 bnez a0,3c0 <_Z13test_syscallsv+0x240>
{
- print(" [Child] PID: ");
- 1b0: 00000517 auipc a0,0x0
- 1b4: 24050513 addi a0,a0,576 # 3f0 <putc+0xee>
- 1b8: e69ff0ef jal 20 <_Z5printPKc>
- print_int(getpid());
- 1bc: 126000ef jal 2e2 <getpid>
- 1c0: e87ff0ef jal 46 <_Z9print_inti>
- print("\n");
- 1c4: 00000517 auipc a0,0x0
- 1c8: 23c50513 addi a0,a0,572 # 400 <putc+0xfe>
- 1cc: e55ff0ef jal 20 <_Z5printPKc>
- print(" [Child] Data corruption!\n");
+ // --- 子进程 ---
+ int child_pid = getpid();
+ 2fc: 3d4000ef jal 6d0 <getpid>
+ 300: 84aa mv s1,a0
+ if (child_pid == my_pid)
+ 302: 24a40563 beq s0,a0,54c <_Z13test_syscallsv+0x3cc>
+ while (s[n])
+ 306: 00000697 auipc a3,0x0
+ 30a: 57a68693 addi a3,a3,1402 # 880 <disk_test+0x188>
+ if (child_pid == my_pid)
+ 30e: 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>
+ n++;
+ 31a: 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 <disk_test+0x188>
+ 326: 4505 li a0,1
+ 328: 348000ef jal 670 <write>
+ {
+ print(" FAIL: Child has same PID as parent\n");
exit(1);
}
-
- val = 200;
- print(" [Child] Modified val to 200. Exiting.\n");
- 1d0: 00000517 auipc a0,0x0
- 1d4: 23850513 addi a0,a0,568 # 408 <putc+0x106>
- 1d8: e49ff0ef jal 20 <_Z5printPKc>
+ print(" [Child] I am alive. PID=");
+ print_int(child_pid);
+ 32c: 8526 mv a0,s1
+ 32e: d27ff0ef jal 54 <_Z9print_inti>
+ write(1, s, strlen(s));
+ 332: 4605 li a2,1
+ 334: 00000597 auipc a1,0x0
+ 338: 56c58593 addi a1,a1,1388 # 8a0 <disk_test+0x1a8>
+ 33c: 4505 li a0,1
+ 33e: 332000ef jal 670 <write>
+ while (s[n])
+ 342: 00000697 auipc a3,0x0
+ 346: 56668693 addi a3,a3,1382 # 8a8 <disk_test+0x1b0>
+ write(1, s, strlen(s));
+ 34a: 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>
+ n++;
+ 356: 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 <disk_test+0x1b0>
+ 362: 4505 li a0,1
+ 364: 30c000ef jal 670 <write>
+ print("\n");
+ print(" [Child] Exiting now.\n");
exit(0);
- 1dc: 4501 li a0,0
- 1de: 084000ef jal 262 <exit>
- print_int(val);
- fail();
+ 368: 4501 li a0,0
+ 36a: 2e6000ef jal 650 <exit>
+ while (s[n])
+ 36e: 00000697 auipc a3,0x0
+ 372: 60a68693 addi a3,a3,1546 # 978 <disk_test+0x280>
+ print("PASS (Fork/Wait cycle)\n");
}
- }
+ else
+ {
+ print("FAIL (Wait returned ");
+ print_int(waited_pid);
+ 376: 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>
+ n++;
+ 382: 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 <disk_test+0x280>
+ 38e: 4505 li a0,1
+ 390: 2e0000ef jal 670 <write>
+ while (s[n])
+ 394: 00000697 auipc a3,0x0
+ 398: 61468693 addi a3,a3,1556 # 9a8 <disk_test+0x2b0>
+ write(1, s, strlen(s));
+ 39c: 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>
+
+ // 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)
+ n++;
+ 3ae: 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 <disk_test+0x2b0>
+ 3ba: 4505 li a0,1
+}
+ 3bc: 6105 addi sp,sp,32
+ write(1, s, strlen(s));
+ 3be: ac4d j 670 <write>
+ 3c0: 00000697 auipc a3,0x0
+ 3c4: 50868693 addi a3,a3,1288 # 8c8 <disk_test+0x1d0>
+ else if (pid == 0)
+ 3c8: 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>
+ n++;
+ 3d4: 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 <disk_test+0x1d0>
+ 3e0: 4505 li a0,1
+ 3e2: 28e000ef jal 670 <write>
+ print_int(pid);
+ 3e6: 8526 mv a0,s1
+ 3e8: c6dff0ef jal 54 <_Z9print_inti>
+ write(1, s, strlen(s));
+ 3ec: 4605 li a2,1
+ 3ee: 00000597 auipc a1,0x0
+ 3f2: 4b258593 addi a1,a1,1202 # 8a0 <disk_test+0x1a8>
+ 3f6: 4505 li a0,1
+ 3f8: 278000ef jal 670 <write>
+ while (s[n])
+ 3fc: 00000697 auipc a3,0x0
+ 400: 4f468693 addi a3,a3,1268 # 8f0 <disk_test+0x1f8>
+ write(1, s, strlen(s));
+ 404: 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>
+ n++;
+ 410: 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 <disk_test+0x1f8>
+ 41c: 4505 li a0,1
+ 41e: 252000ef jal 670 <write>
+ int waited_pid = wait(0);
+ 422: 4501 li a0,0
+ 424: 234000ef jal 658 <wait>
+ 428: 00000697 auipc a3,0x0
+ 42c: 53868693 addi a3,a3,1336 # 960 <disk_test+0x268>
+ 430: 842a mv s0,a0
+ if (waited_pid == pid)
+ 432: 87b6 mv a5,a3
+ 434: 0ca48363 beq s1,a0,4fa <_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>
+ n++;
+ 442: 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 <disk_test+0x268>
+ 44e: 4505 li a0,1
+ 450: 220000ef jal 670 <write>
+ print_int(waited_pid);
+ 454: 8522 mv a0,s0
+ 456: bffff0ef jal 54 <_Z9print_inti>
+ while (s[n])
+ 45a: 00000697 auipc a3,0x0
+ 45e: 32e68693 addi a3,a3,814 # 788 <disk_test+0x90>
+ print_int(waited_pid);
+ 462: 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>
+ n++;
+ 46e: 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 <disk_test+0x90>
+ 47a: 4505 li a0,1
+ 47c: 1f4000ef jal 670 <write>
+}
+ 480: b5fd j 36e <_Z13test_syscallsv+0x1ee>
+ 482: 00000697 auipc a3,0x0
+ 486: 30e68693 addi a3,a3,782 # 790 <disk_test+0x98>
+ if (my_pid > 0)
+ 48a: 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>
+ n++;
+ 496: 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 <disk_test+0x98>
+ 4a2: 4505 li a0,1
+ 4a4: 1cc000ef jal 670 <write>
+}
+ 4a8: b361 j 230 <_Z13test_syscallsv+0xb0>
+ 4aa: 00000697 auipc a3,0x0
+ 4ae: 32e68693 addi a3,a3,814 # 7d8 <disk_test+0xe0>
+ if (p == (char *)-1)
+ 4b2: 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>
+ n++;
+ 4be: 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 <disk_test+0xe0>
+ 4ca: 4505 li a0,1
+ 4cc: 1a4000ef jal 670 <write>
+}
+ 4d0: bbed j 2ca <_Z13test_syscallsv+0x14a>
+ 4d2: 00000697 auipc a3,0x0
+ 4d6: 36668693 addi a3,a3,870 # 838 <disk_test+0x140>
+ if (pid < 0)
+ 4da: 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>
+ n++;
+ 4e6: 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 <disk_test+0x140>
+ 4f2: 4505 li a0,1
+ 4f4: 17c000ef jal 670 <write>
+}
+ 4f8: bd9d j 36e <_Z13test_syscallsv+0x1ee>
+ 4fa: 00000617 auipc a2,0x0
+ 4fe: 41e60613 addi a2,a2,1054 # 918 <disk_test+0x220>
+ if (waited_pid == pid)
+ 502: 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>
+ n++;
+ 50e: 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 <disk_test+0x220>
+ 51c: 4505 li a0,1
+ 51e: 152000ef jal 670 <write>
+ while (s[n])
+ 522: 00000617 auipc a2,0x0
+ 526: 42660613 addi a2,a2,1062 # 948 <disk_test+0x250>
+ write(1, s, strlen(s));
+ 52a: 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>
+ n++;
+ 536: 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 <disk_test+0x250>
+ 544: 4505 li a0,1
+ 546: 12a000ef jal 670 <write>
+}
+ 54a: b515 j 36e <_Z13test_syscallsv+0x1ee>
+ 54c: 00000617 auipc a2,0x0
+ 550: 30460613 addi a2,a2,772 # 850 <disk_test+0x158>
+ if (child_pid == my_pid)
+ 554: 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>
+ n++;
+ 560: 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 <disk_test+0x158>
+ 56e: 4505 li a0,1
+ 570: 100000ef jal 670 <write>
+ exit(1);
+ 574: 4505 li a0,1
+ 576: 0da000ef jal 650 <exit>
+ 57a: b371 j 306 <_Z13test_syscallsv+0x186>
+
+000000000000057c <main>:
+// =============================================================
+// 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 <disk_test+0x2d8>
+{
+ 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>
+ print("Commands:\n");
+ 59a: 00000517 auipc a0,0x0
+ 59e: 44e50513 addi a0,a0,1102 # 9e8 <disk_test+0x2f0>
+ 5a2: a8dff0ef 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 <disk_test+0x300>
+ 5ae: a81ff0ef jal 2e <_Z5printPKc>
+ print(" t: Run Disk Driver Test (VirtIO)\n");
+ 5b2: 00000517 auipc a0,0x0
+ 5b6: 47650513 addi a0,a0,1142 # a28 <disk_test+0x330>
+ 5ba: 00000b17 auipc s6,0x0
+ 5be: 49eb0b13 addi s6,s6,1182 # a58 <disk_test+0x360>
+ n++;
+ 5c2: 4a85 li s5,1
+ print(" t: Run Disk Driver Test (VirtIO)\n");
+ 5c4: a6bff0ef jal 2e <_Z5printPKc>
+ 5c8: 848a mv s1,sp
- print("\n=== All Tests Passed ===\n");
- 1e2: 00000517 auipc a0,0x0
- 1e6: 2ce50513 addi a0,a0,718 # 4b0 <putc+0x1ae>
- 1ea: e37ff0ef jal 20 <_Z5printPKc>
while (1)
- 1ee: a001 j 1ee <main+0xbe>
- print(" Fork Failed\n");
- 1f0: 00000517 auipc a0,0x0
- 1f4: 1f050513 addi a0,a0,496 # 3e0 <putc+0xde>
- 1f8: e29ff0ef jal 20 <_Z5printPKc>
- fail();
- 1fc: f03ff0ef jal fe <_Z4failv>
- print(" [Parent] Waiting for child...\n");
- 200: 00000517 auipc a0,0x0
- 204: 23850513 addi a0,a0,568 # 438 <putc+0x136>
- 208: e19ff0ef jal 20 <_Z5printPKc>
- int child_pid = wait(0);
- 20c: 4501 li a0,0
- 20e: 05c000ef jal 26a <wait>
- 212: 842a mv s0,a0
- print(" [Parent] Child ");
- 214: 00000517 auipc a0,0x0
- 218: 24c50513 addi a0,a0,588 # 460 <putc+0x15e>
- 21c: e05ff0ef jal 20 <_Z5printPKc>
- print_int(child_pid);
- 220: 8522 mv a0,s0
- 222: e25ff0ef jal 46 <_Z9print_inti>
- print(" exited.\n");
- 226: 00000517 auipc a0,0x0
- 22a: 25250513 addi a0,a0,594 # 478 <putc+0x176>
- 22e: df3ff0ef jal 20 <_Z5printPKc>
- print(" [Parent] Check val (Expect 100): ");
- 232: 00000517 auipc a0,0x0
- 236: 25650513 addi a0,a0,598 # 488 <putc+0x186>
- 23a: de7ff0ef jal 20 <_Z5printPKc>
- print_int(val);
- 23e: 06400513 li a0,100
- 242: e05ff0ef jal 46 <_Z9print_inti>
-void pass() { print(" -> [PASS]\n"); }
- 246: 00000517 auipc a0,0x0
- 24a: 0da50513 addi a0,a0,218 # 320 <putc+0x1e>
- 24e: dd3ff0ef jal 20 <_Z5printPKc>
- 252: bf41 j 1e2 <main+0xb2>
- fail();
- 254: eabff0ef jal fe <_Z4failv>
- 258: b789 j 19a <main+0x6a>
-
-000000000000025a <fork>:
+ {
+ char buf[16];
+ write(1, "$ ", 2);
+ 5ca: 00000417 auipc s0,0x0
+ 5ce: 48640413 addi s0,s0,1158 # a50 <disk_test+0x358>
+
+ int n = read(0, buf, sizeof(buf));
+ if (n <= 0)
+ continue;
+
+ if (buf[0] == 's')
+ 5d2: 07300913 li s2,115
+ {
+ test_syscalls();
+ }
+ else if (buf[0] == 't')
+ 5d6: 07400993 li s3,116
+ disk_test();
+ exit(0);
+ }
+ wait(0);
+ }
+ else if (buf[0] != '\n')
+ 5da: 4a29 li s4,10
+ n++;
+ 5dc: 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 <write>
+ 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 <read>
+ if (n <= 0)
+ 5f4: fea056e3 blez a0,5e0 <main+0x64>
+ if (buf[0] == 's')
+ 5f8: 00014783 lbu a5,0(sp)
+ 5fc: 03278663 beq a5,s2,628 <main+0xac>
+ else if (buf[0] == 't')
+ 600: 03378763 beq a5,s3,62e <main+0xb2>
+ else if (buf[0] != '\n')
+ 604: fd478ee3 beq a5,s4,5e0 <main+0x64>
+ 608: 00000797 auipc a5,0x0
+ 60c: 45078793 addi a5,a5,1104 # a58 <disk_test+0x360>
+ 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 <main+0x94>
+ 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 <write>
+}
+ 626: bf6d j 5e0 <main+0x64>
+ test_syscalls();
+ 628: b59ff0ef jal 180 <_Z13test_syscallsv>
+ 62c: bf55 j 5e0 <main+0x64>
+ if (fork() == 0)
+ 62e: 01a000ef jal 648 <fork>
+ 632: c509 beqz a0,63c <main+0xc0>
+ wait(0);
+ 634: 4501 li a0,0
+ 636: 022000ef jal 658 <wait>
+ 63a: b75d j 5e0 <main+0x64>
+ disk_test();
+ 63c: 0bc000ef jal 6f8 <disk_test>
+ exit(0);
+ 640: 4501 li a0,0
+ 642: 00e000ef jal 650 <exit>
+ 646: b7fd j 634 <main+0xb8>
+
+0000000000000648 <fork>:
name: \
li a7, SYS_ ## name; \
ecall; \
ret
SYSCALL(fork)
- 25a: 4889 li a7,2
- 25c: 00000073 ecall
- 260: 8082 ret
+ 648: 4889 li a7,2
+ 64a: 00000073 ecall
+ 64e: 8082 ret
-0000000000000262 <exit>:
+0000000000000650 <exit>:
SYSCALL(exit)
- 262: 488d li a7,3
- 264: 00000073 ecall
- 268: 8082 ret
+ 650: 488d li a7,3
+ 652: 00000073 ecall
+ 656: 8082 ret
-000000000000026a <wait>:
+0000000000000658 <wait>:
SYSCALL(wait)
- 26a: 4891 li a7,4
- 26c: 00000073 ecall
- 270: 8082 ret
+ 658: 4891 li a7,4
+ 65a: 00000073 ecall
+ 65e: 8082 ret
-0000000000000272 <pipe>:
+0000000000000660 <pipe>:
SYSCALL(pipe)
- 272: 4895 li a7,5
- 274: 00000073 ecall
- 278: 8082 ret
+ 660: 4895 li a7,5
+ 662: 00000073 ecall
+ 666: 8082 ret
-000000000000027a <read>:
+0000000000000668 <read>:
SYSCALL(read)
- 27a: 4899 li a7,6
- 27c: 00000073 ecall
- 280: 8082 ret
+ 668: 4899 li a7,6
+ 66a: 00000073 ecall
+ 66e: 8082 ret
-0000000000000282 <write>:
+0000000000000670 <write>:
SYSCALL(write)
- 282: 48c5 li a7,17
- 284: 00000073 ecall
- 288: 8082 ret
+ 670: 48c5 li a7,17
+ 672: 00000073 ecall
+ 676: 8082 ret
-000000000000028a <close>:
+0000000000000678 <close>:
SYSCALL(close)
- 28a: 48d9 li a7,22
- 28c: 00000073 ecall
- 290: 8082 ret
+ 678: 48d9 li a7,22
+ 67a: 00000073 ecall
+ 67e: 8082 ret
-0000000000000292 <kill>:
+0000000000000680 <kill>:
SYSCALL(kill)
- 292: 489d li a7,7
- 294: 00000073 ecall
- 298: 8082 ret
+ 680: 489d li a7,7
+ 682: 00000073 ecall
+ 686: 8082 ret
-000000000000029a <exec>:
+0000000000000688 <exec>:
SYSCALL(exec)
- 29a: 48a1 li a7,8
- 29c: 00000073 ecall
- 2a0: 8082 ret
+ 688: 48a1 li a7,8
+ 68a: 00000073 ecall
+ 68e: 8082 ret
-00000000000002a2 <open>:
+0000000000000690 <open>:
SYSCALL(open)
- 2a2: 48c1 li a7,16
- 2a4: 00000073 ecall
- 2a8: 8082 ret
+ 690: 48c1 li a7,16
+ 692: 00000073 ecall
+ 696: 8082 ret
-00000000000002aa <mknod>:
+0000000000000698 <mknod>:
SYSCALL(mknod)
- 2aa: 48c9 li a7,18
- 2ac: 00000073 ecall
- 2b0: 8082 ret
+ 698: 48c9 li a7,18
+ 69a: 00000073 ecall
+ 69e: 8082 ret
-00000000000002b2 <unlink>:
+00000000000006a0 <unlink>:
SYSCALL(unlink)
- 2b2: 48cd li a7,19
- 2b4: 00000073 ecall
- 2b8: 8082 ret
+ 6a0: 48cd li a7,19
+ 6a2: 00000073 ecall
+ 6a6: 8082 ret
-00000000000002ba <fstat>:
+00000000000006a8 <fstat>:
SYSCALL(fstat)
- 2ba: 48a5 li a7,9
- 2bc: 00000073 ecall
- 2c0: 8082 ret
+ 6a8: 48a5 li a7,9
+ 6aa: 00000073 ecall
+ 6ae: 8082 ret
-00000000000002c2 <link>:
+00000000000006b0 <link>:
SYSCALL(link)
- 2c2: 48d1 li a7,20
- 2c4: 00000073 ecall
- 2c8: 8082 ret
+ 6b0: 48d1 li a7,20
+ 6b2: 00000073 ecall
+ 6b6: 8082 ret
-00000000000002ca <mkdir>:
+00000000000006b8 <mkdir>:
SYSCALL(mkdir)
- 2ca: 48d5 li a7,21
- 2cc: 00000073 ecall
- 2d0: 8082 ret
+ 6b8: 48d5 li a7,21
+ 6ba: 00000073 ecall
+ 6be: 8082 ret
-00000000000002d2 <chdir>:
+00000000000006c0 <chdir>:
SYSCALL(chdir)
- 2d2: 48a9 li a7,10
- 2d4: 00000073 ecall
- 2d8: 8082 ret
+ 6c0: 48a9 li a7,10
+ 6c2: 00000073 ecall
+ 6c6: 8082 ret
-00000000000002da <dup>:
+00000000000006c8 <dup>:
SYSCALL(dup)
- 2da: 48ad li a7,11
- 2dc: 00000073 ecall
- 2e0: 8082 ret
+ 6c8: 48ad li a7,11
+ 6ca: 00000073 ecall
+ 6ce: 8082 ret
-00000000000002e2 <getpid>:
+00000000000006d0 <getpid>:
SYSCALL(getpid)
- 2e2: 48b1 li a7,12
- 2e4: 00000073 ecall
- 2e8: 8082 ret
+ 6d0: 48b1 li a7,12
+ 6d2: 00000073 ecall
+ 6d6: 8082 ret
-00000000000002ea <sbrk>:
+00000000000006d8 <sbrk>:
SYSCALL(sbrk)
- 2ea: 48b5 li a7,13
- 2ec: 00000073 ecall
- 2f0: 8082 ret
+ 6d8: 48b5 li a7,13
+ 6da: 00000073 ecall
+ 6de: 8082 ret
-00000000000002f2 <sleep>:
+00000000000006e0 <sleep>:
SYSCALL(sleep)
- 2f2: 48b9 li a7,14
- 2f4: 00000073 ecall
- 2f8: 8082 ret
+ 6e0: 48b9 li a7,14
+ 6e2: 00000073 ecall
+ 6e6: 8082 ret
-00000000000002fa <uptime>:
+00000000000006e8 <uptime>:
SYSCALL(uptime)
- 2fa: 48bd li a7,15
- 2fc: 00000073 ecall
- 300: 8082 ret
-
-0000000000000302 <putc>:
- 302: 4885 li a7,1
- 304: 00000073 ecall
- 308: 8082 ret
+ 6e8: 48bd li a7,15
+ 6ea: 00000073 ecall
+ 6ee: 8082 ret
+
+00000000000006f0 <putc>:
+SYSCALL(putc)
+ 6f0: 4885 li a7,1
+ 6f2: 00000073 ecall
+ 6f6: 8082 ret
+
+00000000000006f8 <disk_test>:
+ 6f8: 48dd li a7,23
+ 6fa: 00000073 ecall
+ 6fe: 8082 ret
diff --git a/build/user/initcode.out b/build/user/initcode.out
index af31998..c8d8b7f 100755
--- a/build/user/initcode.out
+++ b/build/user/initcode.out
Binary files differ
diff --git a/build/user/usys.o b/build/user/usys.o
index 9ac9e11..537c6db 100644
--- a/build/user/usys.o
+++ b/build/user/usys.o
Binary files differ
diff --git a/docs/dev/dev_device.md b/docs/dev/dev_device.md
new file mode 100644
index 0000000..1eb6462
--- /dev/null
+++ b/docs/dev/dev_device.md
@@ -0,0 +1,23 @@
+# Dev log
+## **3.Device Model & HAL:**
+* Interrupt Controller: PLIC:
+
+ * Implement the PLIC (Platform-Level Interrupt Controller) driver.
+
+ * Set the PLIC priority threshold and enable bits during the start() phase.
+
+ * Dispatch Cause 9 (External Interrupt) in kerneltrap/usertrap.
+
+* Character Device: Interrupt-Driven Console:
+
+ * Implement a Ring Buffer. uart_putc returns immediately after writing to the buffer.
+
+ * UART transmit interrupt: triggers when the serial port is idle, the ISR takes data from the Ring Buffer and writes it to the register.
+
+ * UART receive interrupt: triggers when a key is pressed, the ISR reads the character and wakes up the process waiting to read.
+
+* Block Device: VirtIO-Blk:
+
+ * Implement a block device driver for the PCI or MMIO transport layer according to the VirtIO 2.0 standard.
+
+ * DMA: Use the Buddy System to allocate contiguous memory as the descriptor table for the Virtqueue. \ No newline at end of file
diff --git a/docs/dev/dev_memoty.md b/docs/dev/dev_memory.md
index f05e336..f05e336 100644
--- a/docs/dev/dev_memoty.md
+++ b/docs/dev/dev_memory.md
diff --git a/fs.img b/fs.img
new file mode 100644
index 0000000..fada73c
--- /dev/null
+++ b/fs.img
Binary files differ
diff --git a/include/drivers/plic.h b/include/drivers/plic.h
index 8e8d986..11e8c8a 100644
--- a/include/drivers/plic.h
+++ b/include/drivers/plic.h
@@ -1,7 +1,7 @@
#pragma once
#include "common/types.h"
-namespace PILC
+namespace PLIC
{
// Global initialization (executed only once by hart 0)
void init();
diff --git a/include/drivers/uart.h b/include/drivers/uart.h
index cb84bde..26c2394 100644
--- a/include/drivers/uart.h
+++ b/include/drivers/uart.h
@@ -1,11 +1,35 @@
#pragma once
#include "common/types.h"
+#define UART0 0x10000000L
+#define RHR 0 // Receive Holding Register (read mode)
+#define THR 0 // Transmit Holding Register (write mode)
+#define IER 1 // Interrupt Enable Register
+#define FCR 2 // FIFO Control Register
+#define ISR 2 // Interrupt Status Register
+#define LCR 3 // Line Control Register
+#define LSR 5 // Line Status Register
+
+#define LSR_RX_READY 0x01 // input is waiting to be read from RHR
+#define LSR_TX_IDLE 0x20 // THR can accept another character to send
+
+#define UART_RX_BUF_SIZE 128
+
+// ANSI Escape Codes for Modern Terminal Colors
+#define ANSI_RESET "\033[0m"
+#define ANSI_RED "\033[31m"
+#define ANSI_GREEN "\033[32m"
+#define ANSI_YELLOW "\033[33m"
+#define ANSI_BLUE "\033[34m"
+#define ANSI_CLEAR "\033[2J\033[1;1H"
+
namespace Drivers
{
void uart_init();
- void uart_putc(char c);
+ void uart_intr();
+ int console_read(uint64 target, int len);
+ void uart_putc(char c);
void uart_puts(const char *s);
void uart_put_int(int value);
void print_hex(uint64 value);
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
diff --git a/include/kernel/proc.h b/include/kernel/proc.h
index d63ccf7..cbf2902 100644
--- a/include/kernel/proc.h
+++ b/include/kernel/proc.h
@@ -17,6 +17,8 @@ namespace ProcManager
void sleep(void *chan, Spinlock *lk);
void wakeup(void *chan);
+
+ int growproc(int n);
}
void forkret();
diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h
index 222f2f4..1fcd1ff 100644
--- a/include/kernel/syscall.h
+++ b/include/kernel/syscall.h
@@ -22,6 +22,7 @@
#define SYS_link 20
#define SYS_mkdir 21
#define SYS_close 22
+#define SYS_disk_test 23
#ifndef __ASSEMBLER__
void syscall();
diff --git a/include/user/user.h b/include/user/user.h
index 7ab4923..7624a21 100644
--- a/include/user/user.h
+++ b/include/user/user.h
@@ -24,6 +24,7 @@ extern "C" {
int sleep(int ticks);
int uptime();
-
+ // Debug
void putc(char c);
+ int disk_test();
} \ No newline at end of file
diff --git a/src/drivers/plic.cc b/src/drivers/plic.cc
index a13537c..a759597 100644
--- a/src/drivers/plic.cc
+++ b/src/drivers/plic.cc
@@ -1,60 +1,59 @@
#include "common/types.h"
#include "kernel/riscv.h"
#include "drivers/plic.h"
+#include "drivers/uart.h"
-// QEMU Virt PLIC address constants
+// Base Constants
constexpr uint64 PLIC_BASE = 0x0c000000L;
constexpr uint64 PLIC_PRIORITY = PLIC_BASE + 0x0;
constexpr uint64 PLIC_PENDING = PLIC_BASE + 0x1000;
-// S-Mode interrupt enable register: each Hart occupies 0x100 bytes
-// Context 1 is Hart 0 S-Mode, Context 3 is Hart 1 S-Mode...
-inline uint64 PLIC_SENABLE(int hart)
-{
- return PLIC_BASE + 0x2080 + static_cast<uint64>(hart) * 0x100;
-}
+// Helper Macros to calculate addresses
+#define PLIC_SENABLE_ADDR(hart) (PLIC_BASE + 0x2080 + (hart) * 0x100)
+#define PLIC_STHRESHOLD_ADDR(hart) (PLIC_BASE + 0x201000 + (hart) * 0x2000)
+#define PLIC_SCLAIM_ADDR(hart) (PLIC_BASE + 0x201004 + (hart) * 0x2000)
-// S-Mode priority threshold and claim register: 0x2000 bytes per Hart
-inline uint64 PLIC_STHRESHOLD(int hart)
+// Helper for Volatile Access
+static inline volatile uint32 *REG32(uint64 addr)
{
- return PLIC_BASE + 0x201000 + static_cast<uint64>(hart) * 0x2000;
+ return reinterpret_cast<volatile uint32 *>(addr);
}
-inline uint64 PLIC_SCLAIM(int hart)
-{
- return PLIC_BASE + 0x201004 + static_cast<uint64>(hart) * 0x2000;
-}
-
-namespace PILC
+namespace PLIC
{
void init()
{
- *reinterpret_cast<uint32 *>(PLIC_PRIORITY + 10 * 4) = 1; // UART
- *reinterpret_cast<uint32 *>(PLIC_PRIORITY + 1 * 4) = 1; // VirtIO 0
+ // Set Priority for UART (IRQ 10) and VirtIO (IRQ 1)
+ // Must use volatile write
+ *REG32(PLIC_PRIORITY + 10 * 4) = 1;
+ for (int i = 1; i <= 8; i++)
+ {
+ *REG32(PLIC_PRIORITY + i * 4) = 1;
+ }
}
void inithart()
{
- int hart = static_cast<int>(r_tp()); // 获取当前 hartid
+ int hart = static_cast<int>(r_tp());
+
+ // Enable UART(10) and VirtIO(1) for this Hart (S-Mode)
+ *REG32(PLIC_SENABLE_ADDR(hart)) = (1 << 10) | 0x1FE;
- // Enable UART and VirtIO interrupts for the current Hart's S-Mode
- // Set bit 10 and bit 1 in the register bitmap
- *reinterpret_cast<uint32 *>(PLIC_SENABLE(hart)) = (1 << 10) | (1 << 1);
+ // Set Priority Threshold to 0 (Allow all)
+ *REG32(PLIC_STHRESHOLD_ADDR(hart)) = 0;
- // Set the current Hart's S-Mode priority threshold to 0
- // Only interrupts with a priority higher than this threshold will be delivered
- *reinterpret_cast<uint32 *>(PLIC_STHRESHOLD(hart)) = 0;
+ Drivers::uart_puts("[PLIC] Hart Init Done.\n");
}
int claim()
{
int hart = static_cast<int>(r_tp());
- return *reinterpret_cast<uint32 *>(PLIC_SCLAIM(hart));
+ return *REG32(PLIC_SCLAIM_ADDR(hart));
}
void complete(int irq)
{
int hart = static_cast<int>(r_tp());
- *reinterpret_cast<uint32 *>(PLIC_SCLAIM(hart)) = static_cast<uint32>(irq);
+ *REG32(PLIC_SCLAIM_ADDR(hart)) = static_cast<uint32>(irq);
}
-} // namespace PILC
+} \ No newline at end of file
diff --git a/src/drivers/uart.cc b/src/drivers/uart.cc
index fe051f8..9475d49 100644
--- a/src/drivers/uart.cc
+++ b/src/drivers/uart.cc
@@ -1,102 +1,206 @@
#include "drivers/uart.h"
-#include "common/types.h"
-#include "kernel/config.h"
-
-// #define UART0_BASE 0x10000000L
-
-#define UART_RBR 0x00 // Receiver Buffer Register (Read)
-#define UART_THR 0x00 // Transmitter Holding Register (Write)
-#define UART_IER 0x01 // Interrupt Enable Register
-#define UART_FCR 0x02 // FIFO Control Register
-#define UART_LCR 0x03 // Line Control Register
-#define UART_LSR 0x05 // Line Status Register
-
-#define UART_LSR_RX_READY 0x01
-#define UART_LSR_TX_EMPTY 0x20
+#include "kernel/riscv.h"
+#include "kernel/spinlock.h"
+#include "kernel/proc.h"
+#include "kernel/mm.h"
+#include "lib/string.h"
namespace Drivers
{
-
- inline volatile uint8_t &reg(uint32_t offset)
+ // Circular buffer structure
+ struct
{
- return *reinterpret_cast<volatile uint8_t *>(g_uart_base + offset);
- }
+ Spinlock lock;
+ char buf[UART_RX_BUF_SIZE];
+ uint32 r; // read index
+ uint32 w; // write index
+ } uart_rx;
+
+ Spinlock uart_tx_lock;
void uart_init()
{
- if (g_uart_base == 0)
- return;
+ uart_rx.lock.init("uart_rx");
+ uart_tx_lock.init("uart_tx");
+ uart_rx.r = 0;
+ uart_rx.w = 0;
- reg(UART_IER) = 0x00; // Disable interrupt
- reg(UART_LCR) = 0x80; // Set baud rate (LATCH bit)
- reg(0x00) = 0x03; // LSB
- reg(0x01) = 0x00; // MSB
- reg(UART_LCR) = 0x03; // 8 bits, no parity, one stop bit
- reg(UART_FCR) = 0x07; // Enable FIFO, clear TX/RX queues
- }
+ // Disable interrupts and configure
+ *(volatile uint8 *)(UART0 + IER) = 0x00;
- void uart_putc(char c)
- {
- if (g_uart_base == 0)
- return;
+ // Enter baud rate setting mode (LCR_DLAB) = 0x80;
+ *(volatile uint8 *)(UART0 + LCR) = 0x80;
+ *(volatile uint8 *)(UART0 + 0) = 0x03; // DLL: 38.4K baud
+ *(volatile uint8 *)(UART0 + 1) = 0x00; // DLM
- if (c == '\n')
- {
- uart_putc('\r');
- }
+ // Exit baud rate setting, set 8-bit word length, no parity
+ *(volatile uint8 *)(UART0 + LCR) = 0x03;
- // Waiting for the send buffer to be empty
- while ((reg(UART_LSR) & UART_LSR_TX_EMPTY) == 0)
- ;
+ // Reset and enable FIFO
+ *(volatile uint8 *)(UART0 + FCR) = 0x07;
- reg(UART_THR) = c;
+ // Enable Receive Data Available Interrupt
+ *(volatile uint8 *)(UART0 + IER) = 0x01;
}
+ void uart_putc(char c)
+ {
+ uart_tx_lock.acquire();
+ while ((*(volatile uint8 *)(UART0 + LSR) & LSR_TX_IDLE) == 0)
+ ;
+ *(volatile uint8 *)(UART0 + THR) = c;
+ uart_tx_lock.release();
+ }
void uart_puts(const char *s)
{
while (*s)
- {
uart_putc(*s++);
- }
}
- void uart_put_int(int value)
+ void uart_put_int(int val)
{
- if (value == 0)
+ char buf[16];
+ int i = 0;
+ if (val == 0)
{
- uart_putc('0');
+ uart_puts("0");
return;
}
-
- if (value < 0)
+ if (val < 0)
{
- uart_putc('-');
- value = -value;
+ uart_puts("-");
+ val = -val;
}
-
- char buffer[16];
- int i = 0;
- while (value > 0)
+ while (val > 0)
{
- buffer[i++] = (value % 10) + '0';
- value /= 10;
+ buf[i++] = (val % 10) + '0';
+ val /= 10;
}
-
while (i > 0)
{
- uart_putc(buffer[--i]);
+ uart_putc(buf[--i]);
}
}
- void print_hex(uint64 value)
+ void print_hex(uint64 val)
{
+ char hex[] = "0123456789ABCDEF";
uart_puts("0x");
- char hex[] = "0123456789abcdef";
- for (int i = 15; i >= 0; i--)
+ for (int i = 60; i >= 0; i -= 4)
{
- int nibble = (value >> (i * 4)) & 0xF;
- uart_putc(hex[nibble]);
+ uart_putc(hex[(val >> i) & 0xF]);
}
}
+
+ void uart_intr()
+ {
+ uart_rx.lock.acquire();
+
+ while (1)
+ {
+ if ((*(volatile uint8 *)(UART0 + LSR) & LSR_RX_READY) == 0)
+ break;
+
+ char c = *(volatile uint8 *)(UART0 + RHR);
+
+ uart_rx.buf[uart_rx.w % UART_RX_BUF_SIZE] = c;
+ uart_rx.w++;
+
+ ProcManager::wakeup(&uart_rx);
+ }
+
+ uart_rx.lock.release();
+ }
+
+ // Modern console read: Line buffering + Editing Keys + Echo
+ int console_read(uint64 target, int len)
+ {
+ struct Proc *p = myproc();
+ int target_idx = 0;
+
+ uart_rx.lock.acquire();
+
+ while (target_idx < len)
+ {
+ while (uart_rx.r == uart_rx.w)
+ {
+ if (p->xstate != 0)
+ {
+ uart_rx.lock.release();
+ return -1;
+ }
+ ProcManager::sleep(&uart_rx, &uart_rx.lock);
+ }
+
+ char c = uart_rx.buf[uart_rx.r % UART_RX_BUF_SIZE];
+ uart_rx.r++;
+
+ uart_rx.lock.release();
+
+ // 1. Handle Backspace (127 or \b)
+ if (c == 127 || c == '\b')
+ {
+ if (target_idx > 0)
+ {
+ // Erase character from screen: Backspace, Space, Backspace
+ uart_putc('\b');
+ uart_putc(' ');
+ uart_putc('\b');
+ target_idx--;
+ }
+ uart_rx.lock.acquire();
+ continue;
+ }
+
+ // 2. Handle Ctrl+U (Kill Line)
+ if (c == 0x15)
+ {
+ while (target_idx > 0)
+ {
+ uart_putc('\b');
+ uart_putc(' ');
+ uart_putc('\b');
+ target_idx--;
+ }
+ uart_rx.lock.acquire();
+ continue;
+ }
+
+ // 3. Handle Ctrl+L (Clear Screen)
+ if (c == 0x0C)
+ {
+ uart_puts(ANSI_CLEAR);
+ uart_puts("$ ");
+ uart_rx.lock.acquire();
+ continue;
+ }
+
+ // 4. Handle Return (CR -> LF)
+ if (c == '\r')
+ {
+ c = '\n';
+ }
+
+ // Echo back to user
+ uart_putc(c);
+
+ if (VM::copyout(p->pagetable, target + target_idx, &c, 1) < 0)
+ {
+ return -1;
+ }
+
+ target_idx++;
+
+ if (c == '\n')
+ {
+ return target_idx;
+ }
+
+ uart_rx.lock.acquire();
+ }
+
+ uart_rx.lock.release();
+ return target_idx;
+ }
} \ No newline at end of file
diff --git a/src/drivers/virtio_dist.cc b/src/drivers/virtio_dist.cc
new file mode 100644
index 0000000..99d100f
--- /dev/null
+++ b/src/drivers/virtio_dist.cc
@@ -0,0 +1,338 @@
+#include "drivers/virtio.h"
+#include "kernel/riscv.h"
+#include "kernel/pmm.h"
+#include "kernel/spinlock.h"
+#include "lib/string.h"
+#include "drivers/uart.h"
+#include "kernel/proc.h"
+
+static uint64 virtio_base = 0x10001000;
+
+// VirtIO Block Device Config Structure
+struct virtio_blk_config
+{
+ uint64 capacity;
+ uint32 size_max;
+ uint32 seg_max;
+ struct virtio_blk_geometry
+ {
+ uint16 cylinders;
+ uint8 heads;
+ uint8 sectors;
+ } geometry;
+ uint32 blk_size;
+ uint8 physical_block_exp;
+ uint8 alignment_offset;
+ uint16 min_io_size;
+ uint32 opt_io_size;
+} __attribute__((packed));
+
+static inline volatile uint32 *REG(uint32 offset)
+{
+ return reinterpret_cast<volatile uint32 *>(virtio_base + offset);
+}
+
+namespace VirtIO
+{
+ struct Disk
+ {
+ struct VRingDesc *desc;
+ struct VRingAvail *avail;
+ struct VRingUsed *used;
+
+ int free_head;
+ int num_free;
+ int free_chain[NUM_DESCS];
+
+ uint16 used_idx;
+
+ struct TraceInfo
+ {
+ int busy;
+ int status;
+ } info[NUM_DESCS];
+
+ struct BlockRequest reqs[NUM_DESCS];
+ uint8 req_status[NUM_DESCS];
+
+ Spinlock lock;
+ } disk;
+
+ void init()
+ {
+ disk.lock.init("virtio_disk");
+
+ // 1. Probing for VirtIO-MMIO device
+ bool found = false;
+ // Probe common VirtIO addresses in QEMU virt machine
+ for (uint64 addr = 0x10001000; addr < 0x10009000; addr += 0x1000)
+ {
+ volatile uint32 *magic = (volatile uint32 *)(addr + VIRTIO_MMIO_MAGIC_VALUE);
+ volatile uint32 *dev_id = (volatile uint32 *)(addr + VIRTIO_MMIO_DEVICE_ID);
+
+ if (*magic == 0x74726976 && *dev_id == 2) // ID 2 = Block Device
+ {
+ virtio_base = addr;
+ found = true;
+ Drivers::uart_puts(ANSI_GREEN "[VirtIO] Found Block Device @ ");
+ Drivers::print_hex(addr);
+ Drivers::uart_puts(ANSI_RESET "\n");
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ Drivers::uart_puts(ANSI_RED "[VirtIO] Fatal - No Block Device found.\n" ANSI_RESET);
+ return;
+ }
+
+ // 2. Check Device Version (We want Modern v2)
+ if (*REG(VIRTIO_MMIO_VERSION) != 2)
+ {
+ Drivers::uart_puts(ANSI_YELLOW "[VirtIO] Warning: Legacy device detected (expected v2).\n" ANSI_RESET);
+ }
+
+ // 3. Reset Device
+ *REG(VIRTIO_MMIO_STATUS) = 0;
+
+ // 4. Set ACKNOWLEDGE & DRIVER status
+ uint32 status = *REG(VIRTIO_MMIO_STATUS);
+ status |= VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER;
+ *REG(VIRTIO_MMIO_STATUS) = status;
+
+ // 5. Feature Negotiation
+ *REG(VIRTIO_MMIO_DEVICE_FEATURES_SEL) = 0;
+ uint32 device_features_lo = *REG(VIRTIO_MMIO_DEVICE_FEATURES);
+ (void)device_features_lo;
+
+ *REG(VIRTIO_MMIO_DEVICE_FEATURES_SEL) = 1;
+ uint32 device_features_hi = *REG(VIRTIO_MMIO_DEVICE_FEATURES);
+ (void)device_features_hi;
+
+ *REG(VIRTIO_MMIO_DRIVER_FEATURES_SEL) = 0;
+ *REG(VIRTIO_MMIO_DRIVER_FEATURES) = 0;
+
+ *REG(VIRTIO_MMIO_DRIVER_FEATURES_SEL) = 1;
+ // VIRTIO_F_VERSION_1 is usually bit 32.
+ // If not defined in header, we hardcode logic here: (1ULL << 0) for high bits
+ *REG(VIRTIO_MMIO_DRIVER_FEATURES) = 1;
+
+ status |= VIRTIO_CONFIG_S_FEATURES_OK;
+ *REG(VIRTIO_MMIO_STATUS) = status;
+
+ if (!(*REG(VIRTIO_MMIO_STATUS) & VIRTIO_CONFIG_S_FEATURES_OK))
+ {
+ Drivers::uart_puts("VirtIO: Feature negotiation failed.\n");
+ return;
+ }
+
+ // 6. Queue Configuration
+ *REG(VIRTIO_MMIO_QUEUE_SEL) = 0;
+ if (*REG(VIRTIO_MMIO_QUEUE_READY))
+ {
+ Drivers::uart_puts("VirtIO: Queue 0 not ready.\n");
+ }
+
+ uint32 max_queue = *REG(VIRTIO_MMIO_QUEUE_NUM_MAX);
+ if (max_queue < NUM_DESCS)
+ {
+ Drivers::uart_puts("VirtIO: Queue size too small.\n");
+ return;
+ }
+
+ *REG(VIRTIO_MMIO_QUEUE_NUM) = NUM_DESCS;
+
+ // Allocate Memory for VirtQueues
+ void *ptr = PMM::alloc_pages(1); // 4KB is enough for small rings
+ memset(ptr, 0, PGSIZE);
+
+ uint64 base_addr = (uint64)ptr;
+ disk.desc = reinterpret_cast<struct VRingDesc *>(base_addr);
+ disk.avail = reinterpret_cast<struct VRingAvail *>(base_addr + NUM_DESCS * 16);
+ disk.used = reinterpret_cast<struct VRingUsed *>(base_addr + PGSIZE / 2);
+
+ *REG(VIRTIO_MMIO_QUEUE_DESC_LOW) = (uint32)base_addr;
+ *REG(VIRTIO_MMIO_QUEUE_DESC_HIGH) = (uint32)(base_addr >> 32);
+
+ uint64 avail_addr = (uint64)disk.avail;
+ *REG(VIRTIO_MMIO_QUEUE_DRIVER_LOW) = (uint32)avail_addr;
+ *REG(VIRTIO_MMIO_QUEUE_DRIVER_HIGH) = (uint32)(avail_addr >> 32);
+
+ uint64 used_addr = (uint64)disk.used;
+ *REG(VIRTIO_MMIO_QUEUE_DEVICE_LOW) = (uint32)used_addr;
+ *REG(VIRTIO_MMIO_QUEUE_DEVICE_HIGH) = (uint32)(used_addr >> 32);
+
+ *REG(VIRTIO_MMIO_QUEUE_READY) = 1;
+
+ // 7. Initialize Internal Structures
+ disk.free_head = 0;
+ disk.num_free = NUM_DESCS;
+ disk.used_idx = 0;
+ for (int i = 0; i < NUM_DESCS; i++)
+ {
+ disk.free_chain[i] = i + 1;
+ disk.info[i].busy = 0;
+ }
+
+ // 8. Finalize Setup
+ status |= VIRTIO_CONFIG_S_DRIVER_OK;
+ *REG(VIRTIO_MMIO_STATUS) = status;
+
+ // === [Feature] Read Capacity ===
+ volatile struct virtio_blk_config *config = (volatile struct virtio_blk_config *)(virtio_base + VIRTIO_MMIO_CONFIG);
+ uint64 capacity_sectors = config->capacity;
+ uint64 size_mb = (capacity_sectors * 512) / (1024 * 1024);
+
+ Drivers::uart_puts(ANSI_GREEN "[VirtIO] Initialized. Capacity: ");
+ Drivers::uart_put_int(size_mb);
+ Drivers::uart_puts(" MB\n" ANSI_RESET);
+ }
+
+ static int alloc_desc()
+ {
+ if (disk.num_free == 0)
+ return -1;
+ int id = disk.free_head;
+ disk.free_head = disk.free_chain[id];
+ disk.num_free--;
+ return id;
+ }
+
+ static void free_desc(int id)
+ {
+ disk.free_chain[id] = disk.free_head;
+ disk.free_head = id;
+ disk.num_free++;
+ ProcManager::wakeup(&disk.free_head);
+ }
+
+ static void free_chain_soft(int head_idx)
+ {
+ int curr = head_idx;
+ while (1)
+ {
+ int flag = disk.desc[curr].flags;
+ int next = disk.desc[curr].next;
+ free_desc(curr);
+ if (flag & VRING_DESC_F_NEXT)
+ curr = next;
+ else
+ break;
+ }
+ }
+
+ void rw(int write, uint64 blockno, char *buf)
+ {
+ uint64 sector = blockno * (1024 / 512); // Assume 1KB blocks
+
+ disk.lock.acquire();
+
+ // Wait for enough descriptors
+ while (disk.num_free < 3)
+ {
+ ProcManager::sleep(&disk.free_head, &disk.lock);
+ }
+
+ int idx[3];
+ idx[0] = alloc_desc();
+ idx[1] = alloc_desc();
+ idx[2] = alloc_desc();
+
+ // 1. Request Header
+ struct BlockRequest *req = &disk.reqs[idx[0]];
+ req->type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN;
+ req->reserved = 0;
+ req->sector = sector;
+
+ disk.desc[idx[0]].addr = (uint64)req;
+ disk.desc[idx[0]].len = sizeof(struct BlockRequest);
+ disk.desc[idx[0]].flags = VRING_DESC_F_NEXT;
+ disk.desc[idx[0]].next = idx[1];
+
+ // 2. Data Buffer
+ disk.desc[idx[1]].addr = (uint64)buf;
+ disk.desc[idx[1]].len = 1024; // Fixed 1KB for this test
+ disk.desc[idx[1]].flags = VRING_DESC_F_NEXT;
+ if (!write)
+ disk.desc[idx[1]].flags |= VRING_DESC_F_WRITE;
+ disk.desc[idx[1]].next = idx[2];
+
+ // 3. Status Byte
+ disk.desc[idx[2]].addr = (uint64)&disk.req_status[idx[0]];
+ disk.desc[idx[2]].len = 1;
+ disk.desc[idx[2]].flags = VRING_DESC_F_WRITE;
+ disk.desc[idx[2]].next = 0;
+
+ disk.info[idx[0]].busy = 1;
+
+ // Submit to Avail Ring
+ disk.avail->ring[disk.avail->idx % NUM_DESCS] = idx[0];
+ __sync_synchronize();
+ disk.avail->idx++;
+ __sync_synchronize();
+
+ // Notify Device
+ *REG(VIRTIO_MMIO_QUEUE_NOTIFY) = 0;
+
+ // Wait for Completion
+ while (disk.info[idx[0]].busy)
+ {
+ ProcManager::sleep(&disk.info[idx[0]], &disk.lock);
+ }
+
+ free_chain_soft(idx[0]);
+ disk.lock.release();
+ }
+
+ void intr()
+ {
+ disk.lock.acquire();
+
+ uint32 status = *REG(VIRTIO_MMIO_INTERRUPT_STATUS);
+ *REG(VIRTIO_MMIO_INTERRUPT_ACK) = status & 0x3;
+
+ volatile struct VRingUsed *used_ring = (volatile struct VRingUsed *)disk.used;
+
+ while (disk.used_idx != used_ring->idx)
+ {
+ int id = used_ring->ring[disk.used_idx % NUM_DESCS].id;
+
+ if (disk.info[id].busy)
+ {
+ disk.info[id].busy = 0;
+ ProcManager::wakeup(&disk.info[id]);
+ }
+ disk.used_idx++;
+ }
+
+ disk.lock.release();
+ }
+
+ void test_rw()
+ {
+ Drivers::uart_puts(ANSI_BLUE "[VirtIO] Disk Test Start...\n" ANSI_RESET);
+
+ char *buf = (char *)PMM::alloc_page();
+ if (!buf)
+ return;
+
+ const char *msg = "Lume OS Disk Driver Test Pattern";
+ strcpy(buf, msg);
+
+ rw(1, 0, buf); // Write
+ memset(buf, 0, PGSIZE);
+ rw(0, 0, buf); // Read
+
+ if (strcmp(buf, msg) == 0)
+ {
+ Drivers::uart_puts(ANSI_GREEN "[VirtIO] Test PASSED (R/W Verified).\n" ANSI_RESET);
+ }
+ else
+ {
+ Drivers::uart_puts(ANSI_RED "[VirtIO] Test FAILED.\n" ANSI_RESET);
+ }
+
+ PMM::free_page(buf);
+ }
+} \ No newline at end of file
diff --git a/src/kernel/main.cc b/src/kernel/main.cc
index 081ab3e..6e3bdde 100644
--- a/src/kernel/main.cc
+++ b/src/kernel/main.cc
@@ -1,6 +1,8 @@
#include "common/types.h"
#include "kernel/riscv.h"
#include "drivers/uart.h"
+#include "drivers/plic.h"
+#include "drivers/virtio.h"
#include "kernel/pmm.h"
#include "kernel/mm.h"
#include "kernel/proc.h"
@@ -8,7 +10,6 @@
#include "kernel/timer.h"
#include "kernel/cpu.h"
-// 引用外部 FDT 初始化函数
extern void fdt_init(uint64 dtb);
extern uint64 g_dtb_addr;
@@ -30,6 +31,9 @@ extern "C" void kernel_main(uint64 hartid, uint64 dtb)
VM::kvminithart(); // Enable MMU
Trap::init(); // Trap Management
Trap::inithart();
+ PLIC::init();
+ PLIC::inithart();
+ VirtIO::init();
Timer::init();
ProcManager::init(); // Process Management
ProcManager::user_init(); // Initialize first user process
@@ -45,6 +49,7 @@ extern "C" void kernel_main(uint64 hartid, uint64 dtb)
VM::kvminithart();
Trap::inithart();
+ PLIC::inithart();
Timer::init();
Drivers::uart_puts("[Boot] Hart started.\n");
}
diff --git a/src/kernel/mm/pmm.cc b/src/kernel/mm/pmm.cc
index 09bd65b..3474a49 100644
--- a/src/kernel/mm/pmm.cc
+++ b/src/kernel/mm/pmm.cc
@@ -9,73 +9,6 @@
extern "C" char kernel_end[];
extern uint64 g_dtb_addr;
-// namespace PMM
-// {
-// struct Run
-// {
-// struct Run *next;
-// };
-
-// struct
-// {
-// struct Run *freelist;
-// } kmem;
-
-// inline uint64_t PGROUNDUP(uint64_t a)
-// {
-// return (a + PGSIZE - 1) & ~(PGSIZE - 1);
-// }
-
-// void init()
-// {
-// uint64_t start = PGROUNDUP((uint64_t)kernel_end);
-
-// Drivers::uart_puts("PMM: Initializing from");
-
-// for (uint64_t p = start; p + PGSIZE <= PHYSTOP; p += PGSIZE)
-// {
-// free_page((void *)p);
-// }
-// }
-
-// void free_page(void* pa)
-// {
-// struct Run *r;
-// if (((uint64_t)pa % PGSIZE) != 0 || (uint64_t)pa < (uint64_t)kernel_end || (uint64_t)pa >= PHYSTOP)
-// {
-// Drivers::uart_puts("PMM: Error - Invalid free address\n");
-// return;
-// }
-// r = (struct Run*)pa;
-
-// r->next = kmem.freelist;
-// kmem.freelist = r;
-
-// }
-
-// void* alloc_page()
-// {
-// struct Run* r;
-
-// r = kmem.freelist;
-// if (r)
-// {
-// kmem.freelist = r->next;
-
-// uint64_t *p = (uint64_t *)r;
-// for (int i = 0; i < PGSIZE / 8; i++)
-// {
-// p[i] = 0;
-// }
-// }
-// else
-// {
-// Drivers::uart_puts("PMM: Out of memory!\n");
-// }
-// return (void *)r;
-// }
-// }
-
namespace PMM
{
// Global metadata array pointer
diff --git a/src/kernel/mm/slab.cc b/src/kernel/mm/slab.cc
index 370074a..702dc5c 100644
--- a/src/kernel/mm/slab.cc
+++ b/src/kernel/mm/slab.cc
@@ -19,6 +19,7 @@ struct SlabHeader
uint16 used_count; // Number of allocated objects
// Followed immediately by object data...
// The free list of objects is embedded in the first 2 bytes of the object itself (stores the index of the next object)
+ uint32 padding;
};
struct KmemCache
@@ -82,6 +83,7 @@ namespace Slab
slab->next = nullptr;
slab->used_count = 0;
slab->free_idx = 0;
+ slab->padding = 0;
// Initialize the free list of objects
// The starting position of each object stores the index of the next object
@@ -186,7 +188,7 @@ namespace Slab
if (!page)
return;
- if (!(page->flags & PG_slab))
+ if (!page || !(page->flags & PG_slab))
{
PMM::free_pages(ptr, page->order);
return;
@@ -204,6 +206,13 @@ namespace Slab
struct SlabHeader *slab = (struct SlabHeader *)PGROUNDDOWN((uint64)ptr);
+ if ((uint64)ptr < (uint64)(slab + 1) || (uint64)ptr >= (uint64)slab + PGSIZE)
+ {
+ Drivers::uart_puts("Slab: kfree invalid pointer\n");
+ c->lock.release();
+ return;
+ }
+
char *base = (char *)(slab + 1);
int obj_idx = ((uint64)ptr - (uint64)base) / c->obj_size;
diff --git a/src/kernel/mm/vm.cc b/src/kernel/mm/vm.cc
index c3c5f01..7057d88 100644
--- a/src/kernel/mm/vm.cc
+++ b/src/kernel/mm/vm.cc
@@ -360,11 +360,10 @@ namespace VM
{
kernel_pagetable = uvmcreate();
- kvmmap(0x10000000, 0x10000000, PGSIZE, PTE_R | PTE_W);
+ kvmmap(0x10000000, 0x10000000, 0x10000, PTE_R | PTE_W);
kvmmap(0x0c000000, 0x0c000000, 0x400000, PTE_R | PTE_W);
kvmmap(0x02000000, 0x02000000, 0x10000, PTE_R | PTE_W); // CLINT
kvmmap(KERNBASE, KERNBASE, PHYSTOP - KERNBASE, PTE_R | PTE_W | PTE_X);
- // kvmmap(TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
}
void kvminithart()
diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc
index e99b83d..c8b6d1d 100644
--- a/src/kernel/proc/proc.cc
+++ b/src/kernel/proc/proc.cc
@@ -471,7 +471,6 @@ namespace ProcManager
int wait(uint64 addr)
{
- (void)addr;
struct Proc *np;
int havekids, pid;
@@ -499,6 +498,11 @@ namespace ProcManager
}
pid = np->pid;
+ if (addr != 0 && VM::copyout(p->pagetable, addr, (char *)&np->xstate, sizeof(np->xstate)) < 0)
+ {
+ proc_mem_lock.release();
+ return -1;
+ }
freeproc(np);
proc_mem_lock.release();
return pid;
@@ -509,8 +513,33 @@ namespace ProcManager
if (!havekids || p->state == ZOMBIE)
return -1;
- sleep(p, nullptr);
+ sleep(p, &proc_mem_lock);
+ }
+ }
+
+ int growproc(int n)
+ {
+ uint64 sz;
+ struct Proc *p = myproc();
+
+ sz = p->sz;
+
+ if (n > 0)
+ {
+ // Call VM::uvmalloc to allocate memory
+ // Parameters: page table, old size, new size, permissions (PTE_W)
+ if ((sz = VM::uvmalloc(p->pagetable, sz, sz + n, PTE_W)) == 0)
+ {
+ return -1;
+ }
}
+ else if (n < 0)
+ {
+ sz = VM::uvmdealloc(p->pagetable, sz, sz + n);
+ }
+
+ p->sz = sz;
+ return 0;
}
void create_kernel_thread(void (*func)(), const char *name)
diff --git a/src/kernel/syscall.cc b/src/kernel/syscall.cc
index 1dfec73..837ac2c 100644
--- a/src/kernel/syscall.cc
+++ b/src/kernel/syscall.cc
@@ -3,6 +3,7 @@
#include "kernel/proc.h"
#include "kernel/riscv.h"
#include "drivers/uart.h"
+#include "drivers/virtio.h"
#include "kernel/timer.h"
#include "kernel/mm.h"
#include "kernel/trap.h"
@@ -124,6 +125,42 @@ static uint64_t sys_write()
return static_cast<uint64_t>(-1);
}
+static uint64_t sys_read()
+{
+ int fd;
+ int n;
+ uint64_t p;
+
+ // get param: fd, buf, len
+ if (argint(0, &fd) < 0 || argint(2, &n) < 0)
+ return -1;
+ p = argraw(1);
+
+ if (fd == 0) // stdin
+ {
+ return Drivers::console_read(p, n);
+ }
+ return -1;
+}
+
+static uint64_t sys_sbrk()
+{
+ int n;
+ if (argint(0, &n) < 0)
+ return -1;
+
+ uint64_t addr = myproc()->sz;
+ if (ProcManager::growproc(n) < 0)
+ return -1;
+
+ return addr;
+}
+
+static uint64_t sys_disk_test()
+{
+ VirtIO::test_rw();
+ return 0;
+}
void syscall()
{
@@ -131,15 +168,19 @@ void syscall()
int num = p->tf->a7;
uint64_t ret = static_cast<uint64_t>(-1);
- Drivers::uart_puts("Syscall: ");
- Drivers::print_hex(num);
- Drivers::uart_puts("\n");
+ /* Just For Debug */
+ // Drivers::uart_puts("Syscall: ");
+ // Drivers::print_hex(num);
+ // Drivers::uart_puts("\n");
switch (num)
{
case SYS_write:
ret = sys_write();
break;
+ case SYS_read:
+ ret = sys_read();
+ break;
case SYS_putc:
ret = sys_putc();
break;
@@ -155,6 +196,12 @@ void syscall()
case SYS_getpid:
ret = sys_getpid();
break;
+ case SYS_sbrk:
+ ret = sys_sbrk();
+ break;
+ case SYS_disk_test:
+ ret = sys_disk_test();
+ break;
default:
Drivers::uart_puts("Unknown Syscall ID: ");
Drivers::print_hex(num);
diff --git a/src/kernel/trap/handler.cc b/src/kernel/trap/handler.cc
index d7f78de..c1626cc 100644
--- a/src/kernel/trap/handler.cc
+++ b/src/kernel/trap/handler.cc
@@ -6,6 +6,7 @@
#include "kernel/mm.h"
#include "kernel/timer.h"
#include "drivers/plic.h"
+#include "drivers/virtio.h"
#include "lib/string.h"
@@ -59,20 +60,24 @@ namespace Trap
if (is_interrupt && code == 9)
{
// Supervisor External Interrupt (IRQ 9)
- int irq = PILC::claim();
+ int irq = PLIC::claim();
if (irq == 10)
{
- // uart_intr();
+ Drivers::uart_intr();
+ // Debug
+ // Drivers::uart_puts("[Interrupt] UART Input detected!\n");
}
else if (irq >= 1 && irq <= 8)
{
- // virtio_disk_intr();
+ VirtIO::intr();
+ // Debug
+ // Drivers::uart_puts("[Interrupt] VirtIO disk finished!\n");
}
if (irq > 0)
{
- PILC::complete(irq);
+ PLIC::complete(irq);
}
return 1;
diff --git a/src/user/entry.S b/src/user/entry.S
new file mode 100644
index 0000000..110ebbf
--- /dev/null
+++ b/src/user/entry.S
@@ -0,0 +1,12 @@
+.section .text
+.global _start
+
+_start:
+ li a0, 0
+ li a1, 0
+
+ call main
+
+ call exit
+
+1: j 1b \ No newline at end of file
diff --git a/src/user/init.cc b/src/user/init.cc
index 85252be..1646f6b 100644
--- a/src/user/init.cc
+++ b/src/user/init.cc
@@ -13,106 +13,175 @@ void print(const char *s)
write(1, s, strlen(s));
}
-void print_int(int val)
+void print_int(int n)
{
char buf[16];
int i = 0;
- if (val == 0)
+ int neg = 0;
+ if (n == 0)
{
- print("0");
+ write(1, "0", 1);
return;
}
- if (val < 0)
+ if (n < 0)
{
- print("-");
- val = -val;
+ neg = 1;
+ n = -n;
}
- while (val > 0)
+ while (n > 0)
{
- buf[i++] = (val % 10) + '0';
- val /= 10;
+ buf[i++] = (n % 10) + '0';
+ n /= 10;
}
+ if (neg)
+ buf[i++] = '-';
while (i > 0)
- {
- char c = buf[--i];
- write(1, &c, 1);
- }
+ write(1, &buf[--i], 1);
}
-void pass() { print(" -> [PASS]\n"); }
-void fail()
+void print_hex(uint64 n)
{
- print(" -> [FAIL]\n");
- exit(1);
+ char buf[16];
+ char digits[] = "0123456789ABCDEF";
+ write(1, "0x", 2);
+ if (n == 0)
+ {
+ write(1, "0", 1);
+ return;
+ }
+ int i = 0;
+ while (n > 0)
+ {
+ buf[i++] = digits[n % 16];
+ n /= 16;
+ }
+ while (i > 0)
+ write(1, &buf[--i], 1);
}
-int main()
+void test_syscalls()
{
- print("\n=== Lume OS Full Validation ===\n");
-
- print("[TEST 1] Write\n");
- print(" System call write is working.");
- pass();
-
- print("[TEST 2] GetPID\n");
- int parent_pid = getpid();
- print(" Parent PID: ");
- print_int(parent_pid);
- if (parent_pid > 0)
- pass();
+ print("\n=== [Test] Starting System Call Check ===\n");
+
+ print("[1/4] Checking getpid()... ");
+ int my_pid = getpid();
+ if (my_pid > 0)
+ {
+ print("PASS (PID=");
+ print_int(my_pid);
+ print(")\n");
+ }
else
- fail();
+ {
+ print("FAIL (Invalid PID)\n");
+ }
+
+ print("[2/4] Checking sbrk() heap allocation... ");
+ char *p = sbrk(4096);
+ if (p == (char *)-1)
+ {
+ print("FAIL (sbrk returned error)\n");
+ }
+ else
+ {
+ p[0] = 'A';
+ p[4095] = 'Z';
+ if (p[0] == 'A' && p[4095] == 'Z')
+ {
+ print("PASS (Allocated at ");
+ print_hex((uint64)p);
+ print(")\n");
+ }
+ else
+ {
+ print("FAIL (Memory read/write check failed)\n");
+ }
+ }
- print("[TEST 3] Fork, Wait & COW\n");
- int val = 100;
+ print("[3/4] Checking fork() and wait()...\n");
int pid = fork();
if (pid < 0)
{
- print(" Fork Failed\n");
- fail();
+ print(" FAIL: fork error\n");
}
-
- if (pid == 0)
+ else if (pid == 0)
{
- print(" [Child] PID: ");
- print_int(getpid());
- print("\n");
-
- if (val != 100)
+ int child_pid = getpid();
+ if (child_pid == my_pid)
{
- print(" [Child] Data corruption!\n");
+ print(" FAIL: Child has same PID as parent\n");
exit(1);
}
-
- val = 200;
- print(" [Child] Modified val to 200. Exiting.\n");
+ print(" [Child] I am alive. PID=");
+ print_int(child_pid);
+ print("\n");
+ print(" [Child] Exiting now.\n");
exit(0);
}
else
{
- print(" [Parent] Waiting for child...\n");
- int child_pid = wait(0);
-
- print(" [Parent] Child ");
- print_int(child_pid);
- print(" exited.\n");
+ print(" [Parent] Forked child PID=");
+ print_int(pid);
+ print("\n");
+ print(" [Parent] Waiting for child...\n");
- print(" [Parent] Check val (Expect 100): ");
- print_int(val);
+ int waited_pid = wait(0);
- if (val == 100)
- pass();
+ if (waited_pid == pid)
+ {
+ print(" [Parent] Wait returned correct PID.\n");
+ print("PASS (Fork/Wait cycle)\n");
+ }
else
{
- print(" [Parent] Memory Isolation Failed! Val=");
- print_int(val);
- fail();
+ print("FAIL (Wait returned ");
+ print_int(waited_pid);
+ print(")\n");
}
}
- print("\n=== All Tests Passed ===\n");
+ print("[4/4] Checking write()... PASS (Self-evident)\n");
+
+ print("=== [Test] All Tests Finished ===\n");
+}
+
+
+int main()
+{
+ print("\n[Lume Shell] Ready.\n");
+ print("Commands:\n");
+ print(" s: Run System Call Tests (fork, wait, mm)\n");
+ print(" t: Run Disk Driver Test (VirtIO)\n");
+
while (1)
- ;
+ {
+ char buf[16];
+ write(1, "$ ", 2);
+
+ int n = read(0, buf, sizeof(buf));
+ if (n <= 0)
+ continue;
+
+ if (buf[0] == 's')
+ {
+ test_syscalls();
+ }
+ else if (buf[0] == 't')
+ {
+ if (fork() == 0)
+ {
+ disk_test();
+ exit(0);
+ }
+ wait(0);
+ }
+ else if (buf[0] != '\n')
+ {
+ print("Unknown command.\n");
+ }
+ }
+
+ exit(0);
return 0;
} \ No newline at end of file
diff --git a/src/user/usys.S b/src/user/usys.S
index e805d82..65937cc 100644
--- a/src/user/usys.S
+++ b/src/user/usys.S
@@ -28,4 +28,5 @@ SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(sleep)
SYSCALL(uptime)
-SYSCALL(putc) \ No newline at end of file
+SYSCALL(putc)
+SYSCALL(disk_test) \ No newline at end of file