heap allocations

This commit is contained in:
charlesbvll 2021-07-23 18:35:33 +02:00
parent c8b71f2294
commit ec9264620b
6 changed files with 136 additions and 30 deletions

View File

@ -1,6 +1,6 @@
[unstable]
build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins"]
build-std = ["core", "compiler_builtins", "alloc"]
[build]
target = "x86_64-rust_os.json"

41
Cargo.lock generated
View File

@ -29,6 +29,30 @@ dependencies = [
"spin",
]
[[package]]
name = "linked_list_allocator"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0b725207570aa16096962d0b20c79f8a543df2280bd3c903022b9b0b4d7ea68"
dependencies = [
"spinning_top",
]
[[package]]
name = "lock_api"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
dependencies = [
"scopeguard",
]
[[package]]
name = "pc-keyboard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
[[package]]
name = "pic8259"
version = "0.10.1"
@ -44,6 +68,8 @@ version = "0.1.0"
dependencies = [
"bootloader",
"lazy_static",
"linked_list_allocator",
"pc-keyboard",
"pic8259",
"spin",
"uart_16550",
@ -51,12 +77,27 @@ dependencies = [
"x86_64",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spinning_top"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75adad84ee84b521fb2cca2d4fd0f1dab1d8d026bda3c5bea4ca63b5f9f9293c"
dependencies = [
"lock_api",
]
[[package]]
name = "uart_16550"
version = "0.2.15"

View File

@ -4,13 +4,14 @@ version = "0.1.0"
edition = "2018"
[dependencies]
bootloader = "0.9.8"
bootloader = { version = "0.9.8", features = ["map_physical_memory"]}
volatile = "0.2.6"
spin = "0.5.2"
x86_64 = "0.14.2"
uart_16550 = "0.2.0"
pic8259 = "0.10.1"
pc-keyboard = "0.5.0"
linked_list_allocator = "0.9.0"
[dependencies.lazy_static]
version = "1.0"

View File

@ -1,9 +1,17 @@
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use crate::println;
use crate::print;
use x86_64::structures::idt::{PageFaultErrorCode, InterruptDescriptorTable, InterruptStackFrame};
use pic8259::ChainedPics;
use lazy_static::lazy_static;
use crate::println;
use crate::print;
use crate::gdt;
use crate::hlt_loop;
use spin;
pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
lazy_static! {
static ref IDT: InterruptDescriptorTable = {
@ -17,10 +25,24 @@ lazy_static! {
.set_handler_fn(timer_interrupt_handler);
idt[InterruptIndex::Keyboard.as_usize()]
.set_handler_fn(keyboard_interrupt_handler);
idt.page_fault.set_handler_fn(page_fault_handler);
idt
};
}
extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control::Cr2;
println!("EXCEPTION: PAGE FAULT");
println!("Accessed Address: {:?}", Cr2::read());
println!("Error Code: {:?}", error_code);
println!("{:#?}", stack_frame);
hlt_loop();
}
extern "x86-interrupt" fn double_fault_handler(
stack_frame: InterruptStackFrame, _error_code: u64) -> !
{
@ -37,6 +59,12 @@ extern "x86-interrupt" fn timer_interrupt_handler(
}
}
extern "x86-interrupt" fn breakpoint_handler(
stack_frame: InterruptStackFrame)
{
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
extern "x86-interrupt" fn keyboard_interrupt_handler(
_stack_frame: InterruptStackFrame)
{
@ -75,23 +103,6 @@ pub fn init_idt() {
IDT.load();
}
#[test_case]
fn test_breakpoint_exception() {
x86_64::instructions::interrupts::int3();
}
extern "x86-interrupt" fn breakpoint_handler(
stack_frame: InterruptStackFrame)
{
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
use pic8259::ChainedPics;
use spin;
pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
pub static PICS: spin::Mutex<ChainedPics> =
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
@ -111,3 +122,8 @@ impl InterruptIndex {
usize::from(self.as_u8())
}
}
#[test_case]
fn test_breakpoint_exception() {
x86_64::instructions::interrupts::int3();
}

View File

@ -1,6 +1,7 @@
#![no_std]
#![cfg_attr(test, no_main)]
#![feature(custom_test_frameworks)]
#![feature(alloc_error_handler)]
#![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"]
#![feature(abi_x86_interrupt)]
@ -11,6 +12,16 @@ pub mod serial;
pub mod vga_buffer;
pub mod interrupts;
pub mod gdt;
pub mod memory;
pub mod allocator;
extern crate alloc;
#[cfg(test)]
use bootloader::{entry_point, BootInfo};
#[cfg(test)]
entry_point!(test_kernel_main);
pub trait Testable {
fn run(&self) -> ();
@ -50,9 +61,8 @@ pub fn init() {
}
#[cfg(test)]
#[no_mangle]
pub extern "C" fn _start() -> ! {
init(); // new
fn test_kernel_main(_boot_info: &'static BootInfo) -> ! {
init();
test_main();
hlt_loop();
}
@ -63,6 +73,11 @@ fn panic(info: &PanicInfo) -> ! {
test_panic_handler(info)
}
#[alloc_error_handler]
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
panic!("allocation error: {:?}", layout)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum QemuExitCode {

View File

@ -4,16 +4,50 @@
#![test_runner(rust_os::test_runner)]
#![reexport_test_harness_main = "test_main"]
extern crate alloc;
use alloc::{boxed::Box, vec, vec::Vec, rc::Rc};
use core::panic::PanicInfo;
use rust_os::println;
use bootloader::{BootInfo, entry_point};
use x86_64::VirtAddr;
entry_point!(kernel_main);
fn kernel_main(boot_info: &'static BootInfo) -> ! {
use rust_os::allocator;
use rust_os::memory::{self, BootInfoFrameAllocator};
#[no_mangle]
pub extern "C" fn _start() -> ! {
println!("Hello World{}", "!");
rust_os::init();
// as before
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
let mut mapper = unsafe { memory::init(phys_mem_offset) };
let mut frame_allocator = unsafe {
BootInfoFrameAllocator::init(&boot_info.memory_map)
};
allocator::init_heap(&mut mapper, &mut frame_allocator)
.expect("heap initialization failed");
// allocate a number on the heap
let heap_value = Box::new(41);
println!("heap_value at {:p}", heap_value);
// create a dynamically sized vector
let mut vec = Vec::new();
for i in 0..500 {
vec.push(i);
}
println!("vec at {:p}", vec.as_slice());
// create a reference counted vector -> will be freed when count reaches 0
let reference_counted = Rc::new(vec![1, 2, 3]);
let cloned_reference = reference_counted.clone();
println!("current reference count is {}", Rc::strong_count(&cloned_reference));
core::mem::drop(reference_counted);
println!("reference count is {} now", Rc::strong_count(&cloned_reference));
#[cfg(test)]
test_main();
@ -21,7 +55,6 @@ pub extern "C" fn _start() -> ! {
rust_os::hlt_loop();
}
/// This function is called on panic.
#[cfg(not(test))]
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {