diff --git a/kernel/entry.S b/kernel/entry.S index 0a2e5d9..5ab365e 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -1,65 +1,21 @@ -# For a quick reference on RISC-V assembly: -# https://risc-v.guru/instructions/ - -# Kernel entry point -# -# qemu -kernel loads the kernel at 0x80000000 -# and causes each hart (i.e. CPU) to jump there. -# kernel.ld causes the following code to -# be placed at 0x80000000. - + # qemu -kernel loads the kernel at 0x80000000 + # and causes each hart (i.e. CPU) to jump there. + # kernel.ld causes the following code to + # be placed at 0x80000000. .section .text .global _entry _entry: - # Clear all the registers. - li x1, 0x0 - li x2, 0x0 - li x3, 0x0 - li x4, 0x0 - li x5, 0x0 - li x6, 0x0 - li x7, 0x0 - li x8, 0x0 - li x9, 0x0 - li x10, 0x0 - li x11, 0x0 - li x12, 0x0 - li x13, 0x0 - li x14, 0x0 - li x15, 0x0 - li x16, 0x0 - li x17, 0x0 - li x18, 0x0 - li x19, 0x0 - li x20, 0x0 - li x21, 0x0 - li x22, 0x0 - li x23, 0x0 - li x24, 0x0 - li x25, 0x0 - li x26, 0x0 - li x27, 0x0 - li x28, 0x0 - li x29, 0x0 - li x30, 0x0 - li x31, 0x0 - # set up a stack for C. # stack0 is declared in start.c, # with a 4096-byte stack per CPU. # sp = stack0 + (hartid * 4096) la sp, stack0 - li a0, 1024*4 # a0 = 4096 - - # Control and Status Register Read - csrr a1, mhartid # a1 = unique hart (core) id - addi a1, a1, 1 # a1 += 1 - mul a0, a0, a1 # a0 *= a1, aka a0 = 4096 * (hartid + 1), the base of the stack for this hart - add sp, sp, a0 # sp += a0, stack pointer is now properly configured - + li a0, 1024*4 + csrr a1, mhartid + addi a1, a1, 1 + mul a0, a0, a1 + add sp, sp, a0 # jump to start() in start.c call start - -# Infinite spin loop. spin: j spin diff --git a/kernel/kernel.ld b/kernel/kernel.ld index 7ab21d8..ee04f22 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -9,11 +9,6 @@ SECTIONS */ . = 0x80000000; - /* - * This section contains the code. This is, the machine language instructions - * that will be executed by the processor. In here we will find symbols - * that reference the functions in your object file. - */ .text : { *(.text .text.*) . = ALIGN(0x1000); @@ -24,10 +19,6 @@ SECTIONS PROVIDE(etext = .); } - /* - * This contains any data that is marked as read only. - * It is not unusual to find this data interleaved with the text section. - */ .rodata : { . = ALIGN(16); *(.srodata .srodata.*) /* do not need to distinguish this from .rodata */ @@ -35,10 +26,6 @@ SECTIONS *(.rodata .rodata.*) } - /* - * This section contains initialized global and static variables. - * Any global object that has been explicitly initialized to a value different than zero. - */ .data : { . = ALIGN(16); *(.sdata .sdata.*) /* do not need to distinguish this from .data */ @@ -46,12 +33,6 @@ SECTIONS *(.data .data.*) } - /* - * Contains all uninitialized global and static var iables. These are usually - * zeroed out by the startup code before we reach the main function. However, - * In an embedded system we usually provide our own startup code, which means - * we need to remember to do this ourselves. - */ .bss : { . = ALIGN(16); *(.sbss .sbss.*) /* do not need to distinguish this from .bss */ @@ -59,6 +40,5 @@ SECTIONS *(.bss .bss.*) } - /* PROVIDE, see vm.c */ PROVIDE(end = .); } diff --git a/kernel/kernelvec.S b/kernel/kernelvec.S index 008c831..fb31b32 100644 --- a/kernel/kernelvec.S +++ b/kernel/kernelvec.S @@ -1,15 +1,11 @@ -# For a quick reference on RISC-V assembly: -# https://risc-v.guru/instructions/ - -# Kernel trap handling -# -# interrupts and exceptions while in supervisor -# mode come here. -# -# the current stack is a kernel stack. -# push all registers, call kerneltrap(). -# when kerneltrap() returns, restore registers, return. - + # + # interrupts and exceptions while in supervisor + # mode come here. + # + # the current stack is a kernel stack. + # push all registers, call kerneltrap(). + # when kerneltrap() returns, restore registers, return. + # .globl kerneltrap .globl kernelvec .align 4 @@ -57,8 +53,7 @@ kernelvec: ld ra, 0(sp) ld sp, 8(sp) ld gp, 16(sp) - # Skip tp (thread pointer aka x4) (contains hartid) - # in case we moved CPUs + # not tp (contains hartid), in case we moved CPUs ld t0, 32(sp) ld t1, 40(sp) ld t2, 48(sp) @@ -92,11 +87,9 @@ kernelvec: # return to whatever we were doing in the kernel. sret -# machine-mode timer interrupt -# -# See: start.c for timervec declaration -# extern void timervec(); - + # + # machine-mode timer interrupt. + # .globl timervec .align 4 timervec: @@ -104,7 +97,7 @@ timervec: # scratch[0,8,16] : register save area. # scratch[24] : address of CLINT's MTIMECMP register. # scratch[32] : desired interval between interrupts. - + csrrw a0, mscratch, a0 sd a1, 0(a0) sd a2, 8(a0) diff --git a/kernel/start.c b/kernel/start.c index f6d36cb..f2bdc52 100644 --- a/kernel/start.c +++ b/kernel/start.c @@ -2,6 +2,7 @@ #include "param.h" #include "memlayout.h" #include "riscv.h" +#include "defs.h" void main(); void timerinit(); diff --git a/kernel/swtch.S b/kernel/swtch.S index 3a78f60..abbd396 100644 --- a/kernel/swtch.S +++ b/kernel/swtch.S @@ -1,18 +1,12 @@ -# For a quick reference on RISC-V assembly: -# https://risc-v.guru/instructions/ - # Context switch # -# Save current registers in old. Load from new. -# -# See: defs.h for swtch declaration -# See: proc.h for struct context definition -# # void swtch(struct context *old, struct context *new); +# +# Save current registers in old. Load from new. + .globl swtch swtch: - # sd = Store Double (64 bits) sd ra, 0(a0) sd sp, 8(a0) sd s0, 16(a0) @@ -28,7 +22,6 @@ swtch: sd s10, 96(a0) sd s11, 104(a0) - # ld = Load Double (64 bits) ld ra, 0(a1) ld sp, 8(a1) ld s0, 16(a1) @@ -43,7 +36,7 @@ swtch: ld s9, 88(a1) ld s10, 96(a1) ld s11, 104(a1) - + ret diff --git a/kernel/trampoline.S b/kernel/trampoline.S index 3f514dd..d7308cc 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -1,17 +1,14 @@ -# For a quick reference on RISC-V assembly: -# https://risc-v.guru/instructions/ - -# Trampoline code -# -# low-level code to handle traps from user space into -# the kernel, and returns from kernel to user. -# -# the kernel maps the page holding this code -# at the same virtual address (TRAMPOLINE) -# in user and kernel space so that it continues -# to work when it switches page tables. -# kernel.ld causes this code to start at -# a page boundary. + # + # low-level code to handle traps from user space into + # the kernel, and returns from kernel to user. + # + # the kernel maps the page holding this code + # at the same virtual address (TRAMPOLINE) + # in user and kernel space so that it continues + # to work when it switches page tables. + # kernel.ld causes this code to start at + # a page boundary. + # #include "riscv.h" #include "memlayout.h" @@ -21,7 +18,7 @@ trampoline: .align 4 .globl uservec -uservec: +uservec: # # trap.c sets stvec to point here, so # traps from user space start here, @@ -37,7 +34,7 @@ uservec: # but it's mapped to the same virtual address # (TRAPFRAME) in every process's user page table. li a0, TRAPFRAME - + # save the user registers in TRAPFRAME sd ra, 40(a0) sd sp, 48(a0) @@ -148,7 +145,7 @@ userret: # restore user a0 ld a0, 112(a0) - + # return to user mode and user pc. # usertrapret() set up sstatus and sepc. sret diff --git a/user/initcode.S b/user/initcode.S index a8d101a..e8f7a91 100644 --- a/user/initcode.S +++ b/user/initcode.S @@ -1,6 +1,3 @@ -# For a quick reference on RISC-V assembly: -# https://risc-v.guru/instructions/ - # Initial process that execs /init. # This code runs in user space. diff --git a/user/mkdir.c b/user/mkdir.c index 07328b0..274cd45 100644 --- a/user/mkdir.c +++ b/user/mkdir.c @@ -1,3 +1,5 @@ +#include "kernel/types.h" +#include "kernel/stat.h" #include "user/user.h" int