Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
92afafb
zcore: use async executor! remove rcore-thread.
wangrunji0408 Feb 8, 2020
4ec4f8a
zcore: tiny modify
wangrunji0408 Feb 11, 2020
d0eaaf0
zcore: update rboot. parse LOG from cmdline. load fuchsia.zbi from in…
wangrunji0408 Feb 11, 2020
47dcc8a
zcore: import zircon-loader
wangrunji0408 Feb 11, 2020
4ff1ed8
hal: add current page table argument to map_kernel
wangrunji0408 Feb 11, 2020
7ca4c53
hal: add MMUFlags::USER
wangrunji0408 Feb 11, 2020
371746c
zircon-loader: fix user stack and syscall arguments
wangrunji0408 Feb 11, 2020
079010f
hal-bare: implement thread spawn with executor and trapframe-rs
wangrunji0408 Feb 11, 2020
cf0a4e0
fix process::start
PanQL Feb 14, 2020
c77df50
naive: attempt to resolve deadlock
PanQL Feb 17, 2020
29227b6
update prebuilt file to 2020-02-09
PanQL Feb 18, 2020
a10f7e1
Merge branch 'master' into executor
PanQL Feb 19, 2020
0e7a647
use enum SyscallType instead of u32
PanQL Feb 19, 2020
4be0cf7
partially implement `sys_object_set/get_property`
PanQL Feb 19, 2020
2df4aea
update prebuilt binary file to 0209 for libos version
PanQL Feb 20, 2020
4a4a2e2
partial `vmar_map` impl && vdso_vmo creation fix
PanQL Feb 21, 2020
010bc89
add decompressor-zstd.so to prebuilt
PanQL Feb 22, 2020
1ffbe99
fix vdso_vmo creation for libos version
PanQL Feb 22, 2020
df9b706
try to fix `vmar_alloc`
PanQL Feb 23, 2020
9081c24
double size of vmar
PanQL Feb 23, 2020
ff263be
add `cprng_draw_once` and `vmo_write`
PanQL Feb 23, 2020
a4211de
fix SPECIFIC option for `vmar_map`
PanQL Feb 23, 2020
d9452fa
add `thread_create`
PanQL Feb 23, 2020
7471299
add tid and pid for debuglog_write
PanQL Feb 24, 2020
99013fa
add `check_runnable` for thread
PanQL Feb 24, 2020
a201e1b
partial `suspend_task_token` for ThreadObject
PanQL Feb 25, 2020
109b566
add `wait_one` and `process_start`
PanQL Feb 25, 2020
de579f2
specific `thread_write_state` ,only General option
PanQL Feb 25, 2020
07ebf1f
synchronize `state` for ThreadObject, buggy
PanQL Feb 25, 2020
729f5a6
use PanQL/executor momentarily
PanQL Feb 25, 2020
4cdc27f
fix Thread::resume
PanQL Feb 25, 2020
cfbb225
bugs(vmo-rights && pgtable-switch) is fixed by wrj
PanQL Feb 25, 2020
6f58073
object_get_info and vmo_replace_as_exec, partial
PanQL Feb 26, 2020
f20a7e7
impl sys_vmo_get_size
PanQL Feb 26, 2020
ead8c19
channel_create and get_info for vmar
PanQL Feb 28, 2020
6638655
remove `create_child_at` func in vmar
PanQL Feb 28, 2020
5fc1381
fix vmar_map bug, still not implemented.
PanQL Feb 28, 2020
22138bf
run `cargo clippy`
PanQL Mar 1, 2020
2960f50
for green CI. QAQ
PanQL Mar 1, 2020
0a4043c
for green CI
PanQL Mar 1, 2020
98df754
fix `cargo test`
PanQL Mar 1, 2020
a92b6b3
hal-unix: partial fix restoring user registers
wangrunji0408 Feb 26, 2020
e2b5d2b
renew zbi path
PanQL Mar 1, 2020
1b4aeb7
hal-unix: enlarge physical memory to 256MB. impl dealloc frames. fix …
wangrunji0408 Mar 1, 2020
5ec20fd
zircon-object: fix test
wangrunji0408 Mar 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
prebuilt/* filter=lfs diff=lfs merge=lfs -text
prebuilt/zircon/fuchsia.zbi filter=lfs diff=lfs merge=lfs -text
13 changes: 2 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
toolchain: nightly-2020-01-17
override: true
components: rustfmt, clippy
- name: Check code format
Expand Down Expand Up @@ -51,18 +51,9 @@ jobs:
with:
command: build
args: --all-features
- name: Build for riscv32
uses: actions-rs/cargo@v1
with:
command: build
args: --package kernel-hal-bare --target riscv32imac-unknown-none-elf
- name: Build for riscv64
uses: actions-rs/cargo@v1
with:
command: build
args: --package kernel-hal-bare --target riscv64imac-unknown-none-elf
- name: Build zCore
run: |
cargo install cargo-xbuild
cd zCore
make build
- name: Build docs
Expand Down
4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ members = [
"linux-syscall",
"linux-loader",
"kernel-hal-unix",
"kernel-hal-bare",
"kernel-hal",
"kernel-hal-bare",
"kernel-hal-bare",
]

exclude = [
"zCore",
"rboot",
"kernel-hal-bare",
]
4 changes: 3 additions & 1 deletion kernel-hal-bare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ description = "Kernel HAL implementation for bare metal environment."
[dependencies]
log = "0.4"
spin = "0.5"
bitflags = "1.2"
executor = { git = "https://github.com/PanQL/executor.git", rev="1818b01" }
trapframe = "0.1.1"
core = { package = "core-futures-tls", version = "0.1.0" }
kernel-hal = { path = "../kernel-hal" }

[target.'cfg(target_arch = "x86_64")'.dependencies]
Expand Down
17 changes: 16 additions & 1 deletion kernel-hal-bare/src/arch/riscv.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
use riscv::paging::{*, PageTableFlags as PTF};
use riscv::addr::Page;
use riscv::register::satp;

/// Page Table
#[repr(C)]
Expand All @@ -17,7 +18,8 @@ impl PageTableImpl {
let root_vaddr = phys_to_virt(root_frame.paddr);
let root = unsafe { &mut *(root_vaddr as *mut PageTable) };
root.zero();
map_kernel(root_vaddr as _);
let current = phys_to_virt(satp::read().frame().start_address().as_usize()) as *const PageTable;
map_kernel(root_vaddr as _, current as _);
trace!("create page table @ {:#x}", root_frame.paddr);
PageTableImpl { root_paddr: root_frame.paddr }
}
Expand Down Expand Up @@ -88,6 +90,14 @@ impl PageTableImpl {
}
}

pub unsafe fn set_page_table(vmtoken: usize) {
#[cfg(target_arch = "riscv32")]
let mode = satp::Mode::Sv32;
#[cfg(target_arch = "riscv64")]
let mode = satp::Mode::Sv39;
satp::set(mode, 0, vmtoken >> 12);
}

trait FlagsExt {
fn to_ptf(self) -> PTF;
}
Expand All @@ -104,6 +114,9 @@ impl FlagsExt for MMUFlags {
if self.contains(MMUFlags::EXECUTE) {
flags |= PTF::EXECUTABLE;
}
if self.contains(MMUFlags::USER) {
flags |= PTF::USER;
}
flags
}
}
Expand All @@ -127,3 +140,5 @@ impl FrameDeallocator for FrameAllocatorImpl {
.dealloc()
}
}

pub fn init() {}
75 changes: 47 additions & 28 deletions kernel-hal-bare/src/arch/x86_64.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use {
super::*,
apic::{LocalApic, XApic},
bitflags::bitflags,
core::fmt::{Arguments, Write},
spin::Mutex,
uart_16550::SerialPort,
x86_64::{
registers::control::Cr3,
registers::control::{Cr3, Cr3Flags},
structures::paging::{PageTableFlags as PTF, *},
},
};
Expand All @@ -31,7 +30,7 @@ impl PageTableImpl {
let root_vaddr = phys_to_virt(root_frame.paddr);
let root = unsafe { &mut *(root_vaddr as *mut PageTable) };
root.zero();
map_kernel(root_vaddr as _);
map_kernel(root_vaddr as _, frame_to_page_table(Cr3::read().0) as _);
trace!("create page table @ {:#x}", root_frame.paddr);
PageTableImpl {
root_paddr: root_frame.paddr,
Expand All @@ -49,9 +48,13 @@ impl PageTableImpl {
let mut pt = self.get();
let page = Page::<Size4KiB>::from_start_address(vaddr).unwrap();
let frame = unsafe { UnusedPhysFrame::new(PhysFrame::from_start_address(paddr).unwrap()) };
pt.map_to(page, frame, flags.to_ptf(), &mut FrameAllocatorImpl)
.unwrap()
.flush();
let flush = pt
.map_to(page, frame, flags.to_ptf(), &mut FrameAllocatorImpl)
.unwrap();
if flags.contains(MMUFlags::USER) {
self.allow_user_access(vaddr);
}
flush.flush();
trace!("map: {:x?} -> {:x?}, flags={:?}", vaddr, paddr, flags);
Ok(())
}
Expand All @@ -71,7 +74,11 @@ impl PageTableImpl {
pub fn protect(&mut self, vaddr: x86_64::VirtAddr, flags: MMUFlags) -> Result<(), ()> {
let mut pt = self.get();
let page = Page::<Size4KiB>::from_start_address(vaddr).unwrap();
pt.update_flags(page, flags.to_ptf()).unwrap().flush();
let flush = pt.update_flags(page, flags.to_ptf()).unwrap();
if flags.contains(MMUFlags::USER) {
self.allow_user_access(vaddr);
}
flush.flush();
trace!("protect: {:x?}, flags={:?}", vaddr, flags);
Ok(())
}
Expand All @@ -91,26 +98,38 @@ impl PageTableImpl {
let offset = x86_64::VirtAddr::new(phys_to_virt(0) as u64);
unsafe { OffsetPageTable::new(root, offset) }
}

/// Set user bit for 4-level PDEs of the page of `vaddr`.
///
/// This is a workaround since `x86_64` crate does not set user bit for PDEs.
fn allow_user_access(&mut self, vaddr: x86_64::VirtAddr) {
let mut page_table = phys_to_virt(self.root_paddr) as *mut PageTable;
for level in 0..4 {
let index = (vaddr.as_u64() as usize >> (12 + (3 - level) * 9)) & 0o777;
let entry = unsafe { &mut (&mut *page_table)[index] };
let flags = entry.flags();
entry.set_flags(flags | PTF::USER_ACCESSIBLE);
if level == 3 || flags.contains(PTF::HUGE_PAGE) {
return;
}
page_table = frame_to_page_table(entry.frame().unwrap());
}
}
}

pub fn kernel_root_table() -> &'static PageTable {
unsafe { &*frame_to_page_table(Cr3::read().0) }
#[allow(clippy::missing_safety_doc)]
pub unsafe fn set_page_table(vmtoken: usize) {
Cr3::write(
PhysFrame::containing_address(x86_64::PhysAddr::new(vmtoken as _)),
Cr3Flags::empty(),
);
}

fn frame_to_page_table(frame: PhysFrame) -> *mut PageTable {
let vaddr = phys_to_virt(frame.start_address().as_u64() as usize);
vaddr as *mut PageTable
}

bitflags! {
pub struct MMUFlags: usize {
#[allow(clippy::identity_op)]
const READ = 1 << 0;
const WRITE = 1 << 1;
const EXECUTE = 1 << 2;
}
}

trait FlagsExt {
fn to_ptf(self) -> PTF;
}
Expand All @@ -127,6 +146,9 @@ impl FlagsExt for MMUFlags {
if !self.contains(MMUFlags::EXECUTE) {
flags |= PTF::NO_EXECUTE;
}
if self.contains(MMUFlags::USER) {
flags |= PTF::USER_ACCESSIBLE;
}
flags
}
}
Expand Down Expand Up @@ -154,23 +176,15 @@ impl FrameDeallocator<Size4KiB> for FrameAllocatorImpl {
static COM1: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });

pub fn putfmt(fmt: Arguments) {
unsafe {
COM1.force_unlock();
}
COM1.lock().write_fmt(fmt).unwrap();
}

#[export_name = "hal_serial_write"]
pub fn serial_write(s: &str) {
unsafe {
COM1.force_unlock();
}
for byte in s.bytes() {
COM1.lock().send(byte);
}
COM1.lock().write_str(s).unwrap();
}

pub fn timer_init() {
fn timer_init() {
let mut lapic = unsafe { XApic::new(phys_to_virt(LAPIC_ADDR)) };
lapic.cpu_init();
}
Expand All @@ -180,3 +194,8 @@ pub fn ack(_irq: u8) {
let mut lapic = unsafe { XApic::new(phys_to_virt(LAPIC_ADDR)) };
lapic.eoi();
}

/// Initialize the HAL.
pub fn init() {
timer_init();
}
104 changes: 97 additions & 7 deletions kernel-hal-bare/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,113 @@ extern crate log;

extern crate alloc;

use alloc::boxed::Box;
use alloc::sync::Arc;
use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use kernel_hal::defs::*;

pub mod arch;

#[allow(improper_ctypes)]
extern "C" {
fn hal_pt_map_kernel(pt: *mut u8);
fn hal_pt_map_kernel(pt: *mut u8, current: *const u8);
fn hal_frame_alloc() -> Option<PhysAddr>;
fn hal_frame_dealloc(paddr: &PhysAddr);
#[link_name = "hal_pmem_base"]
static PMEM_BASE: usize;
}

#[repr(C)]
pub struct Thread {
thread: usize,
}

impl Thread {
#[export_name = "hal_thread_spawn"]
pub fn spawn(thread: Arc<usize>, regs: GeneralRegs, vmtoken: usize) -> Self {
struct PageTableSwitchWrapper<F: Future> {
inner: F,
vmtoken: usize,
}
impl<F: Future> Future for PageTableSwitchWrapper<F> {
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unsafe {
arch::set_page_table(self.vmtoken);
}
let inner: Pin<&mut F> =
unsafe { core::mem::transmute(&mut self.get_unchecked_mut().inner) };
inner.poll(cx)
}
}

let future = async move {
thread_set_state(&thread, &regs);
let mut context = trapframe::UserContext {
// safety: same structure
general: unsafe { core::mem::transmute(regs) },
..Default::default()
};
loop {
// 判断线程状态是否是RUNNABLE,不是则返回Pending
unsafe {
thread_check_runnable(&thread).await;
}
context.run();
if context.error_code != 0 {
panic!("{:#x?}", context);
}
assert_eq!(context.trap_num, 0x100, "user interrupt still no support");
let exit = unsafe { handle_syscall(&thread, &mut context.general).await };
if exit {
break;
}
}
};
executor::spawn(PageTableSwitchWrapper {
inner: future,
vmtoken,
});
Thread { thread: 0 }
}
}

#[linkage = "weak"]
#[no_mangle]
extern "C" fn handle_syscall(
_thread: &Arc<usize>,
_regs: &mut trapframe::GeneralRegs,
) -> Pin<Box<dyn Future<Output = bool> + Send>> {
// exit by default
Box::pin(async { true })
}

#[linkage = "weak"]
#[export_name = "thread_set_state"]
pub fn thread_set_state(_thread: &Arc<usize>, _state: &GeneralRegs) {
unimplemented!()
}

/// Check whether a thread is runnable
#[linkage = "weak"]
#[no_mangle]
extern "C" fn thread_check_runnable(
_thread: &Arc<usize>,
) -> Pin<Box<dyn Future<Output = ()> + Send>> {
Box::pin(async {})
}

/// Map kernel for the new page table.
///
/// `pt` is a page-aligned pointer to the root page table.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn map_kernel(pt: *mut u8) {
pub fn map_kernel(pt: *mut u8, current: *const u8) {
unsafe {
hal_pt_map_kernel(pt);
hal_pt_map_kernel(pt, current);
}
}

Expand Down Expand Up @@ -85,16 +172,19 @@ pub fn pmem_write(paddr: PhysAddr, buf: &[u8]) {
}

/// Initialize the HAL.
///
/// Call this anywhere to ensure this lib being linked.
pub fn init() {}
pub fn init() {
unsafe {
trapframe::init();
}
arch::init();
}

#[cfg(test)]
mod tests {
use super::*;

#[no_mangle]
extern "C" fn hal_pt_map_kernel(_pt: *mut u8) {
extern "C" fn hal_pt_map_kernel(_pt: *mut u8, _current: *const u8) {
unimplemented!()
}

Expand Down
Loading