diff --git a/.travis.yml b/.travis.yml index 116a34b6e..ab99f4680 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index e212473ce..c5ce9c00d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 $ + # merge libhermit.a and libhermit_rs.a + COMMAND + ${CMAKE_AR} x ${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a + COMMAND + ${CMAKE_AR} rcs $ *.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 $ + # 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) diff --git a/README.md b/README.md index 12b358dce..43f99820b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/kernel/main.c b/kernel/main.c index d2fe61327..7421f8745 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -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(); diff --git a/librs/.gitignore b/librs/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/librs/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/librs/Cargo.toml b/librs/Cargo.toml new file mode 100644 index 000000000..629bd2760 --- /dev/null +++ b/librs/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "hermit-rs" +version = "0.2.0" +authors = [ + "Stefan Lankes ", +] + +[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. diff --git a/librs/src/console.rs b/librs/src/console.rs new file mode 100644 index 000000000..a56a8d4bb --- /dev/null +++ b/librs/src/console.rs @@ -0,0 +1,47 @@ +/* + * 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 = Mutex::new(Console); diff --git a/librs/src/lib.rs b/librs/src/lib.rs new file mode 100644 index 000000000..cf15d5ee4 --- /dev/null +++ b/librs/src/lib.rs @@ -0,0 +1,51 @@ +/* + * 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!"); +} diff --git a/librs/src/macros.rs b/librs/src/macros.rs new file mode 100644 index 000000000..1978db86a --- /dev/null +++ b/librs/src/macros.rs @@ -0,0 +1,45 @@ +/* + * 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)*)); +} diff --git a/librs/src/runtime_glue.rs b/librs/src/runtime_glue.rs new file mode 100644 index 000000000..05b1c98bb --- /dev/null +++ b/librs/src/runtime_glue.rs @@ -0,0 +1,49 @@ +/* + * 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 {} +} diff --git a/librs/x86_64-hermit.json b/librs/x86_64-hermit.json new file mode 100644 index 000000000..81ffa2255 --- /dev/null +++ b/librs/x86_64-hermit.json @@ -0,0 +1,18 @@ +{ + "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" +}