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:
parent
c0138c4c35
commit
1ad3ed738e
@ -1 +1 @@
|
||||
Subproject commit a8bbb3eb031fc377098e1493b14f22ba8448b2ad
|
||||
Subproject commit aa26e4dd950089e115ae0573bab7fb7aeac7764e
|
@ -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!()
|
||||
|
@ -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();
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user