1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-23 00:16:17 +04:00

Can run user program in RV32

This commit is contained in:
WangRunji 2018-07-14 11:56:55 +08:00
parent c0138c4c35
commit 1ad3ed738e
4 changed files with 24 additions and 18 deletions

@ -1 +1 @@
Subproject commit a8bbb3eb031fc377098e1493b14f22ba8448b2ad
Subproject commit aa26e4dd950089e115ae0573bab7fb7aeac7764e

View File

@ -24,8 +24,15 @@ impl TrapFrame {
tf.sstatus.set_spp(sstatus::SPP::Supervisor);
tf
}
fn new_user_thread(entry_addr: usize, rsp: usize) -> Self {
unimplemented!()
fn new_user_thread(entry_addr: usize, sp: usize) -> Self {
use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() };
tf.x[2] = sp;
tf.sepc = entry_addr;
tf.sstatus = sstatus::read();
tf.sstatus.set_spie(false); // Enable interrupt
tf.sstatus.set_spp(sstatus::SPP::User);
tf
}
pub fn is_user(&self) -> bool {
unimplemented!()

View File

@ -1,6 +1,6 @@
use core::slice;
use memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet, Stack};
use super::riscv::addr::*;
use super::riscv::{addr::*, register::sstatus};
use ucore_memory::PAGE_SIZE;
pub fn init() {
@ -8,6 +8,7 @@ pub fn init() {
struct PageData([u8; PAGE_SIZE]);
static PAGE_TABLE_ROOT: PageData = PageData([0; PAGE_SIZE]);
unsafe { sstatus::set_sum(); } // Allow user memory access
let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32));
super::paging::setup_page_table(frame);
init_frame_allocator();

View File

@ -1,7 +1,7 @@
use alloc::String;
use arch::interrupt::*;
use memory::{MemoryArea, MemoryAttr, MemorySet};
use xmas_elf::{ElfFile, header::HeaderPt2, program::{Flags, ProgramHeader}};
use xmas_elf::{ElfFile, header, program::{Flags, ProgramHeader, Type}};
#[derive(Debug)]
pub struct Process {
@ -55,16 +55,15 @@ impl Process {
}
}
/// Make a new user thread
/// The program elf data is placed at [begin, end)
/// uCore x86 32bit program is planned to be supported.
/// Make a new user thread from ELF data
pub fn new_user(data: &[u8]) -> Self {
// Parse elf
let elf = ElfFile::new(data).expect("failed to read elf");
let is32 = match elf.header.pt2 {
HeaderPt2::Header32(_) => true,
HeaderPt2::Header64(_) => false,
header::HeaderPt2::Header32(_) => true,
header::HeaderPt2::Header64(_) => false,
};
assert_eq!(elf.header.pt2.type_().as_type(), header::Type::Executable, "ELF is not executable");
// User stack
use consts::{USER_STACK_OFFSET, USER_STACK_SIZE, USER32_STACK_OFFSET};
@ -78,19 +77,15 @@ impl Process {
memory_set.push(MemoryArea::new(user_stack_buttom, user_stack_top, MemoryAttr::default().user(), "user_stack"));
trace!("{:#x?}", memory_set);
let entry_addr = match elf.header.pt2 {
HeaderPt2::Header32(header) => header.entry_point as usize,
HeaderPt2::Header64(header) => header.entry_point as usize,
};
let entry_addr = elf.header.pt2.entry_point() as usize;
// Temporary switch to it, in order to copy data
unsafe {
memory_set.with(|| {
for ph in elf.program_iter() {
let (virt_addr, offset, file_size) = match ph {
ProgramHeader::Ph32(ph) => (ph.virtual_addr as usize, ph.offset as usize, ph.file_size as usize),
ProgramHeader::Ph64(ph) => (ph.virtual_addr as usize, ph.offset as usize, ph.file_size as usize),
};
let virt_addr = ph.virtual_addr() as usize;
let offset = ph.offset() as usize;
let file_size = ph.file_size() as usize;
use core::slice;
let target = unsafe { slice::from_raw_parts_mut(virt_addr as *mut u8, file_size) };
target.copy_from_slice(&data[offset..offset + file_size]);
@ -166,6 +161,9 @@ impl Process {
fn memory_set_from<'a>(elf: &'a ElfFile<'a>) -> MemorySet {
let mut set = MemorySet::new();
for ph in elf.program_iter() {
if ph.get_type() != Ok(Type::Load) {
continue;
}
let (virt_addr, mem_size, flags) = match ph {
ProgramHeader::Ph32(ph) => (ph.virtual_addr as usize, ph.mem_size as usize, ph.flags),
ProgramHeader::Ph64(ph) => (ph.virtual_addr as usize, ph.mem_size as usize, ph.flags),