Helpful comments in assembly and linker script files
This commit is contained in:
parent
7a3c98f2b4
commit
be6678c0e6
6 changed files with 81 additions and 35 deletions
|
@ -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:
|
||||
|
|
|
@ -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 = .);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in a new issue