Merge crates zircon-loader and linux-loader into one crate

This commit is contained in:
Yuekai Jia 2021-10-26 23:27:19 +08:00
parent 91d57d4409
commit 78322d6f31
29 changed files with 138 additions and 129 deletions

View File

@ -69,7 +69,7 @@ jobs:
with:
command: build
use-cross: true
args: --target aarch64-unknown-linux-gnu --workspace --exclude linux-syscall --exclude linux-loader --exclude zcore
args: --target aarch64-unknown-linux-gnu --workspace --exclude linux-syscall --exclude zcore-loader --exclude zcore
build-user:
runs-on: ${{ matrix.os }}

View File

@ -15,10 +15,11 @@ jobs:
cat >target/doc/index.html <<EOF
<html>
<head>
<noscript><meta http-equiv="refresh" content="0; url=kernel_hal/index.html"></noscript>
<meta http-equiv="refresh" content="0;URL=kernel_hal/index.html">
<title>Redirection</title>
</head>
<body onload="window.location = 'kernel_hal/index.html'">
<a href="kernel_hal/index.html">look here</a>
<p>Redirecting to <a href="kernel_hal/index.html">kernel_hal/index.html</a>...</p>
</body>
</html>
EOF

View File

@ -1,13 +1,12 @@
[workspace]
members = [
"drivers",
"kernel-hal",
"zircon-object",
"zircon-syscall",
"zircon-loader",
"linux-object",
"linux-syscall",
"linux-loader",
"kernel-hal",
"drivers",
"loader",
"zCore",
]

View File

@ -3,6 +3,7 @@ cfg_if::cfg_if! {
mod riscv_intc;
mod riscv_plic;
#[doc(cfg(any(target_arch = "riscv32", target_arch = "riscv64")))]
pub mod riscv {
pub use super::riscv_intc::{Intc, ScauseIntCode};
pub use super::riscv_plic::Plic;
@ -10,6 +11,7 @@ cfg_if::cfg_if! {
} else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
mod x86_apic;
#[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
pub mod x86 {
pub use super::x86_apic::Apic;
}

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(feature = "mock"), no_std)]
#![feature(asm)]
#![feature(doc_cfg)]
extern crate alloc;
@ -9,10 +10,12 @@ extern crate log;
use alloc::sync::Arc;
use core::fmt;
#[cfg(feature = "mock")]
#[cfg(any(feature = "mock", doc))]
#[doc(cfg(feature = "mock"))]
pub mod mock;
#[cfg(feature = "virtio")]
#[cfg(any(feature = "virtio", doc))]
#[doc(cfg(feature = "virtio"))]
pub mod virtio;
pub mod builder;

View File

@ -2,5 +2,6 @@ pub mod display;
pub mod input;
pub mod uart;
#[cfg(feature = "graphic")]
#[cfg(any(feature = "graphic", doc))]
#[doc(cfg(feature = "graphic"))]
pub mod graphic;

View File

@ -8,7 +8,7 @@ hal_fn_def! {
/// Bootstrap and initialization.
pub mod boot {
/// The kernel command line.
pub fn cmdline() -> String { "".into() }
pub fn cmdline() -> String { String::new() }
/// Returns the slice of the initial RAM disk, or `None` if not exist.
pub fn init_ram_disk() -> Option<&'static mut [u8]> {

View File

@ -1,24 +0,0 @@
[package]
name = "linux-loader"
version = "0.1.0"
authors = ["Runji Wang <wangrunji0408@163.com>"]
edition = "2018"
description = "Linux programs loader and runner."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
linux-syscall = { path = "../linux-syscall" }
linux-object = { path = "../linux-object" }
zircon-object = { path = "../zircon-object" }
kernel-hal = { path = "../kernel-hal", default-features = false }
[features]
default = ["libos"]
libos = ["kernel-hal/libos", "zircon-object/aspace-separate"]
[dev-dependencies]
env_logger = "0.9"
async-std = { version = "1.10", features = ["attributes"] }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" }

View File

@ -28,7 +28,7 @@ impl LinuxElfLoader {
&self,
vmar: &Arc<VmAddressRegion>,
data: &[u8],
mut args: Vec<String>,
args: Vec<String>,
envs: Vec<String>,
path: String,
) -> LxResult<(VirtAddr, VirtAddr)> {
@ -45,12 +45,12 @@ impl LinuxElfLoader {
debug!("elf info: {:#x?}", elf.header.pt2);
if let Ok(interp) = elf.get_interpreter() {
info!("interp: {:?}", interp);
info!("interp: {:?}, path: {:?}", interp, path);
let inode = self.root_inode.lookup(interp)?;
let data = inode.read_as_vec()?;
args[0] = path.clone();
args.insert(0, interp.into());
return self.load(vmar, &data, args, envs, path);
let mut new_args = vec![interp.into(), path.clone()];
new_args.extend_from_slice(&args[1..]);
return self.load(vmar, &data, new_args, envs, path);
}
let size = elf.load_segment_size();

View File

@ -1,16 +1,13 @@
//! Linux syscall implementations
//!
//! ## Example
//! the syscall is called like this in the linux-loader:
//! The syscall is called like this in the [`zcore_loader`](../zcore_loader/index.html):
//! ```ignore
//! let num = regs.rax as u32;
//! 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,
//! };

37
loader/Cargo.toml Normal file
View File

@ -0,0 +1,37 @@
[package]
name = "zcore-loader"
version = "0.1.0"
authors = ["Runji Wang <wangrunji0408@163.com>", "Yuekai Jia <equation618@gmail.com>"]
edition = "2018"
description = "Linux and Zircon user programs loader and runner."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
cfg-if = "1.0"
xmas-elf = { version = "0.7", optional = true }
kernel-hal = { path = "../kernel-hal", default-features = false }
zircon-object = { path = "../zircon-object", features = ["elf"] }
linux-object = { path = "../linux-object", optional = true }
zircon-syscall = { path = "../zircon-syscall", optional = true }
linux-syscall = { path = "../linux-syscall", optional = true }
[features]
default = ["libos", "linux", "zircon"]
linux = ["linux-object", "linux-syscall"]
zircon = ["zircon-syscall", "xmas-elf"]
libos = ["kernel-hal/libos", "zircon-object/aspace-separate"]
[dev-dependencies]
env_logger = "0.9"
async-std = { version = "1.10", features = ["attributes"] }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" }
[[example]]
name = "linux-libos"
required-features = ["linux", "libos"]
[[example]]
name = "zircon-libos"
required-features = ["zircon", "libos"]

View File

@ -6,12 +6,17 @@ async fn main() {
env_logger::init();
kernel_hal::init();
let args = env::args().skip(1).collect();
let args = std::env::args().collect::<Vec<_>>();
if args.len() < 2 {
println!("Usage: {} PROGRAM", args[0]);
std::process::exit(-1);
}
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 proc = zcore_loader::linux::run(args[1..].to_vec(), envs, hostfs);
let code = proc.wait_for_exit().await;
std::process::exit(code as i32);
}

View File

@ -13,8 +13,8 @@ async fn main() {
}
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 cmdline = args.get(2).map(String::as_str).unwrap_or_default();
let proc: Arc<dyn KernelObject> = zircon_loader::run_userboot(zbi, cmdline);
let proc: Arc<dyn KernelObject> = zcore_loader::zircon::run_userboot(zbi, cmdline);
proc.wait_signal(Signal::USER_SIGNAL_0).await;
}

26
loader/src/lib.rs Normal file
View File

@ -0,0 +1,26 @@
//! Linux and Zircon user programs loader and runner.
#![no_std]
#![feature(asm)]
#![feature(doc_cfg)]
#![deny(warnings, unused_must_use, missing_docs)]
extern crate alloc;
#[macro_use]
extern crate log;
cfg_if::cfg_if! {
if #[cfg(any(feature = "linux", doc))] {
#[doc(cfg(feature = "linux"))]
pub mod linux;
}
}
cfg_if::cfg_if! {
if #[cfg(any(feature = "zircon", doc))] {
mod kcounter;
#[doc(cfg(feature = "zircon"))]
pub mod zircon;
}
}

View File

@ -1,12 +1,4 @@
//! Linux LibOS
//! - run process and manage trap/interrupt/syscall
#![no_std]
#![feature(asm)]
#![deny(warnings, unused_must_use, missing_docs)]
extern crate alloc;
#[macro_use]
extern crate log;
//! Run Linux process and manage trap/interrupt/syscall.
use {
alloc::{boxed::Box, string::String, sync::Arc, vec::Vec},

View File

@ -1,11 +1,4 @@
#![no_std]
#![feature(asm)]
#![deny(warnings, unused_must_use)]
#[macro_use]
extern crate alloc;
#[macro_use]
extern crate log;
//! Run Zircon user program (userboot) and manage trap/interrupt/syscall.
use {
alloc::{boxed::Box, sync::Arc, vec::Vec},
@ -15,8 +8,6 @@ use {
zircon_syscall::Syscall,
};
mod kcounter;
// These describe userboot itself
const K_PROC_SELF: usize = 0;
const K_VMARROOT_SELF: usize = 1;
@ -32,13 +23,13 @@ const K_COUNTERS: usize = 10;
const K_FISTINSTRUMENTATIONDATA: usize = 11;
const K_HANDLECOUNT: usize = 15;
macro_rules! boot_firmware {
macro_rules! boot_library {
($name: expr) => {{
cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")] {
boot_firmware!($name, "../../prebuilt/zircon/x64")
boot_library!($name, "../../prebuilt/zircon/x64")
} else if #[cfg(target_arch = "aarch64")] {
boot_firmware!($name, "../../prebuilt/zircon/arm64")
boot_library!($name, "../../prebuilt/zircon/arm64")
} else {
compile_error!("Unsupported architecture for zircon mode!")
}
@ -56,9 +47,10 @@ macro_rules! boot_firmware {
}};
}
/// Run Zircon `userboot` process from the prebuilt path, and load the ZBI file as the bootfs.
pub fn run_userboot(zbi: impl AsRef<[u8]>, cmdline: &str) -> Arc<Process> {
let userboot = boot_firmware!("userboot");
let vdso = boot_firmware!("libzircon");
let userboot = boot_library!("userboot");
let vdso = boot_library!("libzircon");
let job = Job::root();
let proc = Process::create(&job, "userboot").unwrap();
@ -137,7 +129,7 @@ pub fn run_userboot(zbi: impl AsRef<[u8]>, cmdline: &str) -> Arc<Process> {
let (user_channel, kernel_channel) = Channel::create();
let handle = Handle::new(user_channel, Rights::DEFAULT_CHANNEL);
let mut handles = vec![Handle::new(proc.clone(), Rights::empty()); K_HANDLECOUNT];
let mut handles = alloc::vec![Handle::new(proc.clone(), Rights::empty()); K_HANDLECOUNT];
handles[K_PROC_SELF] = Handle::new(proc.clone(), Rights::DEFAULT_PROCESS);
handles[K_VMARROOT_SELF] = Handle::new(proc.vmar(), Rights::DEFAULT_VMAR | Rights::IO);
handles[K_ROOTJOB] = Handle::new(job, Rights::DEFAULT_JOB);
@ -161,7 +153,7 @@ pub fn run_userboot(zbi: impl AsRef<[u8]>, cmdline: &str) -> Arc<Process> {
let crash_log_vmo = VmObject::new_paged(1);
crash_log_vmo.set_name("crashlog");
handles[K_CRASHLOG] = Handle::new(crash_log_vmo, Rights::DEFAULT_VMO);
let (counter_name_vmo, kcounters_vmo) = kcounter::create_kcounter_vmo();
let (counter_name_vmo, kcounters_vmo) = super::kcounter::create_kcounter_vmo();
handles[K_COUNTERNAMES] = Handle::new(counter_name_vmo, Rights::DEFAULT_VMO);
handles[K_COUNTERS] = Handle::new(kcounters_vmo, Rights::DEFAULT_VMO);
// TODO: use correct Instrumentation data handle

View File

@ -1,5 +1,3 @@
//! Linux LibOS entrance
use rcore_fs_hostfs::HostFS;
use std::fs;
@ -10,7 +8,7 @@ async fn test(cmdline: &str) -> i64 {
let args: Vec<String> = cmdline.split(' ').map(|s| s.into()).collect();
let envs = vec!["PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/x86_64-alpine-linux-musl/bin".into()]; // TODO
let hostfs = HostFS::new("../rootfs");
let proc = linux_loader::run(args, envs, hostfs);
let proc = zcore_loader::linux::run(args, envs, hostfs);
proc.wait_for_exit().await
}

View File

@ -3,6 +3,6 @@
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, "");
let proc = zcore_loader::zircon::run_userboot(zbi, "");
proc.wait_for_exit().await;
}

View File

@ -73,4 +73,4 @@ if check_failed:
else:
print(colored('All checked case passed!', 'green'))
os.system('killall linux-loader')
os.system('killall zcore')

View File

@ -4,7 +4,6 @@ import re
import argparse
TIMEOUT = 300
ZIRCON_LOADER_PATH = 'zircon-loader'
ZBI_PATH = '../prebuilt/zircon/x64/core-tests.zbi'
CMDLINE_BASE = 'LOG=warn:userboot=test/core-standalone-test:userboot.shutdown:core-tests='

View File

@ -5,7 +5,6 @@ import os
import subprocess
TIMEOUT = 300
ZIRCON_LOADER_PATH = 'zircon-loader'
BASE = 'zircon/'
OUTPUT_FILE = BASE + 'test-output-libos.txt'
RESULT_FILE = BASE + 'test-result-libos.txt'

View File

@ -1,7 +1,7 @@
[package]
name = "zcore"
version = "0.1.0"
authors = ["PanQL <panqinglin00@163.com>"]
authors = ["PanQL <panqinglin00@163.com>", "Yuekai Jia <equation618@gmail.com>"]
edition = "2018"
default-run = "zcore"
@ -21,10 +21,10 @@ graphic = ["kernel-hal/graphic"]
init-ram-disk = []
link-user-img = ["init-ram-disk"]
zircon = ["zircon-loader"]
linux = ["linux-loader", "linux-object", "rcore-fs", "rcore-fs-sfs"]
zircon = ["zcore-loader/zircon"]
linux = ["zcore-loader/linux", "linux-object", "rcore-fs", "rcore-fs-sfs"]
libos = ["async-std", "chrono", "rcore-fs-hostfs", "kernel-hal/libos", "linux-loader/libos", "zircon-loader/libos"]
libos = ["kernel-hal/libos", "zcore-loader/libos", "async-std", "chrono", "rcore-fs-hostfs"]
board-qemu = []
board-d1 = ["link-user-img"]
@ -35,10 +35,9 @@ cfg-if = "1.0"
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" }
kernel-hal = { path = "../kernel-hal", default-features = false, features = ["smp"] }
zcore-loader = { path = "../loader", default-features = false }
zircon-object = { path = "../zircon-object" }
linux-object = { path = "../linux-object", optional = true }
zircon-loader = { path = "../zircon-loader", default-features = false, optional = true }
linux-loader = { path = "../linux-loader", default-features = false, optional = true }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true }

View File

@ -1,4 +1,5 @@
#[allow(dead_code)]
#![allow(dead_code)]
fn init_ram_disk() -> &'static mut [u8] {
if cfg!(feature = "link-user-img") {
extern "C" {
@ -49,12 +50,8 @@ cfg_if! {
#[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")
let path = std::env::args().nth(1).unwrap();
std::fs::read(path).expect("failed to read zbi file")
}
#[cfg(not(feature = "libos"))]

View File

@ -35,15 +35,17 @@ fn primary_main(config: kernel_hal::KernelConfig) {
kernel_hal::primary_init();
cfg_if! {
if #[cfg(feature = "linux")] {
if #[cfg(all(feature = "linux", feature = "zircon"))] {
panic!("Feature `linux` and `zircon` cannot be enabled at the same time!");
} else if #[cfg(feature = "linux")] {
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);
let proc = zcore_loader::linux::run(args, envs, rootfs);
utils::wait_for_exit(Some(proc))
} else if #[cfg(feature = "zircon")] {
let zbi = fs::zbi();
let proc = zircon_loader::run_userboot(zbi, &options.cmdline);
let proc = zcore_loader::zircon::run_userboot(zbi, &options.cmdline);
utils::wait_for_exit(Some(proc))
} else {
panic!("One of the features `linux` or `zircon` must be specified!");

View File

@ -29,9 +29,18 @@ fn parse_cmdline(cmdline: &str) -> BTreeMap<&str, &str> {
pub fn boot_options() -> BootOptions {
cfg_if! {
if #[cfg(feature = "libos")] {
let args = std::env::args().collect::<Vec<_>>();
if args.len() < 2 {
#[cfg(feature = "linux")]
println!("Usage: {} PROGRAM", args[0]);
#[cfg(feature = "zircon")]
println!("Usage: {} ZBI_FILE [CMDLINE]", args[0]);
std::process::exit(-1);
}
let log_level = std::env::var("LOG").unwrap_or_default();
let cmdline = if cfg!(feature = "zircon") {
std::env::args().nth(2).unwrap_or_default()
args.get(2).cloned().unwrap_or_default()
} else {
String::new()
};
@ -39,7 +48,7 @@ pub fn boot_options() -> BootOptions {
cmdline,
log_level,
#[cfg(feature = "linux")]
root_proc: std::env::args().skip(1).collect::<Vec<_>>().join("?"),
root_proc: args[1..].join("?"),
}
} else {
let cmdline = kernel_hal::boot::cmdline();

View File

@ -1,24 +0,0 @@
[package]
name = "zircon-loader"
version = "0.1.0"
authors = ["Runji Wang <wangrunji0408@163.com>"]
edition = "2018"
description = "Zircon user program (userboot) loader"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[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", default-features = false }
[features]
default = ["libos"]
libos = ["kernel-hal/libos", "zircon-object/aspace-separate", "zircon-syscall/libos"]
[dev-dependencies]
env_logger = "0.9"
async-std = { version = "1.10", features = ["attributes"] }

View File

@ -9,9 +9,7 @@ description = "Zircon syscalls implementation"
[features]
# hypervisor = ["zircon-object/hypervisor"]
default = []
deny-page-fault = []
libos = ["deny-page-fault", "kernel-hal/libos"]
[dependencies]
log = "0.4"

View File

@ -129,10 +129,11 @@ impl Syscall<'_> {
mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE));
mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE));
let overwrite = options.contains(VmOptions::SPECIFIC_OVERWRITE);
#[cfg(feature = "deny-page-fault")]
let map_range = true;
#[cfg(not(feature = "deny-page-fault"))]
let map_range = options.contains(VmOptions::MAP_RANGE);
let map_range = if cfg!(any(feature = "deny-page-fault", not(target_os = "none"))) {
true
} else {
options.contains(VmOptions::MAP_RANGE)
};
info!(
"mmuflags: {:?}, is_specific {:?}, overwrite {:?}, map_range {:?}",