forked from rcore-os/zCore
Move the ziron libos entry point to zCore directory
This commit is contained in:
parent
806c9d104b
commit
169088dc31
|
@ -47,7 +47,6 @@ jobs:
|
|||
with:
|
||||
crate: cargo-binutils
|
||||
version: latest
|
||||
use-tool-cache: true
|
||||
- name: Build linux LibOS
|
||||
run: cargo build --features "linux libos"
|
||||
- name: Build zircon LibOS
|
||||
|
@ -257,7 +256,6 @@ jobs:
|
|||
with:
|
||||
crate: cargo-binutils
|
||||
version: latest
|
||||
use-tool-cache: true
|
||||
- name: Install cargo tools and qemu-system-riscv64
|
||||
run: |
|
||||
sudo apt update
|
||||
|
|
|
@ -44,9 +44,17 @@ pub struct U128(pub [u64; 2]);
|
|||
|
||||
impl fmt::Debug for U128 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:#016x}{:016x}", self.0[1], self.0[0])
|
||||
write!(f, "{:#016x}_{:016x}", self.0[1], self.0[0])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "libos")]
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "libos")] {
|
||||
pub use trapframe::syscall_fn_entry as syscall_entry;
|
||||
} else {
|
||||
pub use dummpy_syscall_entry as syscall_entry;
|
||||
pub fn dummpy_syscall_entry() {
|
||||
unreachable!("dummpy_syscall_entry")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,6 @@ use crate::{KernelConfig, KernelHandler, KCONFIG, KHANDLER};
|
|||
|
||||
hal_fn_impl! {
|
||||
impl mod crate::hal_fn::boot {
|
||||
fn cmdline() -> String {
|
||||
let root_proc = std::env::args().skip(1).collect::<Vec<_>>().join("?");
|
||||
let mut cmdline = format!("ROOTPROC={}", root_proc);
|
||||
if let Ok(level) = std::env::var("LOG") {
|
||||
cmdline += &format!(":LOG={}", level);
|
||||
}
|
||||
cmdline
|
||||
}
|
||||
|
||||
fn primary_init_early(cfg: KernelConfig, handler: &'static impl KernelHandler) {
|
||||
KCONFIG.init_once_by(cfg);
|
||||
KHANDLER.init_once_by(handler);
|
||||
|
|
|
@ -5,10 +5,12 @@ use std::path::Path;
|
|||
async fn main() {
|
||||
env_logger::init();
|
||||
kernel_hal::init();
|
||||
|
||||
let args = env::args().skip(1).collect();
|
||||
let envs = vec!["PATH=/usr/sbin:/usr/bin:/sbin:/bin".into()];
|
||||
let rootfs_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("../rootfs");
|
||||
let hostfs = rcore_fs_hostfs::HostFS::new(rootfs_path);
|
||||
|
||||
let proc = linux_loader::run(args, envs, hostfs);
|
||||
let code = proc.wait_for_exit().await;
|
||||
std::process::exit(code as i32);
|
||||
|
|
|
@ -35,10 +35,7 @@ pub fn run(args: Vec<String>, envs: Vec<String>, rootfs: Arc<dyn FileSystem>) ->
|
|||
let proc = Process::create_linux(&job, rootfs.clone()).unwrap();
|
||||
let thread = Thread::create_linux(&proc).unwrap();
|
||||
let loader = LinuxElfLoader {
|
||||
#[cfg(feature = "libos")]
|
||||
syscall_entry: kernel_hal::context::syscall_entry as usize,
|
||||
#[cfg(not(feature = "libos"))]
|
||||
syscall_entry: 0,
|
||||
stack_pages: 8,
|
||||
root_inode: rootfs.root_inode(),
|
||||
};
|
||||
|
@ -181,10 +178,7 @@ async fn handle_syscall(thread: &CurrentThread, regs: &mut GeneralRegs) {
|
|||
let args = [regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9];
|
||||
let mut syscall = Syscall {
|
||||
thread,
|
||||
#[cfg(feature = "libos")]
|
||||
syscall_entry: kernel_hal::context::syscall_entry as usize,
|
||||
#[cfg(not(feature = "libos"))]
|
||||
syscall_entry: 0,
|
||||
thread_fn,
|
||||
regs,
|
||||
};
|
||||
|
@ -211,10 +205,7 @@ async fn handle_syscall(thread: &CurrentThread, cx: &mut UserContext) {
|
|||
|
||||
let mut syscall = Syscall {
|
||||
thread,
|
||||
#[cfg(feature = "libos")]
|
||||
syscall_entry: kernel_hal::context::syscall_entry as usize,
|
||||
#[cfg(not(feature = "libos"))]
|
||||
syscall_entry: 0,
|
||||
context: cx,
|
||||
thread_fn,
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ def print_cases(cases, file=None):
|
|||
print(case, file=file)
|
||||
|
||||
|
||||
subprocess.run("cd .. && cargo build -p zcore --release --features 'libos linux'",
|
||||
subprocess.run("cd .. && cargo build -p zcore --release --features 'linux libos'",
|
||||
shell=True, check=True)
|
||||
|
||||
for path in sorted(glob.glob("../rootfs/libc-test/src/*/*.exe")):
|
||||
|
|
|
@ -5,15 +5,15 @@ import argparse
|
|||
|
||||
TIMEOUT = 300
|
||||
ZIRCON_LOADER_PATH = 'zircon-loader'
|
||||
PREBUILT_PATH = '../prebuilt/zircon/x64'
|
||||
ZBI_PATH = '../prebuilt/zircon/x64/core-tests.zbi'
|
||||
CMDLINE_BASE = 'LOG=warn:userboot=test/core-standalone-test:userboot.shutdown:core-tests='
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('testcase', nargs=1)
|
||||
args = parser.parse_args()
|
||||
|
||||
child = pexpect.spawn("cargo run -p '%s' -- '%s' '%s' --debug " %
|
||||
(ZIRCON_LOADER_PATH, PREBUILT_PATH, CMDLINE_BASE+args.testcase[0]),
|
||||
child = pexpect.spawn("cargo run -p zcore --features 'zircon libos' -- '%s' '%s'" %
|
||||
(ZBI_PATH, CMDLINE_BASE+args.testcase[0]),
|
||||
timeout=TIMEOUT, encoding='utf-8')
|
||||
|
||||
child.logfile = sys.stdout
|
||||
|
|
|
@ -11,7 +11,7 @@ RESULT_FILE = BASE + 'test-result-libos.txt'
|
|||
CHECK_FILE = BASE + 'test-check-passed.txt'
|
||||
TEST_CASE_ALL = BASE + 'testcases-all.txt'
|
||||
TEST_CASE_EXCEPTION = BASE + 'testcases-failed-libos.txt'
|
||||
PREBUILT_PATH = '../prebuilt/zircon/x64'
|
||||
ZBI_PATH = '../prebuilt/zircon/x64/core-tests.zbi'
|
||||
CMDLINE_BASE = 'LOG=warn:userboot=test/core-standalone-test:userboot.shutdown:core-tests='
|
||||
|
||||
class Tee:
|
||||
|
@ -41,8 +41,8 @@ with open(TEST_CASE_EXCEPTION, "r") as tcf:
|
|||
check_case = all_case - exception_case
|
||||
|
||||
for line in check_case:
|
||||
child = pexpect.spawn("cargo run -p '%s' -- '%s' '%s' --debug" %
|
||||
(ZIRCON_LOADER_PATH, PREBUILT_PATH, CMDLINE_BASE+line),
|
||||
child = pexpect.spawn("cargo run -p zcore --features 'zircon libos' -- '%s' '%s'" %
|
||||
(ZBI_PATH, CMDLINE_BASE+line),
|
||||
timeout=TIMEOUT, encoding='utf-8')
|
||||
|
||||
child.logfile = Tee(OUTPUT_FILE, 'a')
|
||||
|
|
|
@ -24,7 +24,7 @@ link_user_img = ["init_ram_disk"]
|
|||
zircon = ["zircon-loader"]
|
||||
linux = ["linux-loader", "linux-object", "rcore-fs", "rcore-fs-sfs"]
|
||||
|
||||
libos = ["async-std", "chrono", "rcore-fs-hostfs", "linux-loader/libos"]
|
||||
libos = ["async-std", "chrono", "rcore-fs-hostfs", "linux-loader/libos", "zircon-loader/libos"]
|
||||
board_qemu = []
|
||||
board_d1 = ["link_user_img"]
|
||||
|
||||
|
|
|
@ -8,21 +8,44 @@ LINUX ?=
|
|||
LIBOS ?=
|
||||
GRAPHIC ?=
|
||||
HYPERVISOR ?=
|
||||
SMP ?= 1
|
||||
ACCEL ?=
|
||||
V ?=
|
||||
|
||||
USER ?=
|
||||
ZBI ?= bringup
|
||||
CMDLINE ?=
|
||||
ARGS ?= /bin/busybox
|
||||
|
||||
SMP ?= 1
|
||||
ACCEL ?=
|
||||
|
||||
OBJDUMP ?= rust-objdump --print-imm-hex --x86-asm-syntax=intel
|
||||
OBJCOPY ?= rust-objcopy --binary-architecture=$(ARCH)
|
||||
|
||||
ifeq ($(LINUX), 1)
|
||||
user_img := $(ARCH).img
|
||||
else ifeq ($(USER), 1)
|
||||
user_img := ../zircon-user/target/zcore-user.zbi
|
||||
else
|
||||
user_img := ../prebuilt/zircon/x64/$(ZBI).zbi
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), libos)
|
||||
LIBOS := 1
|
||||
endif
|
||||
ifeq ($(LIBOS), 1)
|
||||
build_path := ../target/$(MODE)
|
||||
PLATFORM := libos
|
||||
ifeq ($(LINUX), 1)
|
||||
ARGS ?= /bin/busybox
|
||||
else
|
||||
ARGS ?= $(user_img) $(CMDLINE)
|
||||
endif
|
||||
else
|
||||
build_path := ../target/$(ARCH)/$(MODE)
|
||||
endif
|
||||
|
||||
################ Internal variables ################
|
||||
|
||||
qemu := qemu-system-$(ARCH)
|
||||
build_path := ../target/$(ARCH)/$(MODE)
|
||||
kernel_elf := $(build_path)/zcore
|
||||
kernel_img := $(build_path)/zcore.bin
|
||||
esp := $(build_path)/esp
|
||||
|
@ -35,13 +58,6 @@ else
|
|||
sed := sed -i
|
||||
endif
|
||||
|
||||
ifeq ($(LINUX), 1)
|
||||
user_img := $(ARCH).img
|
||||
else ifeq ($(USER), 1)
|
||||
user_img := ../zircon-user/target/zcore-user.zbi
|
||||
else
|
||||
user_img := ../prebuilt/zircon/x64/$(ZBI).zbi
|
||||
endif
|
||||
|
||||
################ Export environments ###################
|
||||
|
||||
|
@ -57,10 +73,6 @@ else
|
|||
features := zircon
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), libos)
|
||||
LIBOS := 1
|
||||
endif
|
||||
|
||||
ifeq ($(LIBOS), 1)
|
||||
ifneq ($(ARCH), $(shell uname -m))
|
||||
$(error "ARCH" must be "$(shell uname -m)" for libos mode)
|
||||
|
@ -170,7 +182,7 @@ run:
|
|||
test:
|
||||
cargo test $(build_args)
|
||||
debug: build
|
||||
gdb --args ../target/$(MODE)/zcore $(ARGS)
|
||||
gdb --args $(kernel_elf) $(ARGS)
|
||||
else
|
||||
build: $(kernel_img)
|
||||
run: build justrun
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[allow(dead_code)]
|
||||
pub fn init_ram_disk() -> &'static mut [u8] {
|
||||
fn init_ram_disk() -> &'static mut [u8] {
|
||||
if cfg!(feature = "link_user_img") {
|
||||
extern "C" {
|
||||
fn _user_img_start();
|
||||
|
@ -33,8 +33,8 @@ cfg_if! {
|
|||
|
||||
#[cfg(not(feature = "libos"))]
|
||||
pub fn rootfs() -> Arc<dyn FileSystem> {
|
||||
use linux_object::fs::rcore_fs_wrapper::{Block, BlockCache, MemBuf};
|
||||
use rcore_fs::dev::Device;
|
||||
use linux_object::fs::rcore_fs_wrapper::{MemBuf, Block, BlockCache};
|
||||
|
||||
let device: Arc<dyn Device> = if cfg!(feature = "init_ram_disk") {
|
||||
Arc::new(MemBuf::new(init_ram_disk()))
|
||||
|
@ -45,6 +45,22 @@ cfg_if! {
|
|||
info!("Opening the rootfs...");
|
||||
rcore_fs_sfs::SimpleFileSystem::open(device).expect("failed to open device SimpleFS")
|
||||
}
|
||||
} else if #[cfg(feature = "zircon")] {
|
||||
|
||||
#[cfg(feature = "libos")]
|
||||
pub fn zbi() -> impl AsRef<[u8]> {
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
if args.len() < 2 {
|
||||
println!("Usage: {} ZBI_FILE [CMDLINE]", args[0]);
|
||||
std::process::exit(-1);
|
||||
}
|
||||
std::fs::read(&args[1]).expect("failed to read zbi file")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "libos"))]
|
||||
pub fn zbi() -> impl AsRef<[u8]> {
|
||||
init_ram_disk()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,30 +27,23 @@ fn primary_main(config: kernel_hal::KernelConfig) {
|
|||
memory::init_heap();
|
||||
kernel_hal::primary_init_early(config, &handler::ZcoreKernelHandler);
|
||||
|
||||
let cmdline = kernel_hal::boot::cmdline();
|
||||
let boot_options = utils::parse_cmdline(&cmdline);
|
||||
logging::set_max_level(boot_options.get("LOG").unwrap_or(&""));
|
||||
info!("Boot options: {:#?}", boot_options);
|
||||
let options = utils::boot_options();
|
||||
logging::set_max_level(&options.log_level);
|
||||
info!("Boot options: {:#?}", options);
|
||||
|
||||
memory::init_frame_allocator(&kernel_hal::mem::free_pmem_regions());
|
||||
kernel_hal::primary_init();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "linux")] {
|
||||
let args = boot_options
|
||||
.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")
|
||||
.split('?').map(Into::into).collect(); // parse "arg0?arg1?arg2"
|
||||
let args = options.root_proc.split('?').map(Into::into).collect(); // parse "arg0?arg1?arg2"
|
||||
let envs = alloc::vec!["PATH=/usr/sbin:/usr/bin:/sbin:/bin".into()];
|
||||
let rootfs = fs::rootfs();
|
||||
let proc = linux_loader::run(args, envs, rootfs);
|
||||
utils::wait_for_exit(Some(proc))
|
||||
} else if #[cfg(feature = "zircon")] {
|
||||
let images = zircon_loader::Images::<&[u8]> {
|
||||
userboot: include_bytes!("../../prebuilt/zircon/x64/userboot.so"),
|
||||
vdso: include_bytes!("../../prebuilt/zircon/x64/libzircon.so"),
|
||||
zbi: fs::init_ram_disk(),
|
||||
};
|
||||
let proc = zircon_loader::run_userboot(&images, &cmdline);
|
||||
let zbi = fs::zbi();
|
||||
let proc = zircon_loader::run_userboot(zbi, &options.cmdline);
|
||||
utils::wait_for_exit(Some(proc))
|
||||
} else {
|
||||
panic!("One of the features `linux` or `zircon` must be specified!");
|
||||
|
|
|
@ -1,27 +1,80 @@
|
|||
use alloc::{collections::BTreeMap, sync::Arc};
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
use alloc::{collections::BTreeMap, string::String, sync::Arc};
|
||||
use zircon_object::task::Process;
|
||||
|
||||
pub type BootOptions<'a> = BTreeMap<&'a str, &'a str>;
|
||||
#[derive(Debug)]
|
||||
pub struct BootOptions {
|
||||
pub cmdline: String,
|
||||
pub log_level: String,
|
||||
#[cfg(feature = "linux")]
|
||||
pub root_proc: String,
|
||||
}
|
||||
|
||||
pub fn parse_cmdline(cmdline: &str) -> BootOptions {
|
||||
let mut args = BootOptions::new();
|
||||
fn parse_cmdline(cmdline: &str) -> BTreeMap<&str, &str> {
|
||||
let mut options = BTreeMap::new();
|
||||
for opt in cmdline.split(':') {
|
||||
// parse "key=value"
|
||||
let mut iter = opt.trim().splitn(2, '=');
|
||||
if let Some(key) = iter.next() {
|
||||
if let Some(value) = iter.next() {
|
||||
args.insert(key.trim(), value.trim());
|
||||
options.insert(key.trim(), value.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
options
|
||||
}
|
||||
|
||||
pub fn boot_options() -> BootOptions {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "libos")] {
|
||||
let log_level = std::env::var("LOG").unwrap_or_default();
|
||||
let cmdline = if cfg!(feature = "zircon") {
|
||||
std::env::args().nth(2).unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
BootOptions {
|
||||
cmdline,
|
||||
log_level,
|
||||
#[cfg(feature = "linux")]
|
||||
root_proc: std::env::args().skip(1).collect::<Vec<_>>().join("?"),
|
||||
}
|
||||
} else {
|
||||
let cmdline = kernel_hal::boot::cmdline();
|
||||
let options = parse_cmdline(&cmdline);
|
||||
BootOptions {
|
||||
cmdline: cmdline.clone(),
|
||||
log_level: String::from(*options.get("LOG").unwrap_or(&"")),
|
||||
#[cfg(feature = "linux")]
|
||||
root_proc: String::from(*options.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")),
|
||||
}
|
||||
}
|
||||
}
|
||||
args
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn wait_for_exit(proc: Option<Arc<Process>>) -> ! {
|
||||
#[cfg(feature = "libos")]
|
||||
if let Some(proc) = proc {
|
||||
let future = async move { proc.wait_for_exit().await };
|
||||
let future = async move {
|
||||
use zircon_object::object::{KernelObject, Signal};
|
||||
let object: Arc<dyn KernelObject> = proc.clone();
|
||||
let signal = if cfg!(feature = "zircon") {
|
||||
Signal::USER_SIGNAL_0
|
||||
} else {
|
||||
Signal::PROCESS_TERMINATED
|
||||
};
|
||||
object.wait_signal(signal).await;
|
||||
let code = proc.exit_code().unwrap_or(-1);
|
||||
info!(
|
||||
"process {:?}({}) exited with code {:?}",
|
||||
proc.name(),
|
||||
proc.id(),
|
||||
code
|
||||
);
|
||||
code
|
||||
};
|
||||
|
||||
// If the graphic mode is on, run the process in another thread.
|
||||
#[cfg(feature = "graphic")]
|
||||
|
|
|
@ -9,15 +9,16 @@ description = "Zircon user program (userboot) loader"
|
|||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
cfg-if = "1.0"
|
||||
xmas-elf = "0.7"
|
||||
zircon-object = { path = "../zircon-object", features = ["elf"] }
|
||||
zircon-syscall = { path = "../zircon-syscall" }
|
||||
kernel-hal = { path = "../kernel-hal" }
|
||||
env_logger = { version = "0.8", optional = true }
|
||||
structopt = { version = "0.3", default-features = false, optional = true }
|
||||
async-std = { version = "1.10", features = ["attributes"], optional = true }
|
||||
|
||||
[features]
|
||||
default = ["std", "libos"]
|
||||
libos = ["kernel-hal/libos"]
|
||||
std = ["env_logger", "structopt", "async-std", "zircon-object/aspace-separate", "zircon-syscall/std"]
|
||||
default = ["libos"]
|
||||
libos = ["kernel-hal/libos", "zircon-object/aspace-separate", "zircon-syscall/std"]
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.9"
|
||||
async-std = { version = "1.10", features = ["attributes"] }
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
use std::sync::Arc;
|
||||
use zircon_object::object::{KernelObject, Signal};
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
env_logger::init();
|
||||
kernel_hal::init();
|
||||
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
if args.len() < 2 {
|
||||
println!("Usage: {} ZBI_FILE [CMDLINE]", args[0]);
|
||||
std::process::exit(-1);
|
||||
}
|
||||
|
||||
let zbi = std::fs::read(&args[1]).expect("failed to read zbi file");
|
||||
let cmdline = args.get(2).map(String::as_str).unwrap_or("");
|
||||
|
||||
let proc: Arc<dyn KernelObject> = zircon_loader::run_userboot(zbi, cmdline);
|
||||
proc.wait_signal(Signal::USER_SIGNAL_0).await;
|
||||
}
|
|
@ -32,14 +32,34 @@ const K_COUNTERS: usize = 10;
|
|||
const K_FISTINSTRUMENTATIONDATA: usize = 11;
|
||||
const K_HANDLECOUNT: usize = 15;
|
||||
|
||||
/// Program images to run.
|
||||
pub struct Images<T: AsRef<[u8]>> {
|
||||
pub userboot: T,
|
||||
pub vdso: T,
|
||||
pub zbi: T,
|
||||
macro_rules! boot_firmware {
|
||||
($name: expr) => {{
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_arch = "x86_64")] {
|
||||
boot_firmware!($name, "../../prebuilt/zircon/x64")
|
||||
} else if #[cfg(target_arch = "aarch64")] {
|
||||
boot_firmware!($name, "../../prebuilt/zircon/arm64")
|
||||
} else {
|
||||
compile_error!("Unsupported architecture for zircon mode!")
|
||||
}
|
||||
}
|
||||
}};
|
||||
($name: expr, $base_dir: expr) => {{
|
||||
#[cfg(feature = "libos")]
|
||||
{
|
||||
include_bytes!(concat!($base_dir, "/", $name, "-libos.so"))
|
||||
}
|
||||
#[cfg(not(feature = "libos"))]
|
||||
{
|
||||
include_bytes!(concat!($base_dir, "/", $name, ".so"))
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Process> {
|
||||
pub fn run_userboot(zbi: impl AsRef<[u8]>, cmdline: &str) -> Arc<Process> {
|
||||
let userboot = boot_firmware!("userboot");
|
||||
let vdso = boot_firmware!("libzircon");
|
||||
|
||||
let job = Job::root();
|
||||
let proc = Process::create(&job, "userboot").unwrap();
|
||||
let thread = Thread::create(&proc, "userboot").unwrap();
|
||||
|
@ -54,7 +74,7 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
|
|||
|
||||
// userboot
|
||||
let (entry, userboot_size) = {
|
||||
let elf = ElfFile::new(images.userboot.as_ref()).unwrap();
|
||||
let elf = ElfFile::new(userboot).unwrap();
|
||||
let size = elf.load_segment_size();
|
||||
let vmar = vmar
|
||||
.allocate(None, size, VmarFlags::CAN_MAP_RXW, PAGE_SIZE)
|
||||
|
@ -65,9 +85,9 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
|
|||
|
||||
// vdso
|
||||
let vdso_vmo = {
|
||||
let elf = ElfFile::new(images.vdso.as_ref()).unwrap();
|
||||
let vdso_vmo = VmObject::new_paged(images.vdso.as_ref().len() / PAGE_SIZE + 1);
|
||||
vdso_vmo.write(0, images.vdso.as_ref()).unwrap();
|
||||
let elf = ElfFile::new(vdso).unwrap();
|
||||
let vdso_vmo = VmObject::new_paged(vdso.len() / PAGE_SIZE + 1);
|
||||
vdso_vmo.write(0, vdso).unwrap();
|
||||
let size = elf.load_segment_size();
|
||||
let vmar = vmar
|
||||
.allocate_at(
|
||||
|
@ -78,7 +98,7 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
|
|||
)
|
||||
.unwrap();
|
||||
vmar.map_from_elf(&elf, vdso_vmo.clone()).unwrap();
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(feature = "libos")]
|
||||
{
|
||||
let offset = elf
|
||||
.get_symbol_address("zcore_syscall_entry")
|
||||
|
@ -94,8 +114,8 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
|
|||
|
||||
// zbi
|
||||
let zbi_vmo = {
|
||||
let vmo = VmObject::new_paged(images.zbi.as_ref().len() / PAGE_SIZE + 1);
|
||||
vmo.write(0, images.zbi.as_ref()).unwrap();
|
||||
let vmo = VmObject::new_paged(zbi.as_ref().len() / PAGE_SIZE + 1);
|
||||
vmo.write(0, zbi.as_ref()).unwrap();
|
||||
vmo.set_name("zbi");
|
||||
vmo
|
||||
};
|
||||
|
@ -267,7 +287,7 @@ async fn handle_syscall(thread: &CurrentThread) {
|
|||
#[cfg(target_arch = "aarch64")]
|
||||
let num = regs.x16 as u32;
|
||||
// LibOS: Function call ABI
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(feature = "libos")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let args = unsafe {
|
||||
let a6 = (regs.rsp as *const usize).read();
|
||||
|
@ -277,7 +297,7 @@ async fn handle_syscall(thread: &CurrentThread) {
|
|||
]
|
||||
};
|
||||
// RealOS: Zircon syscall ABI
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[cfg(not(feature = "libos"))]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let args = [
|
||||
regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9, regs.r12, regs.r13,
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
#![deny(warnings, unused_must_use)]
|
||||
|
||||
extern crate log;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use zircon_loader::*;
|
||||
use zircon_object::object::*;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt()]
|
||||
struct Opt {
|
||||
#[structopt(parse(from_os_str))]
|
||||
prebuilt_path: PathBuf,
|
||||
|
||||
#[structopt(default_value = "")]
|
||||
cmdline: String,
|
||||
|
||||
#[structopt(short, long)]
|
||||
debug: bool,
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
kernel_hal::init();
|
||||
init_logger();
|
||||
|
||||
let opt = Opt::from_args();
|
||||
let images = open_images(&opt.prebuilt_path, opt.debug).expect("failed to read file");
|
||||
let proc: Arc<dyn KernelObject> = run_userboot(&images, &opt.cmdline);
|
||||
drop(images);
|
||||
|
||||
proc.wait_signal(Signal::USER_SIGNAL_0).await;
|
||||
}
|
||||
|
||||
fn open_images(path: &Path, debug: bool) -> std::io::Result<Images<Vec<u8>>> {
|
||||
Ok(Images {
|
||||
userboot: std::fs::read(path.join("userboot-libos.so"))?,
|
||||
vdso: std::fs::read(path.join("libzircon-libos.so"))?,
|
||||
zbi: if debug {
|
||||
std::fs::read(path.join("core-tests.zbi"))?
|
||||
} else {
|
||||
std::fs::read(path.join("bringup.zbi"))?
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn init_logger() {
|
||||
env_logger::builder()
|
||||
.format(|buf, record| {
|
||||
use env_logger::fmt::Color;
|
||||
use log::Level;
|
||||
use std::io::Write;
|
||||
|
||||
let (tid, pid) = kernel_hal::thread::get_tid();
|
||||
let mut style = buf.style();
|
||||
match record.level() {
|
||||
Level::Trace => style.set_color(Color::Black).set_intense(true),
|
||||
Level::Debug => style.set_color(Color::White),
|
||||
Level::Info => style.set_color(Color::Green),
|
||||
Level::Warn => style.set_color(Color::Yellow),
|
||||
Level::Error => style.set_color(Color::Red).set_bold(true),
|
||||
};
|
||||
let now = kernel_hal::timer::timer_now();
|
||||
let level = style.value(record.level());
|
||||
let args = record.args();
|
||||
writeln!(buf, "[{:?} {:>5} {}:{}] {}", now, level, pid, tid, args)
|
||||
})
|
||||
.init();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[async_std::test]
|
||||
async fn userboot() {
|
||||
kernel_hal::init();
|
||||
|
||||
let opt = Opt {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
prebuilt_path: PathBuf::from("../prebuilt/zircon/x64"),
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
prebuilt_path: PathBuf::from("../prebuilt/zircon/arm64"),
|
||||
cmdline: String::from(""),
|
||||
debug: false,
|
||||
};
|
||||
let images = open_images(&opt.prebuilt_path, opt.debug).expect("failed to read file");
|
||||
|
||||
let proc: Arc<dyn KernelObject> = run_userboot(&images, &opt.cmdline);
|
||||
drop(images);
|
||||
|
||||
proc.wait_signal(Signal::PROCESS_TERMINATED).await;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#[cfg(target_arch = "x86_64")]
|
||||
#[async_std::test]
|
||||
async fn userboot() {
|
||||
kernel_hal::init();
|
||||
let zbi = std::fs::read("../prebuilt/zircon/x64/bringup.zbi").expect("failed to read zbi file");
|
||||
let proc = zircon_loader::run_userboot(zbi, "");
|
||||
proc.wait_for_exit().await;
|
||||
}
|
|
@ -294,6 +294,15 @@ impl Process {
|
|||
self.inner.lock().status
|
||||
}
|
||||
|
||||
/// Get process exit code if it exited, else returns `None`.
|
||||
pub fn exit_code(&self) -> Option<i64> {
|
||||
if let Status::Exited(code) = self.status() {
|
||||
Some(code)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the extension.
|
||||
pub fn ext(&self) -> &Box<dyn Any + Send + Sync> {
|
||||
&self.ext
|
||||
|
@ -529,7 +538,7 @@ impl Process {
|
|||
pub async fn wait_for_exit(self: &Arc<Self>) -> i64 {
|
||||
let object: Arc<dyn KernelObject> = self.clone();
|
||||
object.wait_signal(Signal::PROCESS_TERMINATED).await;
|
||||
if let Status::Exited(code) = self.status() {
|
||||
let code = self.exit_code().expect("process not exited!");
|
||||
info!(
|
||||
"process {:?}({}) exited with code {:?}",
|
||||
self.name(),
|
||||
|
@ -537,9 +546,6 @@ impl Process {
|
|||
code
|
||||
);
|
||||
code
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue