mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 02:43:24 +00:00
Implement OSDK functionalities and opt-in OSDK for asterinas
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
bc9bce9dea
commit
f97d0f1260
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
align_ext = { path = "../libs/align_ext" }
|
||||
aster-main = { path = "../libs/aster-main" }
|
||||
bit_field = "0.10.1"
|
||||
bitflags = "1.3"
|
||||
bitvec = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||
|
@ -1,74 +0,0 @@
|
||||
ENTRY(__multiboot_boot)
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
|
||||
KERNEL_LMA = 0x8000000;
|
||||
LINUX_32_ENTRY = 0x8001000;
|
||||
KERNEL_VMA = 0xffffffff80000000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = KERNEL_LMA;
|
||||
|
||||
__kernel_start = .;
|
||||
|
||||
.multiboot_header : { KEEP(*(.multiboot_header)) }
|
||||
.multiboot2_header : { KEEP(*(.multiboot2_header)) }
|
||||
|
||||
. = LINUX_32_ENTRY;
|
||||
|
||||
.boot : { KEEP(*(.boot)) }
|
||||
|
||||
. += KERNEL_VMA;
|
||||
|
||||
.text : AT(ADDR(.text) - KERNEL_VMA) {
|
||||
*(.text .text.*)
|
||||
PROVIDE(__etext = .);
|
||||
}
|
||||
.rodata : AT(ADDR(.rodata) - KERNEL_VMA) { *(.rodata .rodata.*) }
|
||||
|
||||
.eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - KERNEL_VMA) {
|
||||
KEEP(*(.eh_frame_hdr .eh_frame_hdr.*))
|
||||
}
|
||||
. = ALIGN(8);
|
||||
.eh_frame : AT(ADDR(.eh_frame) - KERNEL_VMA) {
|
||||
PROVIDE(__eh_frame = .);
|
||||
KEEP(*(.eh_frame .eh_frame.*))
|
||||
}
|
||||
|
||||
.gcc_except_table : AT(ADDR(.gcc_except_table) - KERNEL_VMA) { *(.gcc_except_table .gcc_except_table.*) }
|
||||
|
||||
.data.rel.ro : AT(ADDR(.data.rel.ro) - KERNEL_VMA) { *(.data.rel.ro .data.rel.ro.*) }
|
||||
.dynamic : AT(ADDR(.dynamic) - KERNEL_VMA) { *(.dynamic) }
|
||||
|
||||
.init_array : AT(ADDR(.init_array) - KERNEL_VMA) {
|
||||
__sinit_array = .;
|
||||
KEEP(*(SORT(.init_array .init_array.*)))
|
||||
__einit_array = .;
|
||||
}
|
||||
|
||||
.got : AT(ADDR(.got) - KERNEL_VMA) { *(.got .got.*) }
|
||||
.got.plt : AT(ADDR(.got.plt) - KERNEL_VMA) { *(.got.plt .got.plt.*) }
|
||||
|
||||
. = DATA_SEGMENT_RELRO_END(0, .);
|
||||
|
||||
.data : AT(ADDR(.data) - KERNEL_VMA) { *(.data .data.*) }
|
||||
.bss : AT(ADDR(.bss) - KERNEL_VMA) {
|
||||
__bss = .;
|
||||
*(.bss .bss.*) *(COMMON)
|
||||
__bss_end = .;
|
||||
}
|
||||
|
||||
.ktest_array : AT(ADDR(.ktest_array) - KERNEL_VMA) {
|
||||
__ktest_array = .;
|
||||
KEEP(*(SORT(.ktest_array)))
|
||||
__ktest_array_end = .;
|
||||
}
|
||||
|
||||
.tdata : AT(ADDR(.tdata) - KERNEL_VMA) { *(.tdata .tdata.*) }
|
||||
.tbss : AT(ADDR(.tbss) - KERNEL_VMA) { *(.tbss .tbss.*) }
|
||||
|
||||
. = DATA_SEGMENT_END(.);
|
||||
|
||||
__kernel_end = . - KERNEL_VMA;
|
||||
}
|
@ -91,11 +91,6 @@ impl From<&str> for KCmdlineArg {
|
||||
// The main parse loop. The processing steps are arranged (not very strictly)
|
||||
// by the analysis over the Backus–Naur form syntax tree.
|
||||
for arg in split_arg(cmdline) {
|
||||
// FIXME: The -kernel option in QEMU seems to add this string to the command line, which we skip for now.
|
||||
if arg.starts_with("target/x86_64-custom/") {
|
||||
warn!("Found kcmdline: {:?}, skipped for now.", arg);
|
||||
continue;
|
||||
}
|
||||
// Cmdline => KernelArg "--" InitArg
|
||||
// KernelArg => Arg "\s+" KernelArg | %empty
|
||||
// InitArg => Arg "\s+" InitArg | %empty
|
||||
@ -116,7 +111,8 @@ impl From<&str> for KCmdlineArg {
|
||||
1 => (arg_pattern[0], None),
|
||||
2 => (arg_pattern[0], Some(arg_pattern[1])),
|
||||
_ => {
|
||||
panic!("Unable to parse argument {}", arg);
|
||||
warn!("Unable to parse kernel argument {}, skip for now", arg);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
// Entry => Module "." ModuleOptionName | KernelOptionName
|
||||
@ -125,7 +121,11 @@ impl From<&str> for KCmdlineArg {
|
||||
1 => (None, entry_pattern[0]),
|
||||
2 => (Some(entry_pattern[0]), entry_pattern[1]),
|
||||
_ => {
|
||||
panic!("Unable to parse entry {} in argument {}", entry, arg);
|
||||
warn!(
|
||||
"Unable to parse entry {} in argument {}, skip for now",
|
||||
entry, arg
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if let Some(modname) = node {
|
||||
|
@ -113,48 +113,38 @@ pub fn call_aster_main() -> ! {
|
||||
// The entry point of kernel code, which should be defined by the package that
|
||||
// uses aster-frame.
|
||||
extern "Rust" {
|
||||
fn aster_main() -> !;
|
||||
fn __aster_main() -> !;
|
||||
}
|
||||
aster_main();
|
||||
__aster_main();
|
||||
}
|
||||
#[cfg(ktest)]
|
||||
{
|
||||
use alloc::{boxed::Box, string::ToString};
|
||||
use core::any::Any;
|
||||
|
||||
use crate::arch::qemu::{exit_qemu, QemuExitCode};
|
||||
unsafe {
|
||||
crate::init();
|
||||
let fn_catch_unwind = &(unwinding::panic::catch_unwind::<(), fn()>
|
||||
as fn(fn()) -> Result<(), Box<(dyn Any + Send + 'static)>>);
|
||||
// Parse the whitelist from the kernel command line.
|
||||
let mut paths = None;
|
||||
let args = kernel_cmdline().get_module_args("ktest");
|
||||
if let Some(args) = args {
|
||||
for options in args {
|
||||
match options {
|
||||
kcmdline::ModuleArg::KeyVal(key, val) => {
|
||||
if key.to_str().unwrap() == "whitelist" && val.to_str().unwrap() != "" {
|
||||
let paths_str = val.to_str().unwrap();
|
||||
paths = Some(
|
||||
paths_str
|
||||
.split(',')
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
use ktest::runner::{run_ktests, KtestResult};
|
||||
match run_ktests(
|
||||
&crate::console::print,
|
||||
fn_catch_unwind,
|
||||
paths.map(|v| v.into_iter()),
|
||||
) {
|
||||
KtestResult::Ok => exit_qemu(QemuExitCode::Success),
|
||||
KtestResult::Failed => exit_qemu(QemuExitCode::Failed),
|
||||
// The whitelists that will be generated by OSDK runner as static consts.
|
||||
extern "Rust" {
|
||||
static KTEST_TEST_WHITELIST: Option<&'static [&'static str]>;
|
||||
static KTEST_CRATE_WHITELIST: Option<&'static [&'static str]>;
|
||||
}
|
||||
run_ktests(KTEST_TEST_WHITELIST, KTEST_CRATE_WHITELIST);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_ktests(test_whitelist: Option<&[&str]>, crate_whitelist: Option<&[&str]>) -> ! {
|
||||
use crate::arch::qemu::{exit_qemu, QemuExitCode};
|
||||
use alloc::{boxed::Box, string::ToString};
|
||||
use core::any::Any;
|
||||
|
||||
let fn_catch_unwind = &(unwinding::panic::catch_unwind::<(), fn()>
|
||||
as fn(fn()) -> Result<(), Box<(dyn Any + Send + 'static)>>);
|
||||
|
||||
use ktest::runner::{run_ktests, KtestResult};
|
||||
match run_ktests(
|
||||
&crate::console::print,
|
||||
fn_catch_unwind,
|
||||
test_whitelist.map(|s| s.iter().map(|s| s.to_string())),
|
||||
crate_whitelist,
|
||||
) {
|
||||
KtestResult::Ok => exit_qemu(QemuExitCode::Success),
|
||||
KtestResult::Failed => exit_qemu(QemuExitCode::Failed),
|
||||
};
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(ktest)]
|
||||
#[macro_use]
|
||||
extern crate ktest;
|
||||
#[macro_use]
|
||||
@ -83,7 +84,7 @@ fn invoke_ffi_init_funcs() {
|
||||
}
|
||||
|
||||
/// Simple unit tests for the ktest framework.
|
||||
#[if_cfg_ktest]
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
#[ktest]
|
||||
fn trivial_assertion() {
|
||||
|
@ -23,12 +23,12 @@ use unwinding::{
|
||||
panic::begin_panic,
|
||||
};
|
||||
|
||||
fn abort() -> ! {
|
||||
exit_qemu(QemuExitCode::Failed);
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||
/// The panic handler must be defined in the binary crate or in the crate that the binary
|
||||
/// crate explicity declares by `extern crate`. We cannot let the base crate depend on the
|
||||
/// framework due to prismatic dependencies. That's why we export this symbol and state the
|
||||
/// panic handler in the binary crate.
|
||||
#[export_name = "__aster_panic_handler"]
|
||||
pub fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||
let throw_info = ktest::PanicInfo {
|
||||
message: info.message().unwrap().to_string(),
|
||||
file: info.location().unwrap().file().to_string(),
|
||||
@ -46,6 +46,10 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||
abort();
|
||||
}
|
||||
|
||||
fn abort() -> ! {
|
||||
exit_qemu(QemuExitCode::Failed);
|
||||
}
|
||||
|
||||
fn print_stack_trace() {
|
||||
struct CallbackData {
|
||||
counter: usize,
|
||||
|
@ -8,3 +8,7 @@ pub(crate) use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
pub(crate) use core::any::Any;
|
||||
|
||||
pub use crate::vm::{Paddr, Vaddr};
|
||||
|
||||
pub use crate::early_print as print;
|
||||
pub use crate::early_println as println;
|
||||
pub use aster_main::aster_main;
|
||||
|
@ -288,7 +288,7 @@ impl fmt::Debug for AtomicBits {
|
||||
}
|
||||
}
|
||||
|
||||
#[if_cfg_ktest]
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
|
@ -162,7 +162,7 @@ impl HasPaddr for DmaCoherent {
|
||||
}
|
||||
}
|
||||
|
||||
#[if_cfg_ktest]
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
use alloc::vec;
|
||||
|
||||
|
@ -195,7 +195,7 @@ impl HasPaddr for DmaStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[if_cfg_ktest]
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
use alloc::vec;
|
||||
|
||||
|
Reference in New Issue
Block a user