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": {
|
"version": {
|
||||||
"name": "0.2.1",
|
"name": "0.2.2",
|
||||||
"desc": "HermitCore's kernel as libOS",
|
"desc": "HermitCore's kernel as libOS",
|
||||||
"gpgSign": false
|
"gpgSign": false
|
||||||
},
|
},
|
||||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -6,3 +6,6 @@
|
||||||
path = usr/libomp
|
path = usr/libomp
|
||||||
url = https://github.com/RWTH-OS/libomp_oss.git
|
url = https://github.com/RWTH-OS/libomp_oss.git
|
||||||
branch = hermit
|
branch = hermit
|
||||||
|
[submodule "librs/rust"]
|
||||||
|
path = librs/rust
|
||||||
|
url = https://github.com/RWTH-OS/rust.git
|
||||||
|
|
|
@ -2,6 +2,9 @@ sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
git:
|
git:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- PATH=$PATH:~/.cargo/bin
|
||||||
language: c
|
language: c
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
before_install:
|
before_install:
|
||||||
|
@ -9,10 +12,9 @@ before_install:
|
||||||
- travis_retry sudo apt-get -qq update
|
- 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 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
|
- 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:
|
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
|
- source cmake/local-cmake.sh
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
|
|
|
@ -68,30 +68,40 @@ add_dependencies(hermit-bootstrap ${X86_KERNEL_TARGET})
|
||||||
|
|
||||||
# add external project hermit-rs
|
# add external project hermit-rs
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
hermit-rs
|
objmv
|
||||||
DOWNLOAD_COMMAND ""
|
DOWNLOAD_COMMAND ""
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND cargo build --release
|
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"
|
BINARY_DIR "${CMAKE_SOURCE_DIR}/librs"
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
LOG_BUILD ON)
|
LOG_BUILD ON)
|
||||||
|
|
||||||
|
# Create dependency of hermit-rs objmv
|
||||||
|
add_dependencies(hermit-rs objmv)
|
||||||
# Create dependency of hermit-boostrap hermit-rs
|
# Create dependency of hermit-boostrap hermit-rs
|
||||||
add_dependencies(hermit-bootstrap hermit-rs)
|
add_dependencies(hermit-bootstrap hermit-rs)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET
|
TARGET
|
||||||
hermit-rs POST_BUILD
|
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
|
# rename sections in rust library
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_OBJCOPY} --rename-section .bss=.kbss
|
${CMAKE_SOURCE_DIR}/objmv/target/release/objmv
|
||||||
--rename-section .text=.ktext
|
${CMAKE_SOURCE_DIR}/librs/target/x86_64-hermit/release/libhermit_rs.a
|
||||||
--rename-section .data=.kdata
|
|
||||||
${CMAKE_SOURCE_DIR}/librs/target/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
|
# copy libhermit_rs.a into local prefix directory so that all subsequent
|
||||||
# targets can link against the freshly built version (as opposed to
|
# 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}
|
${CMAKE_COMMAND} -E make_directory ${LOCAL_PREFIX_ARCH_LIB_DIR}
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_COMMAND} -E copy_if_different
|
${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}/)
|
${LOCAL_PREFIX_ARCH_LIB_DIR}/)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -115,7 +125,7 @@ add_custom_command(
|
||||||
|
|
||||||
# merge libhermit.a and libhermit_rs.a
|
# merge libhermit.a and libhermit_rs.a
|
||||||
COMMAND
|
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
|
COMMAND
|
||||||
${CMAKE_AR} rcs $<TARGET_FILE:hermit-bootstrap> *.o
|
${CMAKE_AR} rcs $<TARGET_FILE:hermit-bootstrap> *.o
|
||||||
COMMAND
|
COMMAND
|
||||||
|
@ -248,7 +258,7 @@ set(CPACK_SYSTEM_NAME all)
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR 0)
|
set(CPACK_PACKAGE_VERSION_MAJOR 0)
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR 2)
|
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>")
|
set(CPACK_PACKAGE_CONTACT "Stefan Lankes <slankes@eonerc.rwth-aachen.de>")
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,7 @@ start64:
|
||||||
; store pointer to the multiboot information
|
; store pointer to the multiboot information
|
||||||
mov [mb_info], QWORD rdx
|
mov [mb_info], QWORD rdx
|
||||||
|
|
||||||
|
;
|
||||||
; relocate page tables
|
; relocate page tables
|
||||||
mov rdi, boot_pml4
|
mov rdi, boot_pml4
|
||||||
mov rax, QWORD [rdi]
|
mov rax, QWORD [rdi]
|
||||||
|
@ -255,15 +256,15 @@ Lsmp_main:
|
||||||
jmp $
|
jmp $
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
ALIGN 64
|
;ALIGN 64
|
||||||
global gdt_flush
|
;global gdt_flush
|
||||||
extern gp
|
extern gp
|
||||||
|
|
||||||
; This will set up our new segment registers and is declared in
|
; This will set up our new segment registers and is declared in
|
||||||
; C as 'extern void gdt_flush();'
|
; C as 'extern void gdt_flush();'
|
||||||
gdt_flush:
|
;gdt_flush:
|
||||||
lgdt [gp]
|
; lgdt [gp]
|
||||||
ret
|
; ret
|
||||||
|
|
||||||
; The first 32 interrupt service routines (ISR) entries correspond to exceptions.
|
; 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
|
; Some exceptions will push an error code onto the stack which is specific to
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <asm/tss.h>
|
#include <asm/tss.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define MAX_IST 3
|
#define MAX_IST 3
|
||||||
|
|
||||||
gdt_ptr_t gp;
|
gdt_ptr_t gp;
|
||||||
|
@ -160,3 +161,4 @@ void gdt_install(void)
|
||||||
/* Flush out the old GDT and install the new changes! */
|
/* Flush out the old GDT and install the new changes! */
|
||||||
gdt_flush();
|
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")
|
"HermitCore current version")
|
||||||
|
|
||||||
set(MAX_CORES "512" CACHE STRING
|
set(MAX_CORES "512" CACHE STRING
|
||||||
|
|
|
@ -100,6 +100,7 @@ rcce_mpb_t* rcce_mpb = NULL;
|
||||||
|
|
||||||
extern void signal_init(void);
|
extern void signal_init(void);
|
||||||
extern void rust_main(void);
|
extern void rust_main(void);
|
||||||
|
extern void rust_init(void);
|
||||||
|
|
||||||
static int hermit_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);
|
memcpy((char*) &percore_start + i*sz, (char*) &percore_start, sz);
|
||||||
|
|
||||||
koutput_init();
|
koutput_init();
|
||||||
|
rust_init();
|
||||||
system_init();
|
system_init();
|
||||||
irq_init();
|
irq_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "hermit-rs"
|
name = "hermit-rs"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
authors = [
|
authors = [
|
||||||
"Stefan Lankes <slankes@eonerc.rwth-aachen.de>",
|
"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.
|
// Export our platform-specific modules.
|
||||||
#[cfg(target_arch="x86_64")]
|
#[cfg(target_arch="x86_64")]
|
||||||
pub use self::x86_64::{processor};
|
pub use self::x86_64::{processor, gdt};
|
||||||
|
|
||||||
// Implementations for x86_64.
|
// Implementations for x86_64.
|
||||||
#[cfg(target_arch="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.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
pub mod processor;
|
pub mod processor;
|
||||||
|
pub mod gdt;
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#![cfg(target_arch = "x86_64")]
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use logging::*;
|
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.
|
// 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/)
|
* 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).
|
* 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]
|
#![no_std]
|
||||||
|
|
||||||
extern crate rlibc;
|
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.
|
// These need to be visible to the linker, so we need to export them.
|
||||||
pub use runtime_glue::*;
|
pub use runtime_glue::*;
|
||||||
pub use logging::*;
|
pub use logging::*;
|
||||||
|
pub use consts::*;
|
||||||
|
|
||||||
|
#[cfg(target_arch="x86_64")]
|
||||||
|
pub use arch::gdt::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -46,17 +50,16 @@ mod logging;
|
||||||
mod runtime_glue;
|
mod runtime_glue;
|
||||||
mod console;
|
mod console;
|
||||||
mod arch;
|
mod arch;
|
||||||
|
mod consts;
|
||||||
|
|
||||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() {
|
pub extern "C" fn rust_init() {
|
||||||
info!("HermitCore's Rust runtime! v{}", VERSION);
|
info!("HermitCore's Rust runtime! v{}", VERSION);
|
||||||
|
}
|
||||||
arch::processor::cpu_detection();
|
|
||||||
|
#[no_mangle]
|
||||||
//info!("info");
|
pub extern "C" fn rust_main() {
|
||||||
//warn!("warning");
|
arch::processor::cpu_detection();
|
||||||
//debug!("debug");
|
|
||||||
//error!("oops");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// 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.
|
/// Print formatted text to our console.
|
||||||
///
|
///
|
||||||
/// From http://blog.phil-opp.com/rust-os/printing-to-screen.html, but tweaked
|
/// 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-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
"os": "none",
|
"os": "none",
|
||||||
|
|
Loading…
Add table
Reference in a new issue