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" version = "0.1.0"
[lib] [lib]
path = "kernel/lib.rs"
crate-type = ["staticlib"] crate-type = ["staticlib"]
[target.'cfg(target_arch = "x86_64")'.dependencies]
arch = { path = "arch/x86_64" }
[dependencies] [dependencies]
bitflags = "*" 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. /// Test of non-zero values in BSS.
static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF; static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF;
extern {
fn kmain() -> !;
}
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn kmain() { pub unsafe extern fn kstart() -> ! {
asm!("xchg bx, bx" : : : : "intel", "volatile"); asm!("xchg bx, bx" : : : : "intel", "volatile");
// Zero BSS, this initializes statics that are set to 0 // 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); memset(start_ptr, 0, size);
} }
//debug_assert_eq!(BSS_TEST_ZERO, 0); debug_assert_eq!(BSS_TEST_ZERO, 0);
//debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
} }
asm!("xchg bx, bx" : : : : "intel", "volatile"); asm!("xchg bx, bx" : : : : "intel", "volatile");
@ -64,15 +68,9 @@ pub unsafe extern "C" fn kmain() {
asm!("xchg bx, bx" : : : : "intel", "volatile"); asm!("xchg bx, bx" : : : : "intel", "volatile");
print!("TEST\n"); kmain();
loop{
asm!("hlt" : : : : "intel", "volatile");
}
} }
#[naked] interrupt!(blank, {
pub unsafe extern "C" fn blank() { println!("INTERRUPT");
asm!("xchg bx, bx" : : : : "intel", "volatile"); });
asm!("iretq" : : : : "intel", "volatile");
}

View file

@ -1,8 +1,9 @@
/// Copy memory. /// Memcpy
/// ///
/// Copy N bytes of memory from one location to another. /// Copy N bytes of memory from one location to another.
#[no_mangle] #[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; let mut i = 0;
while i < n { while i < n {
*dest.offset(i as isize) = *src.offset(i as isize); *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 dest
} }
/// Copy (possibly overlapping) memory. /// Memmove
/// ///
/// Copy N bytes of memory from src to dest. The memory areas may overlap. /// Copy N bytes of memory from src to dest. The memory areas may overlap.
#[no_mangle] #[no_mangle]
@ -35,7 +36,7 @@ pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
dest dest
} }
/// Set memory. /// Memset
/// ///
/// Fill a block of memory with a specified value. /// Fill a block of memory with a specified value.
#[no_mangle] #[no_mangle]
@ -49,7 +50,7 @@ pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
s s
} }
/// Compare memory. /// Memcmp
/// ///
/// Compare two blocks of memory. /// Compare two blocks of memory.
#[no_mangle] #[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 { SECTIONS {
kernel_base = 0x101000; 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. //! 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. //! 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(lang_items)]
#![feature(naked_functions)]
#![no_std] #![no_std]
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
/// Print to console use arch::interrupt::{set_interrupts, halt};
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)*));
}
/// Architecture specific items /// Architecture specific items
pub mod arch; #[macro_use]
extern crate arch;
#[cfg(not(test))] /// Intrinsics for panic handling
#[lang = "eh_personality"] pub mod panic;
extern "C" fn eh_personality() {}
#[cfg(not(test))]
/// Required to handle panics
#[lang = "panic_fmt"]
extern "C" fn panic_fmt() -> ! {loop{}}
#[allow(non_snake_case)]
#[no_mangle] #[no_mangle]
/// Required to handle panics pub extern fn kmain() {
pub extern "C" fn _Unwind_Resume() -> ! { println!("TEST");
loop {}
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() }
}
}