mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-30 00:00:15 +01:00
replace C by Rust code to intialize the GDT
This commit is contained in:
parent
e588263a66
commit
d406066fc9
19 changed files with 447 additions and 35 deletions
|
@ -13,7 +13,7 @@
|
|||
},
|
||||
|
||||
"version": {
|
||||
"name": "0.2.1",
|
||||
"name": "0.2.2",
|
||||
"desc": "HermitCore's kernel as libOS",
|
||||
"gpgSign": false
|
||||
},
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -6,3 +6,6 @@
|
|||
path = usr/libomp
|
||||
url = https://github.com/RWTH-OS/libomp_oss.git
|
||||
branch = hermit
|
||||
[submodule "librs/rust"]
|
||||
path = librs/rust
|
||||
url = https://github.com/RWTH-OS/rust.git
|
||||
|
|
|
@ -2,6 +2,9 @@ sudo: required
|
|||
dist: trusty
|
||||
git:
|
||||
submodules: true
|
||||
env:
|
||||
global:
|
||||
- PATH=$PATH:~/.cargo/bin
|
||||
language: c
|
||||
compiler: gcc
|
||||
before_install:
|
||||
|
@ -9,10 +12,9 @@ before_install:
|
|||
- travis_retry sudo apt-get -qq update
|
||||
- travis_retry sudo apt-get install -y curl wget qemu-system-x86 nasm texinfo libmpfr-dev libmpc-dev libgmp-dev libisl-dev flex bison packaging-dev rpm
|
||||
- travis_retry sudo apt-get install -y --force-yes binutils-hermit libhermit newlib-hermit pthread-embedded-hermit gcc-hermit
|
||||
- git submodule update --init lwip usr/libomp
|
||||
|
||||
script:
|
||||
- curl -s https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly
|
||||
- curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly
|
||||
- source cmake/local-cmake.sh
|
||||
- mkdir build
|
||||
- cd build
|
||||
|
|
|
@ -68,30 +68,40 @@ add_dependencies(hermit-bootstrap ${X86_KERNEL_TARGET})
|
|||
|
||||
# add external project hermit-rs
|
||||
ExternalProject_Add(
|
||||
hermit-rs
|
||||
objmv
|
||||
DOWNLOAD_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND cargo build --release
|
||||
BINARY_DIR "${CMAKE_SOURCE_DIR}/objmv"
|
||||
INSTALL_COMMAND ""
|
||||
LOG_BUILD ON)
|
||||
|
||||
# add external project hermit-rs
|
||||
ExternalProject_Add(
|
||||
hermit-rs
|
||||
DOWNLOAD_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND make all
|
||||
BINARY_DIR "${CMAKE_SOURCE_DIR}/librs"
|
||||
INSTALL_COMMAND ""
|
||||
LOG_BUILD ON)
|
||||
|
||||
# Create dependency of hermit-rs objmv
|
||||
add_dependencies(hermit-rs objmv)
|
||||
# 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
|
||||
${CMAKE_SOURCE_DIR}/objmv/target/release/objmv
|
||||
${CMAKE_SOURCE_DIR}/librs/target/x86_64-hermit/release/libhermit_rs.a
|
||||
|
||||
# convert rust library to hermitcore's osabi
|
||||
COMMAND
|
||||
${CMAKE_ELFEDIT} --output-osabi HermitCore ${CMAKE_SOURCE_DIR}/librs/target/x86_64-hermit/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
|
||||
|
@ -100,7 +110,7 @@ add_custom_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
|
||||
${CMAKE_SOURCE_DIR}/librs/target/x86_64-hermit/release/libhermit_rs.a
|
||||
${LOCAL_PREFIX_ARCH_LIB_DIR}/)
|
||||
|
||||
add_custom_command(
|
||||
|
@ -115,7 +125,7 @@ add_custom_command(
|
|||
|
||||
# merge libhermit.a and libhermit_rs.a
|
||||
COMMAND
|
||||
${CMAKE_AR} x ${CMAKE_SOURCE_DIR}/librs/target/release/libhermit_rs.a
|
||||
${CMAKE_AR} x ${CMAKE_SOURCE_DIR}/librs/target/x86_64-hermit/release/libhermit_rs.a
|
||||
COMMAND
|
||||
${CMAKE_AR} rcs $<TARGET_FILE:hermit-bootstrap> *.o
|
||||
COMMAND
|
||||
|
@ -248,7 +258,7 @@ set(CPACK_SYSTEM_NAME all)
|
|||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR 0)
|
||||
set(CPACK_PACKAGE_VERSION_MINOR 2)
|
||||
set(CPACK_PACKAGE_VERSION_PATCH 1)
|
||||
set(CPACK_PACKAGE_VERSION_PATCH 2)
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "Stefan Lankes <slankes@eonerc.rwth-aachen.de>")
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ start64:
|
|||
; store pointer to the multiboot information
|
||||
mov [mb_info], QWORD rdx
|
||||
|
||||
;
|
||||
; relocate page tables
|
||||
mov rdi, boot_pml4
|
||||
mov rax, QWORD [rdi]
|
||||
|
@ -255,15 +256,15 @@ Lsmp_main:
|
|||
jmp $
|
||||
%endif
|
||||
|
||||
ALIGN 64
|
||||
global gdt_flush
|
||||
;ALIGN 64
|
||||
;global gdt_flush
|
||||
extern gp
|
||||
|
||||
; This will set up our new segment registers and is declared in
|
||||
; C as 'extern void gdt_flush();'
|
||||
gdt_flush:
|
||||
lgdt [gp]
|
||||
ret
|
||||
;gdt_flush:
|
||||
; lgdt [gp]
|
||||
; ret
|
||||
|
||||
; The first 32 interrupt service routines (ISR) entries correspond to exceptions.
|
||||
; Some exceptions will push an error code onto the stack which is specific to
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <asm/tss.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#if 0
|
||||
#define MAX_IST 3
|
||||
|
||||
gdt_ptr_t gp;
|
||||
|
@ -160,3 +161,4 @@ void gdt_install(void)
|
|||
/* Flush out the old GDT and install the new changes! */
|
||||
gdt_flush();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(PACKAGE_VERSION "0.2.1" CACHE STRING
|
||||
set(PACKAGE_VERSION "0.2.2" CACHE STRING
|
||||
"HermitCore current version")
|
||||
|
||||
set(MAX_CORES "512" CACHE STRING
|
||||
|
|
|
@ -100,6 +100,7 @@ rcce_mpb_t* rcce_mpb = NULL;
|
|||
|
||||
extern void signal_init(void);
|
||||
extern void rust_main(void);
|
||||
extern void rust_init(void);
|
||||
|
||||
static int hermit_init(void)
|
||||
{
|
||||
|
@ -114,6 +115,7 @@ static int hermit_init(void)
|
|||
memcpy((char*) &percore_start + i*sz, (char*) &percore_start, sz);
|
||||
|
||||
koutput_init();
|
||||
rust_init();
|
||||
system_init();
|
||||
irq_init();
|
||||
timer_init();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "hermit-rs"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
authors = [
|
||||
"Stefan Lankes <slankes@eonerc.rwth-aachen.de>",
|
||||
]
|
||||
|
|
51
librs/Makefile
Normal file
51
librs/Makefile
Normal file
|
@ -0,0 +1,51 @@
|
|||
# derived from http://blog.phil-opp.com/rust-os/multiboot-kernel.html
|
||||
|
||||
arch ?= x86_64
|
||||
target ?= $(arch)-hermit
|
||||
rust_os := target/$(target)/release/libhermit_rs.a
|
||||
|
||||
.PHONY: all lib default clean cargo
|
||||
|
||||
default: lib
|
||||
|
||||
lib: cargo $(rust_os)
|
||||
|
||||
all: runtime lib
|
||||
|
||||
clean:
|
||||
@cargo clean --target $(target)
|
||||
|
||||
cargo:
|
||||
@echo CARGO
|
||||
@cargo build --target $(target) --release
|
||||
|
||||
#==========================================================================
|
||||
# Building the Rust runtime for our bare-metal target
|
||||
|
||||
# Where to put our compiled runtime libraries for this platform.
|
||||
installed_target_libs := \
|
||||
$(shell rustup which rustc | \
|
||||
sed s,bin/rustc,lib/rustlib/$(target)/lib,)
|
||||
|
||||
runtime_rlibs := \
|
||||
$(installed_target_libs)/libcore.rlib \
|
||||
$(installed_target_libs)/libstd_unicode.rlib \
|
||||
$(installed_target_libs)/liballoc.rlib \
|
||||
$(installed_target_libs)/libcollections.rlib
|
||||
|
||||
RUSTC := \
|
||||
rustc --verbose --target $(target) \
|
||||
-Z no-landing-pads \
|
||||
--out-dir $(installed_target_libs)
|
||||
|
||||
.PHONY: runtime
|
||||
|
||||
runtime: $(runtime_rlibs)
|
||||
|
||||
$(installed_target_libs):
|
||||
@mkdir -p $(installed_target_libs)
|
||||
|
||||
$(installed_target_libs)/%.rlib: rust/src/%/lib.rs $(installed_target_libs)
|
||||
@echo RUSTC $<
|
||||
@$(RUSTC) $<
|
||||
@echo Check $(installed_target_libs)
|
1
librs/rust
Submodule
1
librs/rust
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit ed16b0a1de57bac50477ad83e35d648688cc0ded
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
// Export our platform-specific modules.
|
||||
#[cfg(target_arch="x86_64")]
|
||||
pub use self::x86_64::{processor};
|
||||
pub use self::x86_64::{processor, gdt};
|
||||
|
||||
// Implementations for x86_64.
|
||||
#[cfg(target_arch="x86_64")]
|
||||
|
|
301
librs/src/arch/x86_64/gdt.rs
Normal file
301
librs/src/arch/x86_64/gdt.rs
Normal file
|
@ -0,0 +1,301 @@
|
|||
// Copyright (c) 2017 Stefan Lankes, RWTH Aachen University
|
||||
//
|
||||
// MIT License
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(private_no_mangle_fns)]
|
||||
|
||||
use consts::*;
|
||||
use x86::dtables::*;
|
||||
use core::mem::size_of;
|
||||
|
||||
// This segment is a data segment
|
||||
const GDT_FLAG_DATASEG: u8 = 0x02;
|
||||
/// This segment is a code segment
|
||||
const GDT_FLAG_CODESEG: u8 = 0x0a;
|
||||
const GDT_FLAG_TSS: u8 = 0x09;
|
||||
const GDT_FLAG_TSS_BUSY: u8 = 0x02;
|
||||
|
||||
const GDT_FLAG_SEGMENT: u8 = 0x10;
|
||||
/// Privilege level: Ring 0
|
||||
const GDT_FLAG_RING0: u8 = 0x00;
|
||||
/// Privilege level: Ring 1
|
||||
const GDT_FLAG_RING1: u8 = 0x20;
|
||||
/// Privilege level: Ring 2
|
||||
const GDT_FLAG_RING2: u8 = 0x40;
|
||||
/// Privilege level: Ring 3
|
||||
const GDT_FLAG_RING3: u8 = 0x60;
|
||||
/// Segment is present
|
||||
const GDT_FLAG_PRESENT: u8 = 0x80;
|
||||
/// Segment was accessed
|
||||
const GDT_FLAG_ACCESSED: u8 = 0x01;
|
||||
/// Granularity of segment limit
|
||||
/// - set: segment limit unit is 4 KB (page size)
|
||||
/// - not set: unit is bytes
|
||||
const GDT_FLAG_4K_GRAN: u8 = 0x80;
|
||||
/// Default operand size
|
||||
/// - set: 32 bit
|
||||
/// - not set: 16 bit
|
||||
const GDT_FLAG_16_BIT: u8 = 0x00;
|
||||
const GDT_FLAG_32_BIT: u8 = 0x40;
|
||||
const GDT_FLAG_64_BIT: u8 = 0x20;
|
||||
|
||||
// a TSS descriptor is twice larger than a code/data descriptor
|
||||
const GDT_ENTRIES : usize = (6+MAX_CORES*2);
|
||||
const MAX_IST : usize = 3;
|
||||
|
||||
// thread_local on a static mut, signals that the value of this static may
|
||||
// change depending on the current thread.
|
||||
static mut GDT: [GdtEntry; GDT_ENTRIES] = [GdtEntry::new(0, 0, 0, 0); GDT_ENTRIES];
|
||||
static mut GDTR: DescriptorTablePointer = DescriptorTablePointer {
|
||||
limit: 0, //x((size_of::<GdtEntry>() * GDT_ENTRIES) - 1) as u16,
|
||||
base: 0 //GDT.as_ptr() as u64
|
||||
};
|
||||
static mut TSS_BUFFER: TssBuffer = TssBuffer::new();
|
||||
static STACK_TABLE: [[IrqStack; MAX_IST]; MAX_CORES] = [[IrqStack::new(); MAX_IST]; MAX_CORES];
|
||||
|
||||
extern "C" {
|
||||
static boot_stack: [u8; MAX_CORES*KERNEL_STACK_SIZE*MAX_IST];
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
struct GdtEntry {
|
||||
/// Lower 16 bits of limit range
|
||||
limit_low: u16,
|
||||
/// Lower 16 bits of base address
|
||||
base_low: u16,
|
||||
/// middle 8 bits of base address
|
||||
base_middle: u8,
|
||||
/// Access bits
|
||||
access: u8,
|
||||
/// Granularity bits
|
||||
granularity: u8,
|
||||
/// Higher 8 bits of base address
|
||||
base_high: u8
|
||||
}
|
||||
|
||||
impl GdtEntry {
|
||||
pub const fn new(base: u32, limit: u32, access: u8, gran: u8) -> Self {
|
||||
GdtEntry {
|
||||
limit_low: (limit & 0xFFFF) as u16,
|
||||
base_low: (base & 0xFFFF) as u16,
|
||||
base_middle: ((base >> 16) & 0xFF) as u8,
|
||||
access: access,
|
||||
granularity: (gran & 0xF0) as u8 | ((limit >> 16) & 0x0F) as u8,
|
||||
base_high: ((base >> 24) & 0xFF) as u8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// definition of the tast state segment structure
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
struct TaskStateSegment {
|
||||
res0: u16, // reserved entries
|
||||
res1: u16, // reserved entries
|
||||
rsp0: u64,
|
||||
rsp1: u64,
|
||||
rsp2: u64,
|
||||
res2: u32, // reserved entries
|
||||
res3: u32, // reserved entries
|
||||
ist1: u64,
|
||||
ist2: u64,
|
||||
ist3: u64,
|
||||
ist4: u64,
|
||||
ist5: u64,
|
||||
ist6: u64,
|
||||
ist7: u64,
|
||||
res4: u32, // reserved entries
|
||||
res5: u32, // reserved entries
|
||||
res6: u16,
|
||||
bitmap: u16,
|
||||
}
|
||||
|
||||
impl TaskStateSegment {
|
||||
/// Creates a new TSS with zeroed privilege and interrupt stack table and a zero
|
||||
/// `iomap_base`.
|
||||
pub const fn new() -> TaskStateSegment {
|
||||
TaskStateSegment {
|
||||
res0: 0, // reserved entries
|
||||
res1: 0, // reserved entries
|
||||
rsp0: 0,
|
||||
rsp1: 0,
|
||||
rsp2: 0,
|
||||
res2: 0, // reserved entries
|
||||
res3: 0, // reserved entries
|
||||
ist1: 0,
|
||||
ist2: 0,
|
||||
ist3: 0,
|
||||
ist4: 0,
|
||||
ist5: 0,
|
||||
ist6: 0,
|
||||
ist7: 0,
|
||||
res4: 0, // reserved entries
|
||||
res5: 0, // reserved entries
|
||||
res6: 0,
|
||||
bitmap: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// workaround to use th enew repr(align) feature
|
||||
// currently, it is only supported by structs
|
||||
// => map all TSS in a struct
|
||||
#[repr(C, align(4096))]
|
||||
struct TssBuffer {
|
||||
tss: [TaskStateSegment; MAX_CORES],
|
||||
}
|
||||
|
||||
impl TssBuffer {
|
||||
pub const fn new() -> TssBuffer {
|
||||
TssBuffer {
|
||||
tss: [TaskStateSegment::new(); MAX_CORES],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// workaround to use th enew repr(align) feature
|
||||
// currently, it is only supported by structs
|
||||
// => map stacks in a struct
|
||||
#[derive(Copy)]
|
||||
#[repr(C, align(4096))]
|
||||
struct IrqStack {
|
||||
buffer: [u8; KERNEL_STACK_SIZE],
|
||||
}
|
||||
|
||||
impl Clone for IrqStack {
|
||||
fn clone(&self) -> IrqStack
|
||||
{
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl IrqStack {
|
||||
pub const fn new() -> IrqStack {
|
||||
IrqStack {
|
||||
buffer: [0; KERNEL_STACK_SIZE],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This will setup the special GDT
|
||||
/// pointer, set up the entries in our GDT, and then
|
||||
/// finally to load the new GDT and to update the
|
||||
/// new segment registers
|
||||
#[no_mangle]
|
||||
pub extern fn gdt_install()
|
||||
{
|
||||
unsafe {
|
||||
// Setup the GDT pointer and limit
|
||||
GDTR.limit = ((size_of::<GdtEntry>() * GDT_ENTRIES) - 1) as u16;
|
||||
GDTR.base = (&GDT as *const _) as u64;
|
||||
|
||||
let mut num: usize = 0;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
GDT[num] = GdtEntry::new(0, 0, 0, 0);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* The second entry is our Code Segment. The base address
|
||||
* is 0, the limit is 4 GByte, it uses 4KByte granularity,
|
||||
* and is a Code Segment descriptor.
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0,
|
||||
GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT, GDT_FLAG_64_BIT);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* The third entry is our Data Segment. It's EXACTLY the
|
||||
* same as our code segment, but the descriptor type in
|
||||
* this entry's access byte says it's a Data Segment
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0,
|
||||
GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT, 0);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* Create code segment for 32bit user-space applications (ring 3)
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0xFFFFFFFF,
|
||||
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT, GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* Create data segment for 32bit user-space applications (ring 3)
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0xFFFFFFFF,
|
||||
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT, GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* Create code segment for 64bit user-space applications (ring 3)
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0,
|
||||
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT, GDT_FLAG_64_BIT);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* Create data segment for 64bit user-space applications (ring 3)
|
||||
*/
|
||||
GDT[num] = GdtEntry::new(0, 0,
|
||||
GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT, 0);
|
||||
num += 1;
|
||||
|
||||
/*
|
||||
* Create TSS for each core (we use these segments for task switching)
|
||||
*/
|
||||
for i in 0..MAX_CORES {
|
||||
TSS_BUFFER.tss[i].rsp0 = (&(boot_stack[0]) as *const _) as u64;
|
||||
TSS_BUFFER.tss[i].rsp0 += ((i+1) * KERNEL_STACK_SIZE - 0x10) as u64;
|
||||
TSS_BUFFER.tss[i].ist1 = 0; // ist will created per task
|
||||
TSS_BUFFER.tss[i].ist2 = (&(STACK_TABLE[i][2 /*IST number */ - 2]) as *const _) as u64;
|
||||
TSS_BUFFER.tss[i].ist2 += (KERNEL_STACK_SIZE - 0x10) as u64;
|
||||
TSS_BUFFER.tss[i].ist3 = (&(STACK_TABLE[i][3 /*IST number */ - 2]) as *const _) as u64;
|
||||
TSS_BUFFER.tss[i].ist3 += (KERNEL_STACK_SIZE - 0x10) as u64;
|
||||
TSS_BUFFER.tss[i].ist4 = (&(STACK_TABLE[i][4 /*IST number */ - 2]) as *const _) as u64;
|
||||
TSS_BUFFER.tss[i].ist4 += (KERNEL_STACK_SIZE - 0x10) as u64;
|
||||
|
||||
let tss_ptr = &(TSS_BUFFER.tss[i]) as *const TaskStateSegment;
|
||||
GDT[num+i*2] = GdtEntry::new(tss_ptr as u32, (size_of::<TaskStateSegment>()-1) as u32,
|
||||
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, 0);
|
||||
}
|
||||
|
||||
lgdt(&GDTR);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn set_tss(rsp0: u64, ist1: u64)
|
||||
{
|
||||
unsafe {
|
||||
TSS_BUFFER.tss[core_id!()].rsp0 = rsp0;
|
||||
TSS_BUFFER.tss[core_id!()].ist1 = ist1;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn gdt_flush()
|
||||
{
|
||||
unsafe { lgdt(&GDTR); }
|
||||
}
|
|
@ -22,3 +22,4 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
pub mod processor;
|
||||
pub mod gdt;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#![cfg(target_arch = "x86_64")]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use logging::*;
|
||||
|
|
30
librs/src/consts.rs
Normal file
30
librs/src/consts.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2017 Stefan Lankes, RWTH Aachen University
|
||||
//
|
||||
// MIT License
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub const MAX_CORES : usize = 512;
|
||||
pub const KERNEL_STACK_SIZE : usize = 8192;
|
||||
|
||||
#[cfg(target_arch="x86_64")]
|
||||
pub const PAGE_SIZE : usize = 4096;
|
|
@ -22,12 +22,12 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* Derived and adapted for HermitCore from
|
||||
* First version is 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)]
|
||||
#![feature(asm, const_fn, lang_items, repr_align, attr_literals)]
|
||||
#![no_std]
|
||||
|
||||
extern crate rlibc;
|
||||
|
@ -38,6 +38,10 @@ extern crate raw_cpuid;
|
|||
// These need to be visible to the linker, so we need to export them.
|
||||
pub use runtime_glue::*;
|
||||
pub use logging::*;
|
||||
pub use consts::*;
|
||||
|
||||
#[cfg(target_arch="x86_64")]
|
||||
pub use arch::gdt::*;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
@ -46,17 +50,16 @@ mod logging;
|
|||
mod runtime_glue;
|
||||
mod console;
|
||||
mod arch;
|
||||
mod consts;
|
||||
|
||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_main() {
|
||||
pub extern "C" fn rust_init() {
|
||||
info!("HermitCore's Rust runtime! v{}", VERSION);
|
||||
|
||||
arch::processor::cpu_detection();
|
||||
|
||||
//info!("info");
|
||||
//warn!("warning");
|
||||
//debug!("debug");
|
||||
//error!("oops");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_main() {
|
||||
arch::processor::cpu_detection();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
/// Determin the Id of the current CPU
|
||||
macro_rules! core_id {
|
||||
() => ( 0 );
|
||||
}
|
||||
|
||||
/// Print formatted text to our console.
|
||||
///
|
||||
/// From http://blog.phil-opp.com/rust-os/printing-to-screen.html, but tweaked
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"llvm-target": "x86_64-hermit",
|
||||
"llvm-target": "x86_64-unknown-none-gnu",
|
||||
"linker-flavor": "gcc",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"os": "none",
|
||||
|
|
Loading…
Add table
Reference in a new issue