Compare commits
No commits in common. "riscv" and "feat/start" have entirely different histories.
riscv
...
feat/start
1
Makefile
1
Makefile
|
|
@ -8,6 +8,7 @@ OBJS = \
|
||||||
$K/kalloc.o \
|
$K/kalloc.o \
|
||||||
$K/spinlock.o \
|
$K/spinlock.o \
|
||||||
$K/string.o \
|
$K/string.o \
|
||||||
|
$K/main.o \
|
||||||
$K/vm.o \
|
$K/vm.o \
|
||||||
$K/proc.o \
|
$K/proc.o \
|
||||||
$K/swtch.o \
|
$K/swtch.o \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "param.h"
|
||||||
|
#include "memlayout.h"
|
||||||
|
#include "riscv.h"
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
volatile static int started = 0;
|
||||||
|
|
||||||
|
// start() jumps here in supervisor mode on all CPUs.
|
||||||
|
void main() {
|
||||||
|
if (cpuid() == 0) {
|
||||||
|
consoleinit();
|
||||||
|
printfinit();
|
||||||
|
printf("\n");
|
||||||
|
printf("xv6 kernel is booting\n");
|
||||||
|
printf("\n");
|
||||||
|
kinit(); // physical page allocator
|
||||||
|
kvminit(); // create kernel page table
|
||||||
|
kvminithart(); // turn on paging
|
||||||
|
procinit(); // process table
|
||||||
|
trapinit(); // trap vectors
|
||||||
|
trapinithart(); // install kernel trap vector
|
||||||
|
plicinit(); // set up interrupt controller
|
||||||
|
plicinithart(); // ask PLIC for device interrupts
|
||||||
|
binit(); // buffer cache
|
||||||
|
iinit(); // inode table
|
||||||
|
fileinit(); // file table
|
||||||
|
virtio_disk_init(); // emulated hard disk
|
||||||
|
userinit(); // first user process
|
||||||
|
__sync_synchronize();
|
||||||
|
started = 1;
|
||||||
|
} else {
|
||||||
|
while (started == 0)
|
||||||
|
;
|
||||||
|
__sync_synchronize();
|
||||||
|
printf("hart %d starting\n", cpuid());
|
||||||
|
kvminithart(); // turn on paging
|
||||||
|
trapinithart(); // install kernel trap vector
|
||||||
|
plicinithart(); // ask PLIC for device interrupts
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler();
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,12 @@
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
void initlock(struct spinlock *lk, char *name) {
|
||||||
|
lk->name = name;
|
||||||
|
lk->locked = 0;
|
||||||
|
lk->cpu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Acquire the lock.
|
// Acquire the lock.
|
||||||
// Loops (spins) until the lock is acquired.
|
// Loops (spins) until the lock is acquired.
|
||||||
void acquire(struct spinlock *lk) {
|
void acquire(struct spinlock *lk) {
|
||||||
|
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
use crate::riscv;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn cpuid() -> u64;
|
|
||||||
fn consoleinit();
|
|
||||||
fn printfinit();
|
|
||||||
fn printf(msg: *const i8);
|
|
||||||
fn kinit();
|
|
||||||
fn kvminit();
|
|
||||||
fn kvminithart();
|
|
||||||
fn procinit();
|
|
||||||
fn trapinit();
|
|
||||||
fn trapinithart();
|
|
||||||
fn plicinit();
|
|
||||||
fn plicinithart();
|
|
||||||
fn binit();
|
|
||||||
fn iinit();
|
|
||||||
fn fileinit();
|
|
||||||
fn virtio_disk_init();
|
|
||||||
fn userinit();
|
|
||||||
fn scheduler();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub static mut started: bool = false;
|
|
||||||
|
|
||||||
pub unsafe fn kmain() {
|
|
||||||
if cpuid() == 0 {
|
|
||||||
consoleinit();
|
|
||||||
printfinit();
|
|
||||||
printf(c"\n".as_ptr());
|
|
||||||
printf(c"xv6 kernel is booting\n".as_ptr());
|
|
||||||
printf(c"\n".as_ptr());
|
|
||||||
kinit(); // physical page allocator
|
|
||||||
kvminit(); // create kernel page table
|
|
||||||
kvminithart(); // turn on paging
|
|
||||||
procinit(); // process table
|
|
||||||
trapinit(); // trap vectors
|
|
||||||
trapinithart(); // install kernel trap vector
|
|
||||||
plicinit(); // set up interrupt controller
|
|
||||||
plicinithart(); // ask PLIC for device interrupts
|
|
||||||
binit(); // buffer cache
|
|
||||||
iinit(); // inode table
|
|
||||||
fileinit(); // file table
|
|
||||||
virtio_disk_init(); // emulated hard disk
|
|
||||||
userinit(); // first user process
|
|
||||||
riscv::barrier();
|
|
||||||
started = true;
|
|
||||||
} else {
|
|
||||||
while !started {}
|
|
||||||
riscv::barrier();
|
|
||||||
// printf("hart %d starting\n", cpuid());
|
|
||||||
kvminithart(); // turn on paging
|
|
||||||
trapinithart(); // install kernel trap vector
|
|
||||||
plicinithart(); // ask PLIC for device interrupts
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler();
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![crate_type = "staticlib"]
|
#![crate_type = "staticlib"]
|
||||||
|
|
||||||
use core::ffi::CStr;
|
|
||||||
|
|
||||||
pub mod kmain;
|
|
||||||
pub mod memlayout;
|
pub mod memlayout;
|
||||||
pub mod param;
|
pub mod param;
|
||||||
pub mod riscv;
|
pub mod riscv;
|
||||||
|
|
@ -13,16 +10,17 @@ pub mod uart;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// printf.c
|
// printf.c
|
||||||
fn panic(s: *const i8);
|
fn panic(s: *const u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PANIC_MSG: &CStr = c"!RUST PANIC!";
|
/// '!RUST PANIC!\0'
|
||||||
|
static PANIC_MSG: [u8; 13] = [33, 82, 85, 83, 84, 32, 80, 65, 78, 73, 67, 33, 0];
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn panic_handler(_info: &core::panic::PanicInfo) -> ! {
|
fn panic_handler(_info: &core::panic::PanicInfo) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
panic(PANIC_MSG.as_ptr());
|
panic(core::ptr::addr_of!(PANIC_MSG[0]));
|
||||||
}
|
}
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,3 @@ pub fn PX(level: u64, va: u64) -> u64 {
|
||||||
// Sv39, to avoid having to sign-extend virtual addresses
|
// Sv39, to avoid having to sign-extend virtual addresses
|
||||||
// that have the high bit set.
|
// that have the high bit set.
|
||||||
pub const MAXVA: u64 = 1 << (9 + 9 + 9 + 12 - 1);
|
pub const MAXVA: u64 = 1 << (9 + 9 + 9 + 12 - 1);
|
||||||
|
|
||||||
/// Hardware memory barrier
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn barrier() {
|
|
||||||
asm!("fence")
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
use core::ptr::null_mut;
|
|
||||||
|
|
||||||
// Mutual exclusion lock.
|
// Mutual exclusion lock.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct SpinLock {
|
pub struct SpinLock {
|
||||||
// Is the lock held?
|
// Is the lock held?
|
||||||
pub locked: u32, // C boolean
|
pub locked: u32, // C boolean
|
||||||
// For debugging:
|
// For debugging:
|
||||||
pub name: *const i8, // Name of lock.
|
pub name: Option<*mut ()>, // Name of lock.
|
||||||
pub cpu: *mut (), // The cpu holding the lock.
|
pub cpu: Option<*mut ()>, // The cpu holding the lock.
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn initlock(lock: *mut SpinLock, name: *const i8) {
|
|
||||||
(*lock).name = name;
|
|
||||||
(*lock).locked = 0;
|
|
||||||
(*lock).cpu = null_mut();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use core::usize;
|
use core::usize;
|
||||||
|
|
||||||
use crate::kmain::kmain;
|
|
||||||
use crate::memlayout::{CLINT_MTIME, CLINT_MTIMECMP};
|
use crate::memlayout::{CLINT_MTIME, CLINT_MTIMECMP};
|
||||||
use crate::param::NCPU;
|
use crate::param::NCPU;
|
||||||
use crate::riscv as rv;
|
use crate::riscv as rv;
|
||||||
|
|
@ -9,6 +8,9 @@ use crate::riscv as rv;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// assembly code in kernelvec.S for machine-mode timer interrupt.
|
// assembly code in kernelvec.S for machine-mode timer interrupt.
|
||||||
fn timervec();
|
fn timervec();
|
||||||
|
|
||||||
|
// main.c
|
||||||
|
fn main();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(align(16))]
|
#[repr(align(16))]
|
||||||
|
|
@ -32,7 +34,7 @@ pub unsafe extern "C" fn start() {
|
||||||
|
|
||||||
// set M Exception Program Counter to main, for mret.
|
// set M Exception Program Counter to main, for mret.
|
||||||
// requires gcc -mcmodel=medany
|
// requires gcc -mcmodel=medany
|
||||||
rv::w_mepc(kmain as *const () as u64);
|
rv::w_mepc(main as *const () as u64);
|
||||||
|
|
||||||
// disable paging for now.
|
// disable paging for now.
|
||||||
rv::w_satp(0);
|
rv::w_satp(0);
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
use crate::{
|
use crate::{memlayout::UART0, spinlock::SpinLock};
|
||||||
memlayout::UART0,
|
use core::ptr::addr_of_mut;
|
||||||
spinlock::{initlock, SpinLock},
|
|
||||||
};
|
|
||||||
use core::{
|
|
||||||
ffi::CStr,
|
|
||||||
ptr::{addr_of_mut, null, null_mut},
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// spinlock.c
|
// spinlock.c
|
||||||
fn push_off();
|
fn push_off();
|
||||||
fn pop_off();
|
fn pop_off();
|
||||||
|
fn initlock(spinlock: *mut SpinLock, name: *const u8);
|
||||||
fn acquire(spinlock: *mut SpinLock);
|
fn acquire(spinlock: *mut SpinLock);
|
||||||
fn release(spinlock: *mut SpinLock);
|
fn release(spinlock: *mut SpinLock);
|
||||||
|
|
||||||
|
|
@ -65,11 +60,12 @@ pub fn WriteReg(reg: u8, v: u8) {
|
||||||
// the transmit output buffer.
|
// the transmit output buffer.
|
||||||
static mut uart_tx_lock: crate::spinlock::SpinLock = crate::spinlock::SpinLock {
|
static mut uart_tx_lock: crate::spinlock::SpinLock = crate::spinlock::SpinLock {
|
||||||
locked: 0,
|
locked: 0,
|
||||||
cpu: null_mut(),
|
cpu: None,
|
||||||
name: null(),
|
name: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
static UART_LOCK_NAME: &CStr = c"uart";
|
// NOTE: string 'uart\0' for c-implmentation of spinlock. Stupid but works.
|
||||||
|
static UART_LOCK_NAME: [u8; 5] = [117, 97, 114, 116, 0];
|
||||||
|
|
||||||
const UART_TX_BUF_SIZE: usize = 32;
|
const UART_TX_BUF_SIZE: usize = 32;
|
||||||
static mut uart_tx_buf: [u8; UART_TX_BUF_SIZE] = [0; UART_TX_BUF_SIZE];
|
static mut uart_tx_buf: [u8; UART_TX_BUF_SIZE] = [0; UART_TX_BUF_SIZE];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue