Merge branch 'master' of github.com:redox-os/kernel

This commit is contained in:
ticki 2016-08-14 20:55:19 +02:00
commit 1c9b6361c9
22 changed files with 198 additions and 115 deletions

View file

@ -3,8 +3,12 @@ name = "kernel"
version = "0.1.0"
[lib]
path = "kernel/lib.rs"
crate-type = ["staticlib"]
[target.'cfg(target_arch = "x86_64")'.dependencies]
arch = { path = "arch/x86_64" }
[dependencies]
bitflags = "*"

6
arch/x86_64/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "arch"
version = "0.1.0"
[dependencies]
bitflags = "*"

View file

@ -0,0 +1,19 @@
//! Interrupt instructions
/// Clear interrupts
#[inline(always)]
pub unsafe fn clear_interrupts() {
asm!("cli" : : : : "intel", "volatile");
}
/// Set interrupts
#[inline(always)]
pub unsafe fn set_interrupts() {
asm!("sti" : : : : "intel", "volatile");
}
/// Halt instruction
#[inline(always)]
pub unsafe fn halt() {
asm!("hlt" : : : : "intel", "volatile");
}

94
arch/x86_64/src/lib.rs Normal file
View file

@ -0,0 +1,94 @@
//! Architecture support for x86_64
#![feature(asm)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(naked_functions)]
#![no_std]
#[macro_use]
extern crate bitflags;
/// Print to console
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ({
use core::fmt::Write;
let _ = write!($crate::serial::SerialConsole::new(), $($arg)*);
});
}
/// Print with new line to console
#[macro_export]
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
/// Create an interrupt function that can safely run rust code
#[macro_export]
macro_rules! interrupt {
($name:ident, $func:block) => {
#[naked]
pub unsafe extern fn $name () {
unsafe fn inner() {
$func
}
// Push scratch registers
asm!("push rax
push rcx
push rdx
push rdi
push rsi
push r8
push r9
push r10
push r11"
: : : : "intel", "volatile");
// Call inner rust function
inner();
// Pop scratch registers and return
asm!("pop r11
pop r10
pop r9
pop r8
pop rsi
pop rdi
pop rdx
pop rcx
pop rax
iretq"
: : : : "intel", "volatile");
}
};
}
/// Global descriptor table
pub mod gdt;
/// Interrupt descriptor table
pub mod idt;
/// IO Handling
pub mod io;
/// Interrupt instructions
pub mod interrupt;
/// Initialization and main function
pub mod main;
/// Memcpy, memmove, etc.
pub mod mem;
/// Serial driver and print! support
pub mod serial;
/// Task state segment
pub mod tss;
pub mod physical;

View file

@ -30,8 +30,12 @@ static BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in BSS.
static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF;
extern {
fn kmain() -> !;
}
#[no_mangle]
pub unsafe extern "C" fn kmain() {
pub unsafe extern fn kstart() -> ! {
asm!("xchg bx, bx" : : : : "intel", "volatile");
// Zero BSS, this initializes statics that are set to 0
@ -44,8 +48,8 @@ pub unsafe extern "C" fn kmain() {
memset(start_ptr, 0, size);
}
//debug_assert_eq!(BSS_TEST_ZERO, 0);
//debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
debug_assert_eq!(BSS_TEST_ZERO, 0);
debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
}
asm!("xchg bx, bx" : : : : "intel", "volatile");
@ -64,15 +68,9 @@ pub unsafe extern "C" fn kmain() {
asm!("xchg bx, bx" : : : : "intel", "volatile");
print!("TEST\n");
loop{
asm!("hlt" : : : : "intel", "volatile");
}
kmain();
}
#[naked]
pub unsafe extern "C" fn blank() {
asm!("xchg bx, bx" : : : : "intel", "volatile");
asm!("iretq" : : : : "intel", "volatile");
}
interrupt!(blank, {
println!("INTERRUPT");
});

View file

@ -1,8 +1,9 @@
/// Copy memory.
/// Memcpy
///
/// Copy N bytes of memory from one location to another.
#[no_mangle]
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
n: usize) -> *mut u8 {
let mut i = 0;
while i < n {
*dest.offset(i as isize) = *src.offset(i as isize);
@ -12,7 +13,7 @@ pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8
dest
}
/// Copy (possibly overlapping) memory.
/// Memmove
///
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
#[no_mangle]
@ -35,7 +36,7 @@ pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
dest
}
/// Set memory.
/// Memset
///
/// Fill a block of memory with a specified value.
#[no_mangle]
@ -49,7 +50,7 @@ pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
s
}
/// Compare memory.
/// Memcmp
///
/// Compare two blocks of memory.
#[no_mangle]

20
arch/x86_64/src/tss.rs Normal file
View file

@ -0,0 +1,20 @@
#[repr(packed)]
pub struct Tss {
pub reserved1: u32,
pub sp0: u64,
pub sp1: u64,
pub sp2: u64,
pub reserved2: u32,
pub reserved3: u32,
pub ist1: u64,
pub ist2: u64,
pub ist3: u64,
pub ist4: u64,
pub ist5: u64,
pub ist6: u64,
pub ist7: u64,
pub reserved4: u32,
pub reserved5: u32,
pub reserved6: u16,
pub iomap_base: u16,
}

View file

@ -1,4 +1,4 @@
ENTRY(kmain)
ENTRY(kstart)
SECTIONS {
kernel_base = 0x101000;

View file

@ -1,7 +0,0 @@
//! Architecture specific items
#[cfg(target_arch = "x86_64")]
pub use self::x86_64::*;
#[cfg(target_arch = "x86_64")]
pub mod x86_64;

View file

@ -1,10 +0,0 @@
//! # IRQ handling
//!
//! This module defines IRQ handling functions. These functions should all be #[naked],
//! unsafe, extern, and end in `iretq`
/// Interupt Request handler.
#[naked]
pub unsafe extern fn irq() {
}

View file

@ -1,27 +0,0 @@
//! X86_64 architecture primitives.
/// Global descriptor table.
pub mod gdt;
/// Interrupt descriptor table.
pub mod idt;
/// IO handling.
pub mod io;
/// IRQ handling.
pub mod irq;
/// Initialization and main function.
pub mod main;
/// Core memory routines.
pub mod mem;
/// Serial driver and `print!` support.
pub mod serial;
/// Task state segment.
pub mod tss;
pub mod physical;

View file

@ -1,22 +0,0 @@
/// The Task State Segment.
#[repr(C, packed)]
#[derive(Debug, Default, Clone)]
pub struct Tss {
/// Reserved.
pub _reserved1: u32,
/// The stack-pointers (reg RSP) for the IO privilege level 0 through 2.
pub rsp: [u64; 3],
/// Reserved.
pub _reserved2: u32,
/// Reserved.
pub _reserved3: u32,
pub ist: [u64; 7],
/// Reserved.
pub _reserved4: u32,
/// Reserved.
pub _reserved5: u32,
// Reserved.
pub reserved6: u16,
/// The offset to the IOPB.
pub iomap_base: u16,
}

View file

@ -64,45 +64,27 @@
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
#![feature(asm)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![no_std]
#[macro_use]
extern crate bitflags;
/// Print to console
macro_rules! print {
($($arg:tt)*) => ({
use $crate::core::fmt::Write;
let _ = write!($crate::arch::serial::SerialConsole::new(), $($arg)*);
});
}
/// Print with new line to console
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
use arch::interrupt::{set_interrupts, halt};
/// Architecture specific items
pub mod arch;
#[macro_use]
extern crate arch;
#[cfg(not(test))]
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
/// Intrinsics for panic handling
pub mod panic;
#[cfg(not(test))]
/// Required to handle panics
#[lang = "panic_fmt"]
extern "C" fn panic_fmt() -> ! {loop{}}
#[allow(non_snake_case)]
#[no_mangle]
/// Required to handle panics
pub extern "C" fn _Unwind_Resume() -> ! {
loop {}
pub extern fn kmain() {
println!("TEST");
unsafe { set_interrupts() };
loop {
unsafe { halt() };
}
}

25
kernel/panic.rs Normal file
View file

@ -0,0 +1,25 @@
//! Intrinsics for panic handling
use arch::interrupt::halt;
#[cfg(not(test))]
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
#[cfg(not(test))]
/// Required to handle panics
#[lang = "panic_fmt"]
extern "C" fn panic_fmt() -> ! {
loop {
unsafe { halt() };
}
}
#[allow(non_snake_case)]
#[no_mangle]
/// Required to handle panics
pub extern "C" fn _Unwind_Resume() -> ! {
loop {
unsafe { halt() }
}
}