fix proc management

This commit is contained in:
hustccc 2020-11-18 07:23:50 +09:00
parent 4155b75ba4
commit 82960cc8b8
15 changed files with 95 additions and 157 deletions

View File

@ -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

View File

@ -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 就达不到这种效果。这么做的原理我这里直接引用吴一凡学长的笔记:

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -20,3 +20,4 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_test 22

View File

@ -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.

View File

@ -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");

View File

@ -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
// <start>
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, <start>
// <loop>
0xef, 0x00, 0x00, 0x00, // jal ra, <loop>
};
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.

View File

@ -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;
}

View File

@ -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));

View File

@ -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

View File

@ -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");
}

View File

@ -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]);

View File

@ -1,7 +1,7 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0xffffffff80020000;
BASE_ADDRESS = 0x80020000;
SECTIONS
{