Skip to content

Commit

Permalink
get_memory_mapの実装
Browse files Browse the repository at this point in the history
  • Loading branch information
AtsukiTak committed Mar 31, 2022
1 parent ead6b9a commit 6e3bb3c
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 16 deletions.
25 changes: 11 additions & 14 deletions bootloader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@ extern "win64" fn efi_main(handle: Handle, table: SystemTable) -> usize {

println!("Hello World");

// write to file
let sfs = table.boot().locate_protocol::<SimpleFileSystemProtocol>();

if let Some(file) = sfs
.open_volume()
.open("test", 0x8000000000000000 | 0x01 | 0x02)
{
let status = file.write("hoge");
println!("result of file write : {}", status);
file.flush();
println!("Success");
} else {
println!("Failed");
}
let mut buf = [0u8; 8000];
match table.boot().get_memory_map(&mut buf) {
Ok((_key, mem_map_iter)) => {
for mem_desc in mem_map_iter {
println!("{:?}", mem_desc);
}
}
Err(size) => {
println!("required memory map size : {}", size);
}
};

loop {}
}
Expand Down
94 changes: 92 additions & 2 deletions bootloader/src/uefi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
pub mod proto;

use self::proto::{text::SimpleTextOutputProtocol, {Protocol, Guid}};
use self::proto::{
text::SimpleTextOutputProtocol,
{Guid, Protocol},
};
use core::{ffi::c_void, ptr::NonNull};

#[repr(transparent)]
Expand Down Expand Up @@ -52,7 +55,13 @@ pub struct BootServices {
// memory services
allocate_pages: usize,
free_pages: usize,
get_memory_map: usize,
get_memory_map: unsafe extern "win64" fn(
memory_map_size: &mut usize,
memory_map: *mut MemoryDescriptor,
map_key: &mut MapKey,
descriptor_size: &mut usize,
descriptor_version: &mut u32,
) -> usize,
allocate_pool: usize,
free_pool: usize,

Expand Down Expand Up @@ -117,6 +126,39 @@ pub struct BootServices {
}

impl BootServices {
pub fn get_memory_map<'buf>(
&self,
buf: &'buf mut [u8],
) -> Result<(MapKey, MemoryMapIter<'buf>), usize> {
let mut mem_map_size = buf.len();
let mem_map = buf.as_mut_ptr().cast();
let mut map_key = MapKey(0);
let mut desc_size = 0usize;
let mut desc_ver = 0u32;

let status = unsafe {
(self.get_memory_map)(
&mut mem_map_size,
mem_map,
&mut map_key,
&mut desc_size,
&mut desc_ver,
)
};

if status != 0 {
return Err(mem_map_size);
} else {
let mem_map_iter = MemoryMapIter {
buf,
desc_size,
index: 0,
len: mem_map_size / desc_size,
};
Ok((map_key, mem_map_iter))
}
}

pub fn locate_protocol<P: Protocol>(&self) -> &P {
let mut interface: *mut c_void = core::ptr::null_mut();
unsafe {
Expand All @@ -125,3 +167,51 @@ impl BootServices {
}
}
}

#[repr(transparent)]
pub struct MapKey(usize);

#[repr(C)]
#[derive(Debug)]
pub struct MemoryDescriptor {
typ: u32,
physical_start: PhysicalAddress,
virtual_start: VirtualAddress,
number_of_pages: u64,
attribute: u64,
}

#[repr(transparent)]
#[derive(Debug)]
pub struct PhysicalAddress(u64);

#[repr(transparent)]
#[derive(Debug)]
pub struct VirtualAddress(u64);

pub struct MemoryMapIter<'buf> {
buf: &'buf mut [u8],
// size of memory descriptor in bytes
desc_size: usize,
index: usize,
len: usize,
}

impl<'buf> Iterator for MemoryMapIter<'buf> {
type Item = &'buf MemoryDescriptor;

fn next(&mut self) -> Option<Self::Item> {
if self.index == self.len {
return None;
}

let desc = unsafe {
let ptr = self.buf.as_ptr() as usize + self.index * self.desc_size;
&*(ptr as *const MemoryDescriptor)
};

self.index += 1;

Some(desc)
}
}

0 comments on commit 6e3bb3c

Please sign in to comment.