Move arch to seperate crate
This commit is contained in:
parent
3967c0f291
commit
2730144e2a
|
@ -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
6
arch/x86_64/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "arch"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "*"
|
19
arch/x86_64/src/interrupt.rs
Normal file
19
arch/x86_64/src/interrupt.rs
Normal 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");
|
||||
}
|
55
arch/x86_64/src/lib.rs
Normal file
55
arch/x86_64/src/lib.rs
Normal file
|
@ -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;
|
|
@ -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");
|
||||
}
|
|
@ -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
20
arch/x86_64/src/tss.rs
Normal 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,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
ENTRY(kmain)
|
||||
ENTRY(kstart)
|
||||
|
||||
SECTIONS {
|
||||
kernel_base = 0x101000;
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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,
|
||||
}
|
|
@ -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() };
|
||||
}
|
||||
}
|
||||
|
|
25
kernel/panic.rs
Normal file
25
kernel/panic.rs
Normal 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() }
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue