Helpful comments in assembly and linker script files

This commit is contained in:
Imbus 2024-08-07 11:26:07 +02:00
parent 7a3c98f2b4
commit be6678c0e6
6 changed files with 81 additions and 35 deletions

View file

@ -1,7 +1,13 @@
# qemu -kernel loads the kernel at 0x80000000 # For a quick reference on RISC-V assembly:
# and causes each hart (i.e. CPU) to jump there. # https://risc-v.guru/instructions/
# kernel.ld causes the following code to
# be placed at 0x80000000. # 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 .section .text
.global _entry .global _entry
_entry: _entry:

View file

@ -9,6 +9,11 @@ SECTIONS
*/ */
. = 0x80000000; . = 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 .text.*) *(.text .text.*)
. = ALIGN(0x1000); . = ALIGN(0x1000);
@ -19,6 +24,10 @@ SECTIONS
PROVIDE(etext = .); 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 : { .rodata : {
. = ALIGN(16); . = ALIGN(16);
*(.srodata .srodata.*) /* do not need to distinguish this from .rodata */ *(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
@ -26,6 +35,10 @@ SECTIONS
*(.rodata .rodata.*) *(.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 : { .data : {
. = ALIGN(16); . = ALIGN(16);
*(.sdata .sdata.*) /* do not need to distinguish this from .data */ *(.sdata .sdata.*) /* do not need to distinguish this from .data */
@ -33,6 +46,12 @@ SECTIONS
*(.data .data.*) *(.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 : { .bss : {
. = ALIGN(16); . = ALIGN(16);
*(.sbss .sbss.*) /* do not need to distinguish this from .bss */ *(.sbss .sbss.*) /* do not need to distinguish this from .bss */
@ -40,5 +59,6 @@ SECTIONS
*(.bss .bss.*) *(.bss .bss.*)
} }
/* PROVIDE, see vm.c */
PROVIDE(end = .); PROVIDE(end = .);
} }

View file

@ -1,11 +1,15 @@
# # For a quick reference on RISC-V assembly:
# interrupts and exceptions while in supervisor # https://risc-v.guru/instructions/
# mode come here.
# # Kernel trap handling
# the current stack is a kernel stack. #
# push all registers, call kerneltrap(). # interrupts and exceptions while in supervisor
# when kerneltrap() returns, restore registers, return. # mode come here.
# #
# the current stack is a kernel stack.
# push all registers, call kerneltrap().
# when kerneltrap() returns, restore registers, return.
.globl kerneltrap .globl kerneltrap
.globl kernelvec .globl kernelvec
.align 4 .align 4
@ -53,7 +57,8 @@ kernelvec:
ld ra, 0(sp) ld ra, 0(sp)
ld sp, 8(sp) ld sp, 8(sp)
ld gp, 16(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 t0, 32(sp)
ld t1, 40(sp) ld t1, 40(sp)
ld t2, 48(sp) ld t2, 48(sp)
@ -87,9 +92,11 @@ kernelvec:
# return to whatever we were doing in the kernel. # return to whatever we were doing in the kernel.
sret sret
# # machine-mode timer interrupt
# machine-mode timer interrupt. #
# # See: start.c for timervec declaration
# extern void timervec();
.globl timervec .globl timervec
.align 4 .align 4
timervec: timervec:
@ -97,7 +104,7 @@ timervec:
# scratch[0,8,16] : register save area. # scratch[0,8,16] : register save area.
# scratch[24] : address of CLINT's MTIMECMP register. # scratch[24] : address of CLINT's MTIMECMP register.
# scratch[32] : desired interval between interrupts. # scratch[32] : desired interval between interrupts.
csrrw a0, mscratch, a0 csrrw a0, mscratch, a0
sd a1, 0(a0) sd a1, 0(a0)
sd a2, 8(a0) sd a2, 8(a0)

View file

@ -1,12 +1,18 @@
# For a quick reference on RISC-V assembly:
# https://risc-v.guru/instructions/
# Context switch # Context switch
# #
# void swtch(struct context *old, struct context *new);
#
# Save current registers in old. Load from 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 .globl swtch
swtch: swtch:
# sd = Store Double (64 bits)
sd ra, 0(a0) sd ra, 0(a0)
sd sp, 8(a0) sd sp, 8(a0)
sd s0, 16(a0) sd s0, 16(a0)
@ -22,6 +28,7 @@ swtch:
sd s10, 96(a0) sd s10, 96(a0)
sd s11, 104(a0) sd s11, 104(a0)
# ld = Load Double (64 bits)
ld ra, 0(a1) ld ra, 0(a1)
ld sp, 8(a1) ld sp, 8(a1)
ld s0, 16(a1) ld s0, 16(a1)
@ -36,7 +43,7 @@ swtch:
ld s9, 88(a1) ld s9, 88(a1)
ld s10, 96(a1) ld s10, 96(a1)
ld s11, 104(a1) ld s11, 104(a1)
ret ret

View file

@ -1,14 +1,17 @@
# # For a quick reference on RISC-V assembly:
# low-level code to handle traps from user space into # https://risc-v.guru/instructions/
# the kernel, and returns from kernel to user.
# # Trampoline code
# the kernel maps the page holding this code #
# at the same virtual address (TRAMPOLINE) # low-level code to handle traps from user space into
# in user and kernel space so that it continues # the kernel, and returns from kernel to user.
# to work when it switches page tables. #
# kernel.ld causes this code to start at # the kernel maps the page holding this code
# a page boundary. # 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 "riscv.h"
#include "memlayout.h" #include "memlayout.h"
@ -18,7 +21,7 @@
trampoline: trampoline:
.align 4 .align 4
.globl uservec .globl uservec
uservec: uservec:
# #
# trap.c sets stvec to point here, so # trap.c sets stvec to point here, so
# traps from user space start here, # traps from user space start here,
@ -34,7 +37,7 @@ uservec:
# but it's mapped to the same virtual address # but it's mapped to the same virtual address
# (TRAPFRAME) in every process's user page table. # (TRAPFRAME) in every process's user page table.
li a0, TRAPFRAME li a0, TRAPFRAME
# save the user registers in TRAPFRAME # save the user registers in TRAPFRAME
sd ra, 40(a0) sd ra, 40(a0)
sd sp, 48(a0) sd sp, 48(a0)
@ -145,7 +148,7 @@ userret:
# restore user a0 # restore user a0
ld a0, 112(a0) ld a0, 112(a0)
# return to user mode and user pc. # return to user mode and user pc.
# usertrapret() set up sstatus and sepc. # usertrapret() set up sstatus and sepc.
sret sret

View file

@ -1,3 +1,6 @@
# For a quick reference on RISC-V assembly:
# https://risc-v.guru/instructions/
# Initial process that execs /init. # Initial process that execs /init.
# This code runs in user space. # This code runs in user space.