diff --git a/Makefile b/Makefile index 99db2da..f2b989e 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,7 @@ CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 & LDFLAGS = -z max-page-size=4096 linker = ./linker/k210.ld +# linker = ./linker/xv6.ld # LDFLAGS = -Wl,--build-id=none -nostartfiles -nostdlib -static -fno-stack-protector # LIBS := -lgcc diff --git a/doc/s_extern_interrupt.md b/doc/s_extern_interrupt.md index 42a388b..51b6b67 100644 --- a/doc/s_extern_interrupt.md +++ b/doc/s_extern_interrupt.md @@ -76,7 +76,7 @@ supervisor_external_handler() { ... // 使用 SBI 调用注册 S 态外部中断处理函数 -sbi_set_extern_interrupt((uint64)supervisor_external_handler - 0xffffffff00000000); +sbi_set_extern_interrupt((uint64)supervisor_external_handler); ``` 这样做看起来很简单,是因为 luojia 在 RustSBI 中针对 K210 这个平台做的特定的功能,如果是 OpenSBI 就达不到这种效果。这么做的原理我这里直接引用吴一凡学长的笔记: diff --git a/kernel/entry_k210.S b/kernel/entry_k210.S index 4dd1dc9..f5d2378 100644 --- a/kernel/entry_k210.S +++ b/kernel/entry_k210.S @@ -3,16 +3,21 @@ _start: add t0, a0, 1 slli t0, t0, 14 - lui sp, %hi(boot_stack) + // lui sp, %hi(boot_stack) + la sp, boot_stack add sp, sp, t0 // add by retrhelo, write tp reg - //csrr t1, mhartid - //mv tp, t1 + // csrr t1, mhartid + // mv tp, t1 - lui t0, %hi(main) - addi t0, t0, %lo(main) - jr t0 + // lui t0, %hi(main) + // addi t0, t0, %lo(main) + // jr t0 + call main + +loop: + j loop .section .bss.stack .align 12 diff --git a/kernel/include/param.h b/kernel/include/param.h index 7d338b1..c1be2cc 100644 --- a/kernel/include/param.h +++ b/kernel/include/param.h @@ -1,4 +1,4 @@ -#define NPROC 64 // maximum number of processes +#define NPROC 16 // maximum number of processes #define NCPU 8 // maximum number of CPUs #define NOFILE 16 // open files per process #define NFILE 100 // open files per system diff --git a/kernel/include/riscv.h b/kernel/include/riscv.h index 4e5efbf..7eee34a 100644 --- a/kernel/include/riscv.h +++ b/kernel/include/riscv.h @@ -319,7 +319,6 @@ sfence_vma() { // the zero, zero means flush all TLB entries. // asm volatile("sfence.vma zero, zero"); - // asm volatile("sfence.vm"); asm volatile("sfence.vma"); } diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index bc5f356..4dd9473 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -20,3 +20,4 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 +#define SYS_test 22 diff --git a/kernel/kalloc.c b/kernel/kalloc.c index b664e1a..18c9f36 100644 --- a/kernel/kalloc.c +++ b/kernel/kalloc.c @@ -28,8 +28,8 @@ void kinit() { initlock(&kmem.lock, "kmem"); - printf("kernel_end: %p, phystop: %p\n", kernel_end - 0xffffffff00000000, (void*)PHYSTOP); - freerange(kernel_end - 0xffffffff00000000, (void*)PHYSTOP); + printf("kernel_end: %p, phystop: %p\n", kernel_end, (void*)PHYSTOP); + freerange(kernel_end, (void*)PHYSTOP); printf("kinit\n"); } @@ -51,7 +51,7 @@ kfree(void *pa) { struct run *r; - if(((uint64)pa % PGSIZE) != 0 || (char*)pa < kernel_end - 0xffffffff00000000 || (uint64)pa >= PHYSTOP) + if(((uint64)pa % PGSIZE) != 0 || (char*)pa < kernel_end || (uint64)pa >= PHYSTOP) panic("kfree"); // Fill with junk to catch dangling refs. diff --git a/kernel/main.c b/kernel/main.c index 8ac0a08..ba4b50c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -34,19 +34,19 @@ main(unsigned long hartid, unsigned long dtb_pa) timerinit(); // set up timer interrupt handler procinit(); device_init(dtb_pa, hartid); - fpioa_pin_init(); - sdcard_init(); + // fpioa_pin_init(); + // sdcard_init(); //plicinit(); // set up interrupt controller //plicinithart(); // ask PLIC for device interrupts - binit(); // buffer cache - iinit(); // inode cache - fileinit(); // file table + // binit(); // buffer cache + // iinit(); // inode cache + // fileinit(); // file table //virtio_disk_init(); // emulated hard disk - userinit(); // first user process + // userinit(); // first user process + test_proc_init(); // test porc init // test_kalloc(); // test kalloc - test_vm(hartid); // test kernel pagetable - // test_proc_init(); // test porc init + // test_vm(hartid); // test kernel pagetable // test_sdcard(); printf("hart 0 init done\n"); diff --git a/kernel/proc.c b/kernel/proc.c index 0b15ecd..3372d7d 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -24,45 +24,6 @@ static void freeproc(struct proc *p); extern char trampoline[]; // trampoline.S void reg_info(void) { - // struct proc *p = myproc(); - // printf("trapframe {\n"); - // printf(" kernel_satp: %p\n", p->trapframe->kernel_satp); - // printf(" kernel_sp: %p\n", p->trapframe->kernel_sp); - // printf(" kernel_trap: %p\n", p->trapframe->kernel_trap); - // printf(" kernel_hartid: %p\n", p->trapframe->kernel_hartid); - // printf(" epc: %p\n", p->trapframe->epc); - // printf(" ra: %p\n", p->trapframe->ra); - // printf(" sp: %p\n", p->trapframe->sp); - // printf(" gp: %p\n", p->trapframe->gp); - // printf(" tp: %p\n", p->trapframe->tp); - // printf(" t0: %p\n", p->trapframe->t0); - // printf(" t1: %p\n", p->trapframe->t1); - // printf(" t2: %p\n", p->trapframe->t2); - // printf(" s0: %p\n", p->trapframe->s0); - // printf(" s1: %p\n", p->trapframe->s1); - // printf(" a0: %p\n", p->trapframe->a0); - // printf(" a1: %p\n", p->trapframe->a1); - // printf(" a2: %p\n", p->trapframe->a2); - // printf(" a3: %p\n", p->trapframe->a3); - // printf(" a4: %p\n", p->trapframe->a4); - // printf(" a5: %p\n", p->trapframe->a5); - // printf(" a6: %p\n", p->trapframe->a6); - // printf(" a7: %p\n", p->trapframe->a7); - // printf(" s2: %p\n", p->trapframe->s2); - // printf(" s3: %p\n", p->trapframe->s3); - // printf(" s4: %p\n", p->trapframe->s4); - // printf(" s5: %p\n", p->trapframe->s5); - // printf(" s6: %p\n", p->trapframe->s6); - // printf(" s7: %p\n", p->trapframe->s7); - // printf(" s8: %p\n", p->trapframe->s8); - // printf(" s9: %p\n", p->trapframe->s9); - // printf(" s10: %p\n", p->trapframe->s10); - // printf(" s11: %p\n", p->trapframe->s11); - // printf(" t3: %p\n", p->trapframe->t3); - // printf(" t4: %p\n", p->trapframe->t4); - // printf(" t5: %p\n", p->trapframe->t5); - // printf(" t6: %p\n", p->trapframe->t6); - // printf("}\n"); printf("register info: {\n"); printf("sstatus: %p\n", r_sstatus()); printf("sip: %p\n", r_sip()); @@ -268,74 +229,55 @@ uchar initcode[] = { 0x00, 0x00, 0x00, 0x00 }; - -uchar proc_test_code_1[] = { - 0x13, 0x05, 0x10, 0x04, 0x93, 0x05, 0x00, 0x00, 0x13, 0x06, 0x00, 0x00, 0x93, 0x06, 0x00, 0x00, - 0x93, 0x08, 0x10, 0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00 +uchar printhello[] = { + 0x13, 0x00, 0x00, 0x00, // nop + 0x13, 0x00, 0x00, 0x00, // nop + 0x13, 0x00, 0x00, 0x00, // nop + // + 0x17, 0x05, 0x00, 0x00, // auipc a0, 0x0 + 0x13, 0x05, 0x05, 0x00, // mv a0, a0 + 0x93, 0x08, 0x60, 0x01, // li a7, 22 + 0x73, 0x00, 0x00, 0x00, // ecall + 0xef, 0xf0, 0x1f, 0xff, // jal ra, + // + 0xef, 0x00, 0x00, 0x00, // jal ra, }; -uchar proc_test_code_2[] = { - 0x13, 0x05, 0x20, 0x04, 0x93, 0x05, 0x00, 0x00, 0x13, 0x06, 0x00, 0x00, 0x93, 0x06, 0x00, 0x00, - 0x93, 0x08, 0x10, 0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00 -}; - -uchar proc_test_code_3[] = { - 0x13, 0x05, 0x30, 0x04, 0x93, 0x05, 0x00, 0x00, 0x13, 0x06, 0x00, 0x00, 0x93, 0x06, 0x00, 0x00, - 0x93, 0x08, 0x10, 0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00 -}; - -uchar proc_test_code_4[] = { - 0x13, 0x05, 0x40, 0x04, 0x93, 0x05, 0x00, 0x00, 0x13, 0x06, 0x00, 0x00, 0x93, 0x06, 0x00, 0x00, - 0x93, 0x08, 0x10, 0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00 -}; void test_proc_init() { - struct proc *p1; + struct proc *p; - p1 = allocproc(); - uvminit(p1->pagetable, proc_test_code_1, sizeof(proc_test_code_1)); - // initproc = p1; - p1->sz = PGSIZE; - p1->trapframe->epc = 0; // user program counter - p1->trapframe->sp = PGSIZE; // user stack pointer - safestrcpy(p1->name, "proc_test_code_1", sizeof(p1->name)); - p1->cwd = namei("/test"); - p1->state = RUNNABLE; - release(&p1->lock); - printf("[test_proc_init]allocproc: %p\n", p1); + p = allocproc(); + initproc = p; - // struct proc *p2; - // p2 = allocproc(); - // uvminit(p2->pagetable, proc_test_code_2, sizeof(proc_test_code_2)); - // p2->sz = PGSIZE; - // p2->trapframe->epc = 0; // user program counter - // p2->trapframe->sp = PGSIZE; // user stack pointer - // safestrcpy(p2->name, "proc_test_code_2", sizeof(p2->name)); - // p2->cwd = namei("/test"); - // p2->state = RUNNABLE; - // release(&p2->lock); + uvminit(p->pagetable, (uchar*)printhello, sizeof(printhello)); + p->sz = PGSIZE; - // struct proc *p3; - // p3 = allocproc(); - // uvminit(p3->pagetable, proc_test_code_3, sizeof(proc_test_code_3)); - // p3->sz = PGSIZE; - // p3->trapframe->epc = 0; // user program counter - // p3->trapframe->sp = PGSIZE; // user stack pointer - // safestrcpy(p3->name, "proc_test_code_3", sizeof(p3->name)); - // p3->cwd = namei("/test"); - // p3->state = RUNNABLE; - // release(&p3->lock); + p->trapframe->epc = 0x0; + p->trapframe->sp = PGSIZE; - // struct proc *p4; - // p4 = allocproc(); - // uvminit(p4->pagetable, proc_test_code_4, sizeof(proc_test_code_4)); - // p4->sz = PGSIZE; - // p4->trapframe->epc = 0; // user program counter - // p4->trapframe->sp = PGSIZE; // user stack pointer - // safestrcpy(p4->name, "proc_test_code_4", sizeof(p4->name)); - // p4->cwd = namei("/test"); - // p4->state = RUNNABLE; - // release(&p4->lock); + safestrcpy(p->name, "test_code_0", sizeof(p->name)); + + p->state = RUNNABLE; + + release(&p->lock); + + struct proc *p1; + + p1 = allocproc(); + printf("return from allocproc()\n"); + + uvminit(p1->pagetable, (uchar*)printhello, sizeof(printhello)); + p1->sz = PGSIZE; + + p1->trapframe->epc = 0x0; + p1->trapframe->sp = PGSIZE; + + safestrcpy(p1->name, "test_code_1", sizeof(p1->name)); + + p1->state = RUNNABLE; + + release(&p1->lock); printf("[test_proc]test_proc init done\n"); } @@ -352,7 +294,7 @@ userinit(void) // allocate one user page and copy init's instructions // and data into it. // uvminit(p->pagetable, initcode, sizeof(initcode)); - uvminit(p->pagetable, proc_test_code_1, sizeof(proc_test_code_1)); + uvminit(p->pagetable, initcode, sizeof(initcode)); p->sz = PGSIZE; // prepare for the very first "return" from kernel to user. diff --git a/kernel/syscall.c b/kernel/syscall.c index 073d4e5..4aeb51b 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -106,6 +106,7 @@ extern uint64 sys_unlink(void); extern uint64 sys_wait(void); extern uint64 sys_write(void); extern uint64 sys_uptime(void); +extern uint64 sys_test(void); static uint64 (*syscalls[])(void) = { [SYS_fork] sys_fork, @@ -129,6 +130,7 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_test] sys_test, }; void @@ -146,3 +148,9 @@ syscall(void) p->trapframe->a0 = -1; } } + +uint64 +sys_test(void) { + printf("%d: hello world\n", myproc()->pid); + return 0; +} \ No newline at end of file diff --git a/kernel/test.c b/kernel/test.c index a15f2d0..dd7e190 100644 --- a/kernel/test.c +++ b/kernel/test.c @@ -11,7 +11,7 @@ #include "include/sbi.h" #include "include/sdcard.h" -extern uint64 etext_addr; +extern uint64 etext; extern struct proc *initproc; void test_kalloc() { char *mem = kalloc(); @@ -70,11 +70,11 @@ void test_vm(unsigned long hart_id) { printf("[test_vm](kvmpa) va: %p, pa: %p\n", KERNBASE + 0x1000, kvmpa(KERNBASE + 0x1000)); printf("[test_vm](kvmpa) va: %p, pa: %p\n", KERNBASE + 0x2000, kvmpa(KERNBASE + 0x2000)); printf("[test_vm](kvmpa) va: %p, pa: %p\n", KERNBASE + 0x3000, kvmpa(KERNBASE + 0x3000)); - printf("[test_vm]etext_addr:\n"); - printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext_addr, kvmpa(etext_addr)); - printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext_addr + 0x1000, kvmpa(etext_addr + 0x1000)); - printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext_addr + 0x2000, kvmpa(etext_addr + 0x2000)); - printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext_addr + 0x3000, kvmpa(etext_addr + 0x3000)); + printf("[test_vm]etext:\n"); + printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext, kvmpa(etext)); + printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext + 0x1000, kvmpa(etext + 0x1000)); + printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext + 0x2000, kvmpa(etext + 0x2000)); + printf("[test_vm](kvmpa) va: %p, pa: %p\n", etext + 0x3000, kvmpa(etext + 0x3000)); printf("[test_vm]trampoline:\n"); printf("[test_vm](kvmpa) va: %p, pa: %p\n", TRAMPOLINE, kvmpa(TRAMPOLINE)); printf("[test_vm](kvmpa) va: %p, pa: %p\n", TRAMPOLINE + PGSIZE - 1, kvmpa(TRAMPOLINE + PGSIZE - 1)); diff --git a/kernel/trampoline.S b/kernel/trampoline.S index 057ef17..cb696a2 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -78,7 +78,7 @@ uservec: csrw satp, t1 # sfence.vma zero, zero - sfence.vm + sfence.vma # a0 is no longer valid, since the kernel page # table does not specially map p->tf. @@ -100,8 +100,7 @@ userret: csrw satp, a1 # sfence.vma zero, zero - sfence.vm - # sfence.vma + sfence.vma # put the saved user a0 in sscratch, so we # can swap it with our a0 (TRAPFRAME) in the last step. @@ -143,10 +142,6 @@ userret: # restore user a0, and save TRAPFRAME in sscratch csrrw a0, sscratch, a0 - lui t0, %hi(reg_info) - addi t0, t0, %lo(reg_info) - jr t0 - # return to user mode and user pc. # usertrapret() set up sstatus and sepc. sret diff --git a/kernel/trap.c b/kernel/trap.c index 555af60..7372370 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -19,11 +19,6 @@ void kernelvec(); extern int devintr(); -void userret_log() { - printf("run in userret\n"); - while (1) {} - -} void trapinit(void) { @@ -48,7 +43,7 @@ trapinithart(void) void usertrap(void) { - printf("run in usertrap\n"); + // printf("run in usertrap\n"); int which_dev = 0; if((r_sstatus() & SSTATUS_SPP) != 0) @@ -133,19 +128,14 @@ usertrapret(void) w_sepc(p->trapframe->epc); // tell trampoline.S the user page table to switch to. - printf("[usertrapret]p->pagetable: %p\n", p->pagetable); + // printf("[usertrapret]p->pagetable: %p\n", p->pagetable); uint64 satp = MAKE_SATP(p->pagetable); - // reg_info(); // jump to trampoline.S at the top of memory, which // switches to the user page table, restores user registers, // and switches to user mode with sret. uint64 fn = TRAMPOLINE + (userret - trampoline); - printf("[usertrapret]fn va: %p, pa: %p\n", fn, kvmpa(fn)); - printf("[usertrapret]useret: %p\n", ((uint64)userret & 0xffffffff)); - // ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp); - // use physical address `userret` instead of virtual address `fn` - ((void (*)(uint64,uint64))((uint64)userret & 0xffffffff))(TRAPFRAME, satp); + ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp); } // interrupts and exceptions from kernel code go here via kernelvec, @@ -234,7 +224,8 @@ devintr() // software interrupt from a supervisor-mode timer interrupt, if(cpuid() == 0){ - clockintr(); + // clockintr(); + printf("[devintr]clockintr\n"); } // acknowledge the software interrupt by clearing @@ -278,6 +269,6 @@ void device_init(unsigned long pa, uint64 hartid) { uint32 *hart0_m_int_enable_hi = (uint32*)(PLIC_MENABLE(hartid) + 0x04); *(hart0_m_int_enable_hi) = (1 << 0x1); // *(uint32*)0x0c002004 = (1 << 0x1); - sbi_set_extern_interrupt((uint64)supervisor_external_handler - 0xffffffff00000000); + sbi_set_extern_interrupt((uint64)supervisor_external_handler); printf("device init\n"); } \ No newline at end of file diff --git a/kernel/vm.c b/kernel/vm.c index 51ed30f..7c98933 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -12,9 +12,7 @@ pagetable_t kernel_pagetable; extern char etext[]; // kernel.ld sets this to end of kernel code. -uint64 etext_addr = (uint64)etext - 0xffffffff00000000; extern char trampoline[]; // trampoline.S -uint64 trampoline_addr = (uint64)trampoline - 0xffffffff00000000; /* * create a direct-map page table for the kernel. */ @@ -37,15 +35,14 @@ kvminit() // PLIC kvmmap(PLIC, PLIC, 0x400000, PTE_R | PTE_W); - // printf("kernel_base: %p, etext: %p, etext - kernel_base: %p\n", KERNBASE, etext_addr, etext_addr - KERNBASE); // map kernel text executable and read-only. - kvmmap(KERNBASE, KERNBASE, etext_addr - KERNBASE, PTE_R | PTE_X); + kvmmap(KERNBASE, KERNBASE, (uint64)etext - KERNBASE, PTE_R | PTE_X); // map kernel data and the physical RAM we'll make use of. - kvmmap(etext_addr, etext_addr, PHYSTOP - etext_addr, PTE_R | PTE_W); + kvmmap((uint64)etext, (uint64)etext, PHYSTOP - (uint64)etext, PTE_R | PTE_W); // map the trampoline for trap entry/exit to // the highest virtual address in the kernel. - kvmmap(TRAMPOLINE, trampoline_addr, PGSIZE, PTE_R | PTE_X); + kvmmap(TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X); // kvmmap(TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X); printf("kvminit\n"); @@ -228,8 +225,7 @@ uvminit(pagetable_t pagetable, uchar *src, uint sz) mem = kalloc(); printf("[uvminit]kalloc: %p\n", mem); memset(mem, 0, PGSIZE); - // int map_res = mappages(pagetable, 0, PGSIZE, (uint64)mem, PTE_W|PTE_R|PTE_X|PTE_U); - // printf("[vminit]map result: %d, va: %p, pa: %p\n", map_res, PGSIZE - 1, walkaddr(pagetable, PGSIZE - 1) + PGSIZE - 1); + mappages(pagetable, 0, PGSIZE, (uint64)mem, PTE_W|PTE_R|PTE_X|PTE_U); memmove(mem, src, sz); for (int i = 0; i < sz; i ++) { printf("[uvminit]mem: %p, %x\n", mem + i, mem[i]); diff --git a/linker/k210.ld b/linker/k210.ld index adadc4d..d2102b7 100644 --- a/linker/k210.ld +++ b/linker/k210.ld @@ -1,7 +1,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0xffffffff80020000; +BASE_ADDRESS = 0x80020000; SECTIONS {