Skip to content

Commit

Permalink
use heap and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Gege-Wang committed Aug 21, 2024
1 parent 00b4964 commit e0bf458
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -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-unknown-none"
Expand Down
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ x86_64 = "0.15.1"
uart_16550 = "0.2.0"
pic8259 = "0.10.0"
pc-keyboard = "0.7.0"
linked_list_allocator = "0.9.0"

[profile.dev]
#panic = "abort"
Expand Down
47 changes: 47 additions & 0 deletions src/allocator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use alloc::alloc::{GlobalAlloc, Layout};
use x86_64::{structures::paging::Page, VirtAddr};
use core::ptr::null_mut;
use x86_64::structures::paging::Size4KiB;
use crate::memory;
use x86_64::structures::paging::FrameAllocator;
use x86_64::structures::paging::mapper::{MapToError, Mapper};
use x86_64::structures::paging::PageTableFlags as Flags;
use linked_list_allocator::LockedHeap;
pub const HEAP_START: u64 = 0x4444_4444_0000;
pub const HEAP_SIZE: u64 = 100 * 1024; // 100 KiB

pub struct Dummy;

unsafe impl GlobalAlloc for Dummy {
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
null_mut()
}

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
panic!("dealloc is not supported")
}
}

#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();

pub fn init_heap(mapper: &mut impl Mapper<Size4KiB>, frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<(), MapToError<Size4KiB>> {

let page_range = {
let heap_start = VirtAddr::new(HEAP_START as u64);
let heap_end = heap_start + HEAP_SIZE - 1u64;
let heap_start_page: Page<Size4KiB> = Page::containing_address(heap_start);
let heap_end_page: Page<Size4KiB> = Page::containing_address(heap_end);
Page::range_inclusive(heap_start_page, heap_end_page)
};
for page in page_range {
let frame = frame_allocator.allocate_frame().ok_or(MapToError::FrameAllocationFailed)?;
let flags = Flags::PRESENT | Flags::WRITABLE;
unsafe { mapper.map_to(page, frame, flags, frame_allocator)?.flush() };

}
unsafe {
ALLOCATOR.lock().init(HEAP_START as usize, HEAP_SIZE as usize);
}
Ok(())
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#![reexport_test_harness_main = "test_main"]
#![feature(abi_x86_interrupt)]
use core::panic::PanicInfo;
extern crate alloc;

pub mod gdt;
pub mod interrupts;
pub mod memory;
pub mod serial;
pub mod vga_buffer;
pub mod allocator;

#[cfg(test)]
use bootloader::entry_point;
Expand Down
47 changes: 25 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
#![feature(custom_test_frameworks)]
#![test_runner(candy::test_runner)]
#![reexport_test_harness_main = "test_main"]

extern crate alloc;
use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use alloc::rc::Rc;
use bootloader::{entry_point, BootInfo};
use candy::{
hlt_loop,
memory::{self, create_example_mapping},
memory,
println,
allocator
};
use core::panic::PanicInfo;
use x86_64::structures::paging::Translate;


entry_point!(kernel_main);

Expand All @@ -20,28 +25,26 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
candy::init();

use x86_64::VirtAddr;
use x86_64::structures::paging::{Page, PageTableFlags as Flags};
let physical_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
let mut page_table = unsafe { memory::init(physical_mem_offset) };
let mut mapper = unsafe { memory::init(physical_mem_offset) };
let mut frame_allocator = unsafe { memory::BootInfoFrameAllocator::init(&boot_info.memory_map) };
let page = Page::containing_address(VirtAddr::new(0));
// 为他找到一个虚拟地址 如果我们已经知道物理地址 我们使用地址转换 mapper 进行 物理地址到虚拟地址的转换 然后我们创建一个页表项
//let phys_frame = frame_allocator.allocate_frame().expect("no more frames");
let flags = Flags::PRESENT | Flags::WRITABLE;
create_example_mapping(page, flags, &mut page_table, &mut frame_allocator);
let addresses = [
0x0,
0xb8000,
0x201008,
0x0100_0020_1a10,
boot_info.physical_memory_offset,
];

for &address in &addresses {
let virt = VirtAddr::new(address);
let phys = page_table.translate_addr(virt);
println!("{:?} -> {:?}", virt, phys);
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");

let x = Box::new(41);
println!("heap_value at {:p}", x);

let mut vec = Vec::new();
for i in 0..500 {
vec.push(i);
}
println!("vec at {:p}", vec.as_slice());

let reference_count = Rc::new(vec![1, 2, 3]);
let cloned_reference = reference_count.clone();
println!("current reference count is {}", Rc::strong_count(&cloned_reference));
core::mem::drop(reference_count);
println!("reference count is {}", Rc::strong_count(&cloned_reference));


#[cfg(test)]
test_main();
Expand Down
8 changes: 8 additions & 0 deletions tests/basic_boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@

use candy::println;
use core::panic::PanicInfo;
use bootloader::{entry_point, BootInfo};
entry_point!(main);
fn main(boot_info: &'static BootInfo) -> ! {
candy::init();
test_main();
candy::hlt_loop();
}


#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
Expand Down
67 changes: 67 additions & 0 deletions tests/heap_allocation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#![no_std]
#![no_main]
#![feature(custom_test_frameworks)]
#![test_runner(candy::test_runner)]
#![reexport_test_harness_main = "test_main"]

extern crate alloc;

use bootloader::{entry_point, BootInfo};
use core::panic::PanicInfo;

entry_point!(main);

fn main(boot_info: &'static BootInfo) -> ! {
use candy::allocator;
use candy::memory::{self, BootInfoFrameAllocator};
use x86_64::VirtAddr;

candy::init();
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");

test_main();
loop {}
}

#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
candy::test_panic_handler(info)
}

use alloc::boxed::Box;

#[test_case]
fn simple_allocation() {
let heap_value_1 = Box::new(41);
let heap_value_2 = Box::new(13);
assert_eq!(*heap_value_1, 41);
assert_eq!(*heap_value_2, 13);
}

use alloc::vec::Vec;

#[test_case]
fn large_vec() {
let n = 1000;
let mut vec = Vec::new();
for i in 0..n {
vec.push(i);
}
assert_eq!(vec.iter().sum::<u64>(), (n - 1) * n / 2);
}

use candy::allocator::HEAP_SIZE;

#[test_case]
fn many_boxes() {
for i in 0..HEAP_SIZE {
let x = Box::new(i);
assert_eq!(*x, i);
}
}

0 comments on commit e0bf458

Please sign in to comment.