From 2730144e2aa1174125bfd1406f21c621555f7682 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 14 Aug 2016 11:45:47 -0600 Subject: [PATCH 1/3] Move arch to seperate crate --- Cargo.toml | 4 ++ arch/x86_64/Cargo.toml | 6 ++ .../arch/x86_64 => arch/x86_64/src}/gdt.rs | 0 .../arch/x86_64 => arch/x86_64/src}/idt.rs | 0 arch/x86_64/src/interrupt.rs | 19 +++++++ .../arch/x86_64 => arch/x86_64/src}/io/io.rs | 0 .../x86_64 => arch/x86_64/src}/io/mmio.rs | 0 .../arch/x86_64 => arch/x86_64/src}/io/mod.rs | 0 .../arch/x86_64 => arch/x86_64/src}/io/pio.rs | 0 .../arch/x86_64 => arch/x86_64/src}/irq.rs | 0 arch/x86_64/src/lib.rs | 55 +++++++++++++++++++ .../arch/x86_64 => arch/x86_64/src}/main.rs | 18 +++--- .../arch/x86_64 => arch/x86_64/src}/mem.rs | 11 ++-- .../x86_64 => arch/x86_64/src}/physical.rs | 0 .../arch/x86_64 => arch/x86_64/src}/serial.rs | 0 arch/x86_64/src/tss.rs | 20 +++++++ bootloader/x86/kernel.ld | 2 +- kernel/arch/mod.rs | 7 --- kernel/arch/x86_64/mod.rs | 27 --------- kernel/arch/x86_64/tss.rs | 22 -------- kernel/lib.rs | 41 ++++---------- kernel/panic.rs | 25 +++++++++ 22 files changed, 156 insertions(+), 101 deletions(-) create mode 100644 arch/x86_64/Cargo.toml rename {kernel/arch/x86_64 => arch/x86_64/src}/gdt.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/idt.rs (100%) create mode 100644 arch/x86_64/src/interrupt.rs rename {kernel/arch/x86_64 => arch/x86_64/src}/io/io.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/io/mmio.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/io/mod.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/io/pio.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/irq.rs (100%) create mode 100644 arch/x86_64/src/lib.rs rename {kernel/arch/x86_64 => arch/x86_64/src}/main.rs (89%) rename {kernel/arch/x86_64 => arch/x86_64/src}/mem.rs (88%) rename {kernel/arch/x86_64 => arch/x86_64/src}/physical.rs (100%) rename {kernel/arch/x86_64 => arch/x86_64/src}/serial.rs (100%) create mode 100644 arch/x86_64/src/tss.rs delete mode 100644 kernel/arch/mod.rs delete mode 100644 kernel/arch/x86_64/mod.rs delete mode 100644 kernel/arch/x86_64/tss.rs create mode 100644 kernel/panic.rs diff --git a/Cargo.toml b/Cargo.toml index 577a595..6526084 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 = "*" diff --git a/arch/x86_64/Cargo.toml b/arch/x86_64/Cargo.toml new file mode 100644 index 0000000..1992ebe --- /dev/null +++ b/arch/x86_64/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "arch" +version = "0.1.0" + +[dependencies] +bitflags = "*" diff --git a/kernel/arch/x86_64/gdt.rs b/arch/x86_64/src/gdt.rs similarity index 100% rename from kernel/arch/x86_64/gdt.rs rename to arch/x86_64/src/gdt.rs diff --git a/kernel/arch/x86_64/idt.rs b/arch/x86_64/src/idt.rs similarity index 100% rename from kernel/arch/x86_64/idt.rs rename to arch/x86_64/src/idt.rs diff --git a/arch/x86_64/src/interrupt.rs b/arch/x86_64/src/interrupt.rs new file mode 100644 index 0000000..eb0bbba --- /dev/null +++ b/arch/x86_64/src/interrupt.rs @@ -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"); +} diff --git a/kernel/arch/x86_64/io/io.rs b/arch/x86_64/src/io/io.rs similarity index 100% rename from kernel/arch/x86_64/io/io.rs rename to arch/x86_64/src/io/io.rs diff --git a/kernel/arch/x86_64/io/mmio.rs b/arch/x86_64/src/io/mmio.rs similarity index 100% rename from kernel/arch/x86_64/io/mmio.rs rename to arch/x86_64/src/io/mmio.rs diff --git a/kernel/arch/x86_64/io/mod.rs b/arch/x86_64/src/io/mod.rs similarity index 100% rename from kernel/arch/x86_64/io/mod.rs rename to arch/x86_64/src/io/mod.rs diff --git a/kernel/arch/x86_64/io/pio.rs b/arch/x86_64/src/io/pio.rs similarity index 100% rename from kernel/arch/x86_64/io/pio.rs rename to arch/x86_64/src/io/pio.rs diff --git a/kernel/arch/x86_64/irq.rs b/arch/x86_64/src/irq.rs similarity index 100% rename from kernel/arch/x86_64/irq.rs rename to arch/x86_64/src/irq.rs diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs new file mode 100644 index 0000000..c9e6a5b --- /dev/null +++ b/arch/x86_64/src/lib.rs @@ -0,0 +1,55 @@ +//! Architecture support for x86_64 + +#![feature(asm)] +#![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)*)); +} + +/// Global descriptor table +pub mod gdt; + +/// Interrupt descriptor table +pub mod idt; + +/// IO Handling +pub mod io; + +/// IRQ Handling +pub mod irq; + +/// 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; diff --git a/kernel/arch/x86_64/main.rs b/arch/x86_64/src/main.rs similarity index 89% rename from kernel/arch/x86_64/main.rs rename to arch/x86_64/src/main.rs index 50748b1..ad9640a 100644 --- a/kernel/arch/x86_64/main.rs +++ b/arch/x86_64/src/main.rs @@ -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,11 @@ 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() { +pub unsafe extern fn blank() { asm!("xchg bx, bx" : : : : "intel", "volatile"); asm!("iretq" : : : : "intel", "volatile"); } diff --git a/kernel/arch/x86_64/mem.rs b/arch/x86_64/src/mem.rs similarity index 88% rename from kernel/arch/x86_64/mem.rs rename to arch/x86_64/src/mem.rs index 8e1678c..3b87427 100644 --- a/kernel/arch/x86_64/mem.rs +++ b/arch/x86_64/src/mem.rs @@ -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] diff --git a/kernel/arch/x86_64/physical.rs b/arch/x86_64/src/physical.rs similarity index 100% rename from kernel/arch/x86_64/physical.rs rename to arch/x86_64/src/physical.rs diff --git a/kernel/arch/x86_64/serial.rs b/arch/x86_64/src/serial.rs similarity index 100% rename from kernel/arch/x86_64/serial.rs rename to arch/x86_64/src/serial.rs diff --git a/arch/x86_64/src/tss.rs b/arch/x86_64/src/tss.rs new file mode 100644 index 0000000..b1034b8 --- /dev/null +++ b/arch/x86_64/src/tss.rs @@ -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, +} diff --git a/bootloader/x86/kernel.ld b/bootloader/x86/kernel.ld index f19fe7f..19f0f2c 100644 --- a/bootloader/x86/kernel.ld +++ b/bootloader/x86/kernel.ld @@ -1,4 +1,4 @@ -ENTRY(kmain) +ENTRY(kstart) SECTIONS { kernel_base = 0x101000; diff --git a/kernel/arch/mod.rs b/kernel/arch/mod.rs deleted file mode 100644 index 924dc1a..0000000 --- a/kernel/arch/mod.rs +++ /dev/null @@ -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; diff --git a/kernel/arch/x86_64/mod.rs b/kernel/arch/x86_64/mod.rs deleted file mode 100644 index d5180fc..0000000 --- a/kernel/arch/x86_64/mod.rs +++ /dev/null @@ -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; diff --git a/kernel/arch/x86_64/tss.rs b/kernel/arch/x86_64/tss.rs deleted file mode 100644 index 389de39..0000000 --- a/kernel/arch/x86_64/tss.rs +++ /dev/null @@ -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, -} diff --git a/kernel/lib.rs b/kernel/lib.rs index 23c0a18..b99e777 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -64,45 +64,26 @@ //! 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() {} +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() }; + } } diff --git a/kernel/panic.rs b/kernel/panic.rs new file mode 100644 index 0000000..fb90cfd --- /dev/null +++ b/kernel/panic.rs @@ -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() } + } +} From b130f9a8607d3463c0bd189e188b2d31b8cc9a50 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 14 Aug 2016 12:08:42 -0600 Subject: [PATCH 2/3] Magic to make interrupt functions easy to write --- arch/x86_64/src/irq.rs | 10 --------- arch/x86_64/src/lib.rs | 45 ++++++++++++++++++++++++++++++++++++++--- arch/x86_64/src/main.rs | 8 +++----- 3 files changed, 45 insertions(+), 18 deletions(-) delete mode 100644 arch/x86_64/src/irq.rs diff --git a/arch/x86_64/src/irq.rs b/arch/x86_64/src/irq.rs deleted file mode 100644 index bbceaa7..0000000 --- a/arch/x86_64/src/irq.rs +++ /dev/null @@ -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() { - -} diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs index c9e6a5b..3b03958 100644 --- a/arch/x86_64/src/lib.rs +++ b/arch/x86_64/src/lib.rs @@ -1,6 +1,7 @@ //! Architecture support for x86_64 #![feature(asm)] +#![feature(concat_idents)] #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(naked_functions)] @@ -25,6 +26,47 @@ macro_rules! println { ($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; @@ -34,9 +76,6 @@ pub mod idt; /// IO Handling pub mod io; -/// IRQ Handling -pub mod irq; - /// Interrupt instructions pub mod interrupt; diff --git a/arch/x86_64/src/main.rs b/arch/x86_64/src/main.rs index ad9640a..a17d19c 100644 --- a/arch/x86_64/src/main.rs +++ b/arch/x86_64/src/main.rs @@ -71,8 +71,6 @@ pub unsafe extern fn kstart() -> ! { kmain(); } -#[naked] -pub unsafe extern fn blank() { - asm!("xchg bx, bx" : : : : "intel", "volatile"); - asm!("iretq" : : : : "intel", "volatile"); -} +interrupt!(blank, { + println!("INTERRUPT"); +}); From ef22aafb60eb960b936e5365333130ec7f6fbd88 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 14 Aug 2016 12:11:53 -0600 Subject: [PATCH 3/3] Add comment --- kernel/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/lib.rs b/kernel/lib.rs index b99e777..d9353c7 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -76,6 +76,7 @@ use arch::interrupt::{set_interrupts, halt}; #[macro_use] extern crate arch; +/// Intrinsics for panic handling pub mod panic; #[no_mangle]