#![no_std]
#![no_main]
#![deny(missing_docs)]
#![deny(warnings)]
#![feature(never_type)]
#![feature(extract_if)]
#![feature(const_trait_impl)]
use ::fs::file::File;
use common::{config::DEFAULT_SERVE_EP, root::shutdown};
use futures::task::LocalSpawnExt;
use libc_core::fcntl::OpenFlags;
use crate::{
child_test::TASK_MAP,
consts::task::{VDSO_AREA_SIZE, VDSO_KADDR},
timer::handle_timer,
utils::{blk::get_blk_dev, obj::OBJ_ALLOCATOR},
};
#[macro_use]
extern crate log;
#[macro_use]
extern crate alloc;
#[cfg(not(fs_ipc))]
extern crate lwext4_thread;
#[cfg(not(uart_ipc))]
extern crate uart_thread;
#[macro_use]
pub mod rasync;
mod child_test;
mod logging;
pub mod arch;
pub mod consts;
pub mod device;
pub mod exception;
pub mod fs;
pub mod syscall;
pub mod task;
pub mod timer;
pub mod utils;
pub mod vdso;
macro_rules! test_task {
($file:expr $(,$args:expr)*) => {{
let file =
::fs::file::File::open(concat!("/", $file), OpenFlags::RDONLY).unwrap();
let mut data = vec![0u8; file.file_size().unwrap()];
file.read(&mut data).unwrap();
child_test::add_test_child(&data, &[$file $(,$args)*]).unwrap();
sel4::debug_println!("loading file: {}", $file);
drop(data);
}};
}
const DEF_HEAP_SIZE: usize = 0x380_0000;
sel4_runtime::define_heap!(DEF_HEAP_SIZE);
#[sel4_runtime::main]
fn main() {
common::slot::init_slot_edge_handler(|slot| {
OBJ_ALLOCATOR.extend_slot(slot);
});
logging::init();
utils::obj::init();
::fs::dentry::mount_fs(ext4fs::Ext4FileSystem::new(get_blk_dev()), "/");
::fs::dentry::mount_fs(allocfs::AllocFS::new(), "/tmp");
::fs::dentry::mount_fs(fs::devfs::DevFS::new(), "/dev");
::fs::dentry::mount_fs(allocfs::AllocFS::new(), "/var");
::fs::dentry::mount_fs(allocfs::AllocFS::new(), "/dev/shm");
device::init();
exception::init();
timer::init();
{
vdso::init_vdso_addr();
let vdso = File::open("/vdso.so", OpenFlags::RDONLY).unwrap();
let vdso_size = vdso
.read(unsafe { core::slice::from_raw_parts_mut(VDSO_KADDR as _, VDSO_AREA_SIZE) })
.unwrap();
assert!(vdso_size > 0);
}
test_task!("busybox", "sh", "/init.sh");
let mut pool = sel4_async_single_threaded_executor::LocalPool::new();
let spawner = pool.spawner();
loop {
{
if !TASK_MAP.lock().iter().any(|x| x.1.exit.lock().is_none()) {
sel4::debug_println!("\n\n **** rel4-linux-kit **** \nsystem run done😸🎆🎆🎆");
shutdown();
}
}
let (message, tid) = DEFAULT_SERVE_EP.recv(());
match tid {
u64::MAX => handle_timer(),
_ => spawner
.spawn_local(exception::waiting_and_handle(tid, message))
.unwrap(),
};
let _ = pool.run_all_until_stalled();
}
}