Skip to content

Commit 78e4342

Browse files
Merge pull request #1665 from rust-osdev/uefi-alloc-doc
doc: improved documentation for boot allocation functions
2 parents 128696a + 58e7f4c commit 78e4342

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed

uefi/src/boot.rs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,28 +121,46 @@ pub unsafe fn raise_tpl(tpl: Tpl) -> TplGuard {
121121
}
122122
}
123123

124-
/// Allocates memory pages from the system.
124+
/// Allocates a consecutive set of memory pages using the UEFI allocator.
125125
///
126-
/// UEFI OS loaders should allocate memory of the type `LoaderData`.
126+
/// The buffer will be [`PAGE_SIZE`] aligned. Callers are responsible for
127+
/// freeing the memory using [`free_pages`].
128+
///
129+
/// # Arguments
130+
/// - `allocation_type`: The [`AllocateType`] to choose the allocation strategy.
131+
/// - `memory_type`: The [`MemoryType`] used to persist the allocation in the
132+
/// UEFI memory map. Typically, UEFI OS loaders should allocate memory of
133+
/// type [`MemoryType::LOADER_DATA`].
134+
///- `count`: Number of bytes to allocate.
135+
///
136+
/// # Safety
137+
///
138+
/// Using this function is safe, but it returns a raw pointer to uninitialized
139+
/// memory. The memory must be initialized before creating a reference to it
140+
/// or reading from it eventually.
127141
///
128142
/// # Errors
129143
///
130144
/// * [`Status::OUT_OF_RESOURCES`]: allocation failed.
131145
/// * [`Status::INVALID_PARAMETER`]: `mem_ty` is [`MemoryType::PERSISTENT_MEMORY`],
132146
/// [`MemoryType::UNACCEPTED`], or in the range [`MemoryType::MAX`]`..=0x6fff_ffff`.
133147
/// * [`Status::NOT_FOUND`]: the requested pages could not be found.
134-
pub fn allocate_pages(ty: AllocateType, mem_ty: MemoryType, count: usize) -> Result<NonNull<u8>> {
148+
pub fn allocate_pages(
149+
allocation_type: AllocateType,
150+
memory_type: MemoryType,
151+
count: usize,
152+
) -> Result<NonNull<u8>> {
135153
let bt = boot_services_raw_panicking();
136154
let bt = unsafe { bt.as_ref() };
137155

138-
let (ty, initial_addr) = match ty {
156+
let (ty, initial_addr) = match allocation_type {
139157
AllocateType::AnyPages => (0, 0),
140158
AllocateType::MaxAddress(addr) => (1, addr),
141159
AllocateType::Address(addr) => (2, addr),
142160
};
143161

144162
let mut addr1 = initial_addr;
145-
unsafe { (bt.allocate_pages)(ty, mem_ty, count, &mut addr1) }.to_result()?;
163+
unsafe { (bt.allocate_pages)(ty, memory_type, count, &mut addr1) }.to_result()?;
146164

147165
// The UEFI spec allows `allocate_pages` to return a valid allocation at
148166
// address zero. Rust does not allow writes through a null pointer (which
@@ -156,7 +174,7 @@ pub fn allocate_pages(ty: AllocateType, mem_ty: MemoryType, count: usize) -> Res
156174
// not yet been freed, so if this allocation succeeds it should be at a
157175
// non-zero address.
158176
let mut addr2 = initial_addr;
159-
let r = unsafe { (bt.allocate_pages)(ty, mem_ty, count, &mut addr2) }.to_result();
177+
let r = unsafe { (bt.allocate_pages)(ty, memory_type, count, &mut addr2) }.to_result();
160178

161179
// Free the original allocation (ignoring errors).
162180
let _unused = unsafe { (bt.free_pages)(addr1, count) };
@@ -190,22 +208,37 @@ pub unsafe fn free_pages(ptr: NonNull<u8>, count: usize) -> Result {
190208
unsafe { (bt.free_pages)(addr, count) }.to_result()
191209
}
192210

193-
/// Allocates from a memory pool. The pointer will be 8-byte aligned.
211+
/// Allocates a consecutive region of bytes using the UEFI allocator.
212+
///
213+
/// The buffer will be 8-byte aligned. Callers are responsible for freeing the
214+
/// memory using [`free_pool`].
215+
///
216+
/// # Arguments
217+
/// - `memory_type`: The [`MemoryType`] used to persist the allocation in the
218+
/// UEFI memory map. Typically, UEFI OS loaders should allocate memory of
219+
/// type [`MemoryType::LOADER_DATA`].
220+
///- `size`: Number of bytes to allocate.
221+
///
222+
/// # Safety
223+
///
224+
/// Using this function is safe, but it returns a raw pointer to uninitialized
225+
/// memory. The memory must be initialized before creating a reference to it
226+
/// or reading from it eventually.
194227
///
195228
/// # Errors
196229
///
197230
/// * [`Status::OUT_OF_RESOURCES`]: allocation failed.
198231
/// * [`Status::INVALID_PARAMETER`]: `mem_ty` is [`MemoryType::PERSISTENT_MEMORY`],
199232
/// [`MemoryType::UNACCEPTED`], or in the range [`MemoryType::MAX`]`..=0x6fff_ffff`.
200-
pub fn allocate_pool(mem_ty: MemoryType, size: usize) -> Result<NonNull<u8>> {
233+
pub fn allocate_pool(memory_type: MemoryType, size: usize) -> Result<NonNull<u8>> {
201234
let bt = boot_services_raw_panicking();
202235
let bt = unsafe { bt.as_ref() };
203236

204237
let mut buffer = ptr::null_mut();
205-
let ptr =
206-
unsafe { (bt.allocate_pool)(mem_ty, size, &mut buffer) }.to_result_with_val(|| buffer)?;
238+
let ptr = unsafe { (bt.allocate_pool)(memory_type, size, &mut buffer) }
239+
.to_result_with_val(|| buffer)?;
207240

208-
Ok(NonNull::new(ptr).expect("allocate_pool must not return a null pointer if successful"))
241+
NonNull::new(ptr).ok_or(Status::OUT_OF_RESOURCES.into())
209242
}
210243

211244
/// Frees memory allocated by [`allocate_pool`].

0 commit comments

Comments
 (0)