Move kernel related files into kernel
This commit is contained in:
parent
f28082f98f
commit
a79af996e1
4 changed files with 2 additions and 2 deletions
59
kern/entry.S
Normal file
59
kern/entry.S
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.section .text
|
||||
.globl _entry
|
||||
_entry:
|
||||
# Both call and j will work here, but since ra will be cleared,
|
||||
# we will need a jump instruction back (from _clear) to continue.
|
||||
call _clear
|
||||
|
||||
continue:
|
||||
# Set up a stack for C.
|
||||
la sp, stack0
|
||||
li a0, 1024*4 # a0 = 4096
|
||||
csrr a1, mhartid # a1 = hart id
|
||||
addi a1, a1, 1 # hartid + 1
|
||||
mul a0, a0, a1 # a0 *= hartid+1
|
||||
add sp, sp, a0 # sp += a0
|
||||
|
||||
# Jump to start() in start.c
|
||||
call start
|
||||
|
||||
1:
|
||||
j 1b # Infinite loop
|
||||
|
||||
.section .text
|
||||
.globl _clear
|
||||
_clear:
|
||||
li x1, 0x0 # ra: Return address
|
||||
li x2, 0x0 # sp: Stack points
|
||||
li x3, 0x0 # gp: Global pointer
|
||||
li x4, 0x0 # tp: Thread pointer
|
||||
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
|
||||
|
||||
# ret wont work here since we cleared x1
|
||||
j continue
|
||||
83
kern/kernel.ld
Normal file
83
kern/kernel.ld
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY( _entry ) /* See: entry.S */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
* ensure that entry.S / _entry is at 0x80000000,
|
||||
* where qemu's -kernel jumps.
|
||||
*/
|
||||
. = 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 : {
|
||||
/* Match any section that starts with .text. */
|
||||
*(.text*)
|
||||
|
||||
/* Align the next section to a 4KB (page) boundary. */
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
/* Put the trampoline code here. */
|
||||
_trampoline = .;
|
||||
|
||||
/* Match any section that starts with .trampsec. */
|
||||
*(trampsec)
|
||||
|
||||
/* Align the next section to a 4KB (page) boundary. */
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
/* Assert that the trampoline code is exactly 4KB (page) in size. */
|
||||
/* ASSERT(. - _trampoline == 0x1000, "error: trampoline larger than one page"); */
|
||||
|
||||
/* Define symbol etext to be the current location. */
|
||||
PROVIDE(etext = .);
|
||||
} :text
|
||||
|
||||
/*
|
||||
* 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 on quadword boundary. */
|
||||
. = ALIGN(16);
|
||||
*(.srodata*) /* do not need to distinguish this from .rodata */
|
||||
. = ALIGN(16);
|
||||
*(.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*) /* do not need to distinguish this from .data */
|
||||
. = ALIGN(16);
|
||||
*(.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*) /* do not need to distinguish this from .bss */
|
||||
. = ALIGN(16);
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
/* Define symbol end as current location, note that this is not aligned, see vm.c */
|
||||
PROVIDE(kernel_end = .);
|
||||
}
|
||||
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS(0x5); /* R + X */
|
||||
}
|
||||
|
||||
69
kern/start.c
Normal file
69
kern/start.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include <config.h>
|
||||
#include <ispinlock.h>
|
||||
#include <kalloc.h>
|
||||
#include <memory.h>
|
||||
#include <proc.h>
|
||||
#include <riscv.h>
|
||||
#include <stdint.h>
|
||||
#include <uart.h>
|
||||
|
||||
/**
|
||||
* Allocate one stack per CPU (hart).
|
||||
* Each stack is 4096 bytes, aligned to 16 bytes for safety and performance.
|
||||
* The entry assembly code will calculate the proper stack address for the
|
||||
* current hart. For more info, read up on stack pointers and see: entry.S
|
||||
*/
|
||||
char stack0[4096 * NCPU] __attribute__((aligned(16)));
|
||||
|
||||
/* Keep this here and sync on it until we have synchronized printf */
|
||||
spinlock_t sl = {0};
|
||||
volatile int hold = 1;
|
||||
volatile int max_hart = 0;
|
||||
|
||||
/* This is where entry.S drops us of. All cores land here */
|
||||
void start() {
|
||||
// Do this first
|
||||
__sync_fetch_and_add(&max_hart, 1);
|
||||
__sync_synchronize();
|
||||
|
||||
u64 id = read_mhartid();
|
||||
|
||||
// Keep each CPU's hartid in its tp (thread pointer) register, for cpuid().
|
||||
// This can then be retrieved with r_wp or cpuid(). It is used to index the
|
||||
// cpus[] array in mycpu(), which in turn holds state for each individual
|
||||
// cpu (struct Cpu).
|
||||
write_tp(id);
|
||||
|
||||
if (id == 0) {
|
||||
/* Here we will do a bunch of initialization steps */
|
||||
kalloc_init();
|
||||
uart_puts("Hello Neptune!\n");
|
||||
spinlock_init(&sl);
|
||||
hold = 0;
|
||||
} else {
|
||||
while (hold);
|
||||
}
|
||||
|
||||
// spin_lock(&sl);
|
||||
//
|
||||
// uart_puts("Hart number: ");
|
||||
// uart_putc(id + '0');
|
||||
// uart_putc('\n');
|
||||
//
|
||||
// spin_unlock(&sl);
|
||||
|
||||
if (id == 0) {
|
||||
spin_lock(&sl);
|
||||
uart_puts("Core count: ");
|
||||
uart_putc(max_hart + '0');
|
||||
uart_putc('\n');
|
||||
if (max_hart == NCPU) {
|
||||
uart_puts("All cores up!");
|
||||
uart_putc('\n');
|
||||
}
|
||||
spin_unlock(&sl);
|
||||
}
|
||||
|
||||
// We should not arrive here, but if we do, hang in a while on wfi.
|
||||
while (1) __asm__ volatile("wfi"); // (Wait For Interrupt)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue