#![cfg_attr(feature = "axstd", no_std)]
#![cfg_attr(feature = "axstd", no_main)]
#[cfg(feature = "axstd")]
extern crate axstd as std;
#[cfg(feature = "axstd")]
extern crate alloc;
#[cfg(feature = "axstd")]
#[macro_use]
extern crate axlog;
#[cfg(feature = "axstd")]
extern crate axfs;
#[cfg(feature = "axstd")]
extern crate axio;
#[cfg(feature = "axstd")]
mod loader;
#[cfg(feature = "axstd")]
mod syscall;
#[cfg(feature = "axstd")]
mod task;
#[cfg(feature = "axstd")]
const USER_STACK_SIZE: usize = 0x10000;
#[cfg(feature = "axstd")]
const KERNEL_STACK_SIZE: usize = 0x40000;
#[cfg_attr(feature = "axstd", unsafe(no_mangle))]
fn main() {
#[cfg(feature = "axstd")]
{
use alloc::string::String;
use axhal::paging::MappingFlags;
use memory_addr::va;
let mut uspace = axmm::new_user_aspace(va!(0x0), 0x40_0000_0000).unwrap();
uspace
.copy_mappings_from(&axmm::kernel_aspace().lock())
.unwrap();
let entry = match loader::load_user_app("/sbin/hello", &mut uspace) {
Ok(e) => e,
Err(err) => panic!("Cannot load app! {:?}", err),
};
ax_println!("entry: {:#x}", entry);
let ustack_top = uspace.end();
let ustack_vaddr = ustack_top - USER_STACK_SIZE;
ax_println!(
"Mapping user stack: {:#x?} -> {:#x?}",
ustack_vaddr,
ustack_top
);
uspace
.map_alloc(
ustack_vaddr,
USER_STACK_SIZE,
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::USER,
true,
)
.unwrap();
let app_name = "hello";
let stack_data = kernel_elf_parser::app_stack_region(
&[String::from(app_name)],
&[],
&[],
ustack_top.as_usize(),
);
let ustack_pointer = ustack_top.as_usize() - stack_data.len();
uspace
.write(ustack_pointer.into(), stack_data.as_slice())
.unwrap();
ax_println!("New user address space: {:#x?}", uspace);
let user_task = task::spawn_user_task(uspace, entry, ustack_pointer.into());
let exit_code = user_task.join();
ax_println!("monolithic kernel exit [{:?}] normally!", Some(exit_code));
}
#[cfg(not(feature = "axstd"))]
{
println!("This application requires the 'axstd' feature for running Linux apps.");
println!("Run with: cargo xtask run [--arch <ARCH>]");
}
}