this shit compiles but crashes after fighting for eternity with the borrow checker
This commit is contained in:
parent
0f5bf89493
commit
edfffc3b13
8 changed files with 109 additions and 68 deletions
|
|
@ -9,3 +9,7 @@ crate-type = ["staticlib"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rlibc = "1.0"
|
rlibc = "1.0"
|
||||||
multiboot2 = { path = "multiboot2-elf64" }
|
multiboot2 = { path = "multiboot2-elf64" }
|
||||||
|
|
||||||
|
[dependencies.lazy_static]
|
||||||
|
version = "0.2.4"
|
||||||
|
features = ["spin_no_std"]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ extern crate multiboot2;
|
||||||
use acpi;
|
use acpi;
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use core::char;
|
use core::char;
|
||||||
use context::CONTEXT;
|
use context::*;
|
||||||
use vga::*;
|
use vga::*;
|
||||||
|
|
||||||
fn dispatch(command: &str) -> Result <(), &'static str> {
|
fn dispatch(command: &str) -> Result <(), &'static str> {
|
||||||
|
|
@ -120,7 +120,7 @@ fn print_stack() -> Result <(), &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mb2_memory() -> Result <(), &'static str> {
|
fn mb2_memory() -> Result <(), &'static str> {
|
||||||
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
|
let boot_info = &context().boot_info;
|
||||||
|
|
||||||
let memory_map_tag = boot_info.memory_map_tag()
|
let memory_map_tag = boot_info.memory_map_tag()
|
||||||
.expect("Memory map tag required");
|
.expect("Memory map tag required");
|
||||||
|
|
@ -134,7 +134,8 @@ fn mb2_memory() -> Result <(), &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mb2_sections() -> Result <(), &'static str> {
|
fn mb2_sections() -> Result <(), &'static str> {
|
||||||
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
|
let boot_info = &context().boot_info;
|
||||||
|
|
||||||
let elf_sections_tag = boot_info.elf_sections_tag()
|
let elf_sections_tag = boot_info.elf_sections_tag()
|
||||||
.expect("Elf-sections tag required");
|
.expect("Elf-sections tag required");
|
||||||
|
|
||||||
|
|
@ -147,7 +148,7 @@ fn mb2_sections() -> Result <(), &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mb2_info() -> Result <(), &'static str> {
|
fn mb2_info() -> Result <(), &'static str> {
|
||||||
let boot_info = unsafe { multiboot2::load(CONTEXT.boot_info_addr) };
|
let boot_info = &context().boot_info;
|
||||||
|
|
||||||
let command_line_tag = boot_info.command_line_tag()
|
let command_line_tag = boot_info.command_line_tag()
|
||||||
.expect("Elf-sections tag required");
|
.expect("Elf-sections tag required");
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,56 @@
|
||||||
extern crate core;
|
use multiboot2;
|
||||||
|
use memory;
|
||||||
use vga;
|
use vga;
|
||||||
|
use cpuio;
|
||||||
|
|
||||||
pub static mut CONTEXT: Context = Context {
|
pub static mut CONTEXT: Option<Context> = None;
|
||||||
current_term: 0,
|
|
||||||
boot_info_addr: 0,
|
|
||||||
vga1: vga::Writer::new(),
|
|
||||||
vga2: vga::Writer::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub current_term: u8,
|
pub current_term: u8,
|
||||||
pub boot_info_addr: usize,
|
pub multiboot_start: usize,
|
||||||
|
pub multiboot_end: usize,
|
||||||
|
pub kernel_start: usize,
|
||||||
|
pub kernel_end: usize,
|
||||||
|
pub boot_info: multiboot2::BootInformation,
|
||||||
|
pub frame_allocator: memory::AreaFrameAllocator,
|
||||||
pub vga1: vga::Writer,
|
pub vga1: vga::Writer,
|
||||||
pub vga2: vga::Writer,
|
pub vga2: vga::Writer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context
|
||||||
|
{
|
||||||
|
pub fn new(multiboot_start: usize) -> Context {
|
||||||
|
let boot_info = multiboot2::load(multiboot_start);
|
||||||
|
let multiboot_end = multiboot_start + boot_info.total_size();
|
||||||
|
|
||||||
|
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
|
||||||
|
let memory_map_tag = boot_info.memory_map_tag().unwrap();
|
||||||
|
|
||||||
|
let kernel_start = elf_sections_tag.sections().map(
|
||||||
|
|s| s.start_address())
|
||||||
|
.min().unwrap() as usize;
|
||||||
|
let kernel_end = elf_sections_tag.sections().map(
|
||||||
|
|s| s.start_address() + s.size())
|
||||||
|
.max().unwrap() as usize;
|
||||||
|
|
||||||
|
let frame_allocator = memory::AreaFrameAllocator::new(
|
||||||
|
kernel_start, kernel_end, multiboot_start,
|
||||||
|
multiboot_end, memory_map_tag.memory_areas());
|
||||||
|
|
||||||
|
Context {
|
||||||
|
current_term: 0,
|
||||||
|
multiboot_start,
|
||||||
|
multiboot_end,
|
||||||
|
kernel_start,
|
||||||
|
kernel_end,
|
||||||
|
boot_info,
|
||||||
|
frame_allocator,
|
||||||
|
vga1: vga::Writer::new(),
|
||||||
|
vga2: vga::Writer::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn switch_term(&mut self) {
|
pub fn switch_term(&mut self) {
|
||||||
self.current_term = {
|
self.current_term = {
|
||||||
if self.current_term == 0 { 1 }
|
if self.current_term == 0 { 1 }
|
||||||
|
|
@ -33,3 +67,11 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn context() -> Context {
|
||||||
|
unsafe {
|
||||||
|
match CONTEXT.take() {
|
||||||
|
Some(context) => context,
|
||||||
|
None => panic!("heeelp"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use context::CONTEXT;
|
use context::*;
|
||||||
|
|
||||||
const MAX_KEYS: usize = 59;
|
const MAX_KEYS: usize = 59;
|
||||||
const KEYMAP_US: [[u8;2]; MAX_KEYS] = [
|
const KEYMAP_US: [[u8;2]; MAX_KEYS] = [
|
||||||
|
|
@ -93,23 +93,18 @@ pub fn kbd_callback() {
|
||||||
0x38 => {ALT = !is_release},
|
0x38 => {ALT = !is_release},
|
||||||
0x1D => {CTRL = !is_release},
|
0x1D => {CTRL = !is_release},
|
||||||
0x0F if !is_release => {
|
0x0F if !is_release => {
|
||||||
CONTEXT.switch_term();
|
context().switch_term();
|
||||||
CONTEXT.current_term().flush();
|
context().current_term().flush();
|
||||||
},
|
},
|
||||||
0x0E if !is_release => {
|
0x0E if !is_release => {
|
||||||
CONTEXT.current_term().backspace();
|
context().current_term().backspace();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(ascii) if !is_release => {
|
Some(ascii) if !is_release => {
|
||||||
let mut terminal = CONTEXT.current_term();
|
let sym = if SHIFT { ascii[1] } else { ascii[0] };
|
||||||
if SHIFT {
|
context().current_term().keypress(sym);
|
||||||
terminal.keypress(ascii[1]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
terminal.keypress(ascii[0]);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Some(_) => {},
|
Some(_) => {},
|
||||||
None =>{},
|
None =>{},
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
extern crate rlibc;
|
extern crate rlibc;
|
||||||
extern crate multiboot2; //slightly modified fork from official 0.3.2
|
extern crate multiboot2; //slightly modified fork from official 0.3.2
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
/// 80x25 screen and simplistic terminal driver
|
/// 80x25 screen and simplistic terminal driver
|
||||||
#[macro_use] pub mod vga;
|
#[macro_use] pub mod vga;
|
||||||
|
|
@ -24,21 +26,15 @@ pub mod acpi;
|
||||||
/// simple area frame allocator implementation
|
/// simple area frame allocator implementation
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
use context::CONTEXT;
|
use context::*;
|
||||||
|
|
||||||
fn init_kernel(multiboot_information_address: usize) -> Result <(), &'static str> {
|
|
||||||
unsafe { CONTEXT.boot_info_addr = multiboot_information_address };
|
|
||||||
acpi::init()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
use vga::{Color, ColorCode};
|
use vga::{Color, ColorCode};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn kmain(multiboot_information_address: usize) -> ! {
|
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
||||||
if let Err(msg) = init_kernel(multiboot_information_address) {
|
unsafe { CONTEXT = Some(Context::new(multiboot_info_addr)) };
|
||||||
println!("Kernel initialization has failed: {}", msg);
|
acpi::init().unwrap();
|
||||||
cpuio::halt();
|
|
||||||
}
|
|
||||||
set_color!(White, Cyan);
|
set_color!(White, Cyan);
|
||||||
print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
|
print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
|
||||||
format_args!("{: ^80}", r#" ,--, "#),
|
format_args!("{: ^80}", r#" ,--, "#),
|
||||||
|
|
@ -57,9 +53,7 @@ pub extern fn kmain(multiboot_information_address: usize) -> ! {
|
||||||
format_args!("{: ^80}", r#" '--' `---' "#));
|
format_args!("{: ^80}", r#" '--' `---' "#));
|
||||||
set_color!();
|
set_color!();
|
||||||
|
|
||||||
unsafe { CONTEXT.vga1.prompt();CONTEXT.vga1.flush(); }
|
context();
|
||||||
unsafe { CONTEXT.vga2.prompt(); }
|
|
||||||
|
|
||||||
loop { keyboard::kbd_callback(); }
|
loop { keyboard::kbd_callback(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use memory::*;
|
use memory::*;
|
||||||
use multiboot2::{MemoryAreaIter, MemoryArea};
|
use multiboot2::{MemoryAreaIter, MemoryArea};
|
||||||
|
|
||||||
pub struct AreaAllocator {
|
pub struct AreaFrameAllocator {
|
||||||
next_free_frame: Frame,
|
next_free_frame: Frame,
|
||||||
current_area: Option<&'static MemoryArea>,
|
current_area: Option<&'static MemoryArea>,
|
||||||
areas: MemoryAreaIter,
|
areas: MemoryAreaIter,
|
||||||
|
|
@ -12,10 +12,10 @@ pub struct AreaAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AreaFrameAllocator {
|
impl AreaFrameAllocator {
|
||||||
pub fn new(kernel_start: usize, kernel_end: usize
|
pub fn new(kernel_start: usize, kernel_end: usize,
|
||||||
multiboot_start: usize, multiboot_end: usize
|
multiboot_start: usize, multiboot_end: usize,
|
||||||
memory_areas: MemoryAreaIter) -> AreaAllocator {
|
memory_areas: MemoryAreaIter) -> AreaFrameAllocator {
|
||||||
let mut allocator = AreaAllocator {
|
let mut allocator = AreaFrameAllocator {
|
||||||
next_free_frame: Frame::containing_address(0),
|
next_free_frame: Frame::containing_address(0),
|
||||||
current_area: None,
|
current_area: None,
|
||||||
areas: memory_areas,
|
areas: memory_areas,
|
||||||
|
|
@ -23,7 +23,7 @@ impl AreaFrameAllocator {
|
||||||
kernel_end: Frame::containing_address(kernel_end),
|
kernel_end: Frame::containing_address(kernel_end),
|
||||||
multiboot_start: Frame::containing_address(multiboot_start),
|
multiboot_start: Frame::containing_address(multiboot_start),
|
||||||
multiboot_end: Frame::containing_address(multiboot_end),
|
multiboot_end: Frame::containing_address(multiboot_end),
|
||||||
}
|
};
|
||||||
allocator.choose_next_area();
|
allocator.choose_next_area();
|
||||||
allocator
|
allocator
|
||||||
}
|
}
|
||||||
|
|
@ -32,10 +32,10 @@ impl AreaFrameAllocator {
|
||||||
// get next area with free frames
|
// get next area with free frames
|
||||||
self.current_area = self.areas.clone().filter(|area| {
|
self.current_area = self.areas.clone().filter(|area| {
|
||||||
Frame::containing_address(area.end_address()) >= self.next_free_frame
|
Frame::containing_address(area.end_address()) >= self.next_free_frame
|
||||||
}).min_by_key(|area| area.start_addr());
|
}).min_by_key(|area| area.start_address());
|
||||||
|
|
||||||
if let Some(area) = self.current_area {
|
if let Some(area) = self.current_area {
|
||||||
let start_frame = Frame::containing_address(area.start_addr());
|
let start_frame = Frame::containing_address(area.start_address());
|
||||||
if self.next_free_frame < start_frame {
|
if self.next_free_frame < start_frame {
|
||||||
self.next_free_frame = start_frame;
|
self.next_free_frame = start_frame;
|
||||||
}
|
}
|
||||||
|
|
@ -45,27 +45,31 @@ impl AreaFrameAllocator {
|
||||||
|
|
||||||
impl FrameAllocator for AreaFrameAllocator {
|
impl FrameAllocator for AreaFrameAllocator {
|
||||||
fn allocate_frame(&mut self) -> Option<Frame> {
|
fn allocate_frame(&mut self) -> Option<Frame> {
|
||||||
if let Some(area) = sef.current_area {
|
if let Some(area) = self.current_area {
|
||||||
let frame = Frame { number: self.next_free_frame.number },
|
let frame = Frame { number: self.next_free_frame.number };
|
||||||
let current_area_last_frame = Frame::containing_address(area.end_address());
|
let current_area_last_frame = Frame::containing_address(area.end_address());
|
||||||
if frame > current_area_last_frame {
|
if frame > current_area_last_frame {
|
||||||
// all frames are taken in this area
|
// all frames are taken in this area
|
||||||
self.choose_next_area();
|
self.choose_next_area();
|
||||||
} else if frame >= self.kernel_start && frame <= kernel_end {
|
} else if frame >= self.kernel_start && frame <= self.kernel_end {
|
||||||
// frame used by kernel
|
// frame used by kernel
|
||||||
self.next_free_frame = Frame {
|
self.next_free_frame = Frame {
|
||||||
number: self.kernel_end.number + 1;
|
number: self.kernel_end.number + 1,
|
||||||
}
|
}
|
||||||
} else if frame >= self.multiboot_start && frame <= multiboot_end {
|
} else if frame >= self.multiboot_start && frame <= self.multiboot_end {
|
||||||
// frame used by multiboot
|
// frame used by multiboot
|
||||||
self.next_free_frame = Frame {
|
self.next_free_frame = Frame {
|
||||||
number: self.multiboot_end.number + 1;
|
number: self.multiboot_end.number + 1,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.next_free_frame_number += 1;
|
self.next_free_frame.number += 1;
|
||||||
return Some(Frame);
|
return Some(frame);
|
||||||
|
}
|
||||||
|
// try again with next_free_frame
|
||||||
|
self.allocate_frame()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
} else { None }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deallocate_frame(&mut self, frame: Frame) {
|
fn deallocate_frame(&mut self, frame: Frame) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
pub const PAGE_SIZE: usize = 4096;
|
pub const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
// pub use self::area_allocator::*;
|
mod area_allocator;
|
||||||
|
|
||||||
|
pub use self::area_allocator::*;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
#[macro_use]
|
|
||||||
pub mod color;
|
pub mod color;
|
||||||
|
|
||||||
pub use self::color::{Color, ColorCode};
|
pub use self::color::{Color, ColorCode};
|
||||||
|
|
||||||
use ::context::CONTEXT;
|
use context::*;
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use ::console;
|
use console;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -26,21 +25,21 @@ macro_rules! println {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! flush {
|
macro_rules! flush {
|
||||||
() => (unsafe { CONTEXT.current_term().flush() });
|
() => (context().current_term().flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! set_color {
|
macro_rules! set_color {
|
||||||
() => (unsafe { CONTEXT.current_term().color_code =
|
() => (context().current_term().color_code =
|
||||||
ColorCode::new(Color::White, Color::Black) });
|
ColorCode::new(Color::White, Color::Black));
|
||||||
($fg:ident) => (unsafe { CONTEXT.current_term().color_code =
|
($fg:ident) => (context().current_term().color_code =
|
||||||
ColorCode::new(Color::$fg, Color::Black) });
|
ColorCode::new(Color::$fg, Color::Black));
|
||||||
($fg:ident, $bg:ident) => (unsafe { CONTEXT.current_term().color_code =
|
($fg:ident, $bg:ident) => (context().current_term().color_code =
|
||||||
ColorCode::new(Color::$fg, Color::$bg) });
|
ColorCode::new(Color::$fg, Color::$bg));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print(args: fmt::Arguments) {
|
pub fn print(args: fmt::Arguments) {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
unsafe { CONTEXT.current_term().write_fmt(args).unwrap() };
|
context().current_term().write_fmt(args).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue