Commit 9125bc37 authored by Stefan Lankes's avatar Stefan Lankes
Browse files

add proof of concept to use Rust within HermitCore's kernel

parent 12356fff
......@@ -12,6 +12,8 @@ before_install:
- git submodule update --init lwip usr/libomp
script:
- curl https://sh.rustup.rs -sSf | sh
- rustup install nightly
- source cmake/local-cmake.sh
- mkdir build
- cd build
......
......@@ -66,6 +66,43 @@ set_target_properties(hermit-bootstrap PROPERTIES
# dependency makes sure that this is done before hermit is linked
add_dependencies(hermit-bootstrap ${X86_KERNEL_TARGET})
# add external project hermit-rs
ExternalProject_Add(
hermit-rs
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build --release
BINARY_DIR "${CMAKE_SOURCE_DIR}/librs"
INSTALL_COMMAND ""
LOG_BUILD ON)
# Create dependency of hermit-boostrap hermit-rs
add_dependencies(hermit-bootstrap hermit-rs)
add_custom_command(
TARGET
hermit-rs POST_BUILD
# convert rust library to hermitcore's osabi
COMMAND
${CMAKE_ELFEDIT} --output-osabi HermitCore ${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a
# rename sections in rust library
COMMAND
${CMAKE_OBJCOPY} --rename-section .bss=.kbss
--rename-section .text=.ktext
--rename-section .data=.kdata
${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a
# copy libhermit_rs.a into local prefix directory so that all subsequent
# targets can link against the freshly built version (as opposed to
# linking against the one supplied by the toolchain)
COMMAND
${CMAKE_COMMAND} -E make_directory ${LOCAL_PREFIX_ARCH_LIB_DIR}
COMMAND
${CMAKE_COMMAND} -E copy_if_different
${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a
${LOCAL_PREFIX_ARCH_LIB_DIR}/)
add_custom_command(
TARGET
hermit-bootstrap POST_BUILD
......@@ -76,6 +113,18 @@ add_custom_command(
--rename-section .data=.kdata
$<TARGET_FILE:hermit-bootstrap>
# merge libhermit.a and libhermit_rs.a
COMMAND
${CMAKE_AR} x ${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a
COMMAND
${CMAKE_AR} rcs $<TARGET_FILE:hermit-bootstrap> *.o
COMMAND
${CMAKE_COMMAND} -E remove *.o
# redefine _Unwind_Resume to avoid collision with libgcc.a
COMMAND
${CMAKE_OBJCOPY} --redefine-sym _Unwind_Resume=_Unwind_Resume_rs $<TARGET_FILE:hermit-bootstrap>
# copy libhermit.a into local prefix directory so that all subsequent
# targets can link against the freshly built version (as opposed to
# linking against the one supplied by the toolchain)
......
......@@ -41,6 +41,7 @@ the HermitCore kernel and applications you need:
* Netwide Assember (NASM)
* recent host compiler such as GCC
* HermitCore cross-toolchain, i.e. Binutils, GCC, newlib, pthreads
* Rust compiler
### HermitCore cross-toolchain
......
......@@ -98,7 +98,8 @@ extern volatile int libc_sd;
islelock_t* rcce_lock = NULL;
rcce_mpb_t* rcce_mpb = NULL;
extern void signal_init();
extern void signal_init(void);
extern void rust_main(void);
static int hermit_init(void)
{
......@@ -537,6 +538,8 @@ int hermit_main(void)
LOG_INFO("Kernel cmdline: %s\n", (char*) (size_t) mb_info->cmdline);
if (hbmem_base)
LOG_INFO("Found high bandwidth memory at 0x%zx (size 0x%zx)\n", hbmem_base, hbmem_size);
LOG_INFO("rust_main at %p\n", rust_main);
rust_main();
#if 0
print_pci_adapters();
......
target
Cargo.lock
[package]
name = "hermit-rs"
version = "0.2.0"
authors = [
"Stefan Lankes <slankes@eonerc.rwth-aachen.de>",
]
[lib]
crate-type = ["staticlib"]
[dependencies]
rlibc = "0.1.4" # Low-level functions like memcpy.
spin = "0.3.4" # Spinlocks.
x86 = "0.6.0" # CPU data structures.
/*
* Copyright (c) 2017, Stefan Lankes, RWTH Aachen University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
use core::fmt;
use spin::Mutex;
extern {
pub fn kputs(s: &[u8]) -> i32;
}
pub struct Console;
impl fmt::Write for Console {
/// print string as kernel message.
fn write_str(&mut self, s: &str) -> fmt::Result {
unsafe {
kputs(s.as_bytes());
}
Ok(())
}
}
pub static CONSOLE: Mutex<Console> = Mutex::new(Console);
/*
* Copyright (c) 2017, Stefan Lankes, RWTH Aachen University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Derived and adapted for HermitCore from
* Philipp Oppermann's excellent series of blog posts (http://blog.phil-opp.com/)
* and Eric Kidd's toy OS (https://github.com/emk/toyos-rs).
*/
#![feature(asm, const_fn, lang_items)]
#![no_std]
extern crate rlibc;
extern crate spin;
// These need to be visible to the linker, so we need to export them.
pub use runtime_glue::*;
#[macro_use]
mod macros;
mod runtime_glue;
mod console;
#[no_mangle]
pub extern "C" fn rust_main() {
println!("Hello from Rust!");
}
/*
* Copyright (c) 2017, Stefan Lankes, RWTH Aachen University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Print formatted text to our console.
///
/// From http://blog.phil-opp.com/rust-os/printing-to-screen.html, but tweaked
/// to work with our APIs.
macro_rules! print {
($($arg:tt)*) => ({
use core::fmt::Write;
$crate::console::CONSOLE.lock().write_fmt(format_args!($($arg)*)).unwrap();
});
}
/// Print formatted text to our console, followed by a newline.
///
/// From https://doc.rust-lang.org/nightly/std/macro.println!.html
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
/*
* Copyright (c) 2017, Stefan Lankes, RWTH Aachen University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//! Minor functions that Rust really expects to be defined by our compiler
//! or something, but which we need to provide manually because we're on
//! bare metal.
#[lang = "eh_personality"]
extern "C" fn eh_personality() {
}
#[lang = "panic_fmt"] #[no_mangle]
extern "C" fn panic_fmt(args: ::core::fmt::Arguments, file: &str, line: usize) -> !
{
println!("PANIC: {}:{}: {}", file, line, args);
loop {}
}
#[no_mangle]
#[allow(non_snake_case)]
pub fn _Unwind_Resume()
{
println!("UNWIND!");
loop {}
}
{
"llvm-target": "x86_64-hermit",
"target-endian": "little",
"target-pointer-width": "64",
"os": "none",
"arch": "x86_64",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"pre-link-args": [ "-m64" ],
"cpu": "x86-64",
"features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
"disable-redzone": true,
"eliminate-frame-pointer": true,
"linker-is-gnu": true,
"no-compiler-rt": true,
"archive-format": "gnu"
"code-model": "kernel"
"relocation-model": "static"
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment