diff --git a/kernel/entry.S b/kernel/entry.S index 5ab365e..9bd821d 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -1,7 +1,13 @@ - # 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. +# 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. + .section .text .global _entry _entry: diff --git a/kernel/kernel.ld b/kernel/kernel.ld index ee04f22..7ab21d8 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -9,6 +9,11 @@ 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); @@ -19,6 +24,10 @@ 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 */ @@ -26,6 +35,10 @@ 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 */ @@ -33,6 +46,12 @@ 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 */ @@ -40,5 +59,6 @@ SECTIONS *(.bss .bss.*) } + /* PROVIDE, see vm.c */ PROVIDE(end = .); } diff --git a/kernel/kernelvec.S b/kernel/kernelvec.S index fb31b32..008c831 100644 --- a/kernel/kernelvec.S +++ b/kernel/kernelvec.S @@ -1,11 +1,15 @@ - # - # 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. - # +# 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. + .globl kerneltrap .globl kernelvec .align 4 @@ -53,7 +57,8 @@ kernelvec: ld ra, 0(sp) ld sp, 8(sp) ld gp, 16(sp) - # not tp (contains hartid), in case we moved CPUs + # Skip tp (thread pointer aka x4) (contains hartid) + # in case we moved CPUs ld t0, 32(sp) ld t1, 40(sp) ld t2, 48(sp) @@ -87,9 +92,11 @@ kernelvec: # return to whatever we were doing in the kernel. sret - # - # machine-mode timer interrupt. - # +# machine-mode timer interrupt +# +# See: start.c for timervec declaration +# extern void timervec(); + .globl timervec .align 4 timervec: @@ -97,7 +104,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/swtch.S b/kernel/swtch.S index abbd396..3a78f60 100644 --- a/kernel/swtch.S +++ b/kernel/swtch.S @@ -1,12 +1,18 @@ +# For a quick reference on RISC-V assembly: +# https://risc-v.guru/instructions/ + # Context switch # -# void swtch(struct context *old, struct context *new); -# # 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); .globl swtch swtch: + # sd = Store Double (64 bits) sd ra, 0(a0) sd sp, 8(a0) sd s0, 16(a0) @@ -22,6 +28,7 @@ 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) @@ -36,7 +43,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 d7308cc..3f514dd 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -1,14 +1,17 @@ - # - # 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. - # +# 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. #include "riscv.h" #include "memlayout.h" @@ -18,7 +21,7 @@ trampoline: .align 4 .globl uservec -uservec: +uservec: # # trap.c sets stvec to point here, so # traps from user space start here, @@ -34,7 +37,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) @@ -145,7 +148,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 e8f7a91..a8d101a 100644 --- a/user/initcode.S +++ b/user/initcode.S @@ -1,3 +1,6 @@ +# For a quick reference on RISC-V assembly: +# https://risc-v.guru/instructions/ + # Initial process that execs /init. # This code runs in user space.