blob: 75a40592c7892d7d6700f3b8bfe1270a658810fb (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# ADR 0001 — Static .bss Buffer for UEFI Memory Map Capture
## Status
Accepted.
## Context
Before calling `ExitBootServices`, the kernel must obtain the UEFI memory map
to know which physical memory regions are available. The standard UEFI recipe
is:
1. Call `GetMemoryMap` with a null buffer to get the required buffer size.
2. Allocate a buffer (via `AllocatePool`).
3. Call `GetMemoryMap` again to fill the buffer, receiving a `MapKey`.
4. Call `ExitBootServices(image_handle, MapKey)`.
**Problem:** Steps 2 and 3 change the memory map themselves (the pool
allocation adds entries). After step 3 we have a valid `MapKey` for the
map *as it was during step 3*, but calling `FreePool` on the buffer
(before step 4) would change the map again and invalidate the key.
Not freeing the buffer leaks pool memory, but more importantly, the
default approach of `AllocatePool + GetMemoryMap + ExitBootServices`
between two `GetMemoryMap` calls makes the key fragile.
## Decision
Use a **pre-allocated static buffer in `.bss`** (64 KB) instead of
dynamically allocating a pool buffer. Because the buffer already exists,
no `AllocatePool`/`FreePool` calls happen between `GetMemoryMap` and
`ExitBootServices`.
The sequence becomes:
1. `GetMemoryMap(null)` → determine required size.
2. `GetMemoryMap(static_buf)` → fill the map, receive `MapKey`.
3. `ExitBootServices(image_handle, MapKey)` — no pool allocation
happened after step 2, so the key is guaranteed valid.
If the static buffer is too small (it shouldn't be — 64 KB holds ~1300
descriptors, real firmware typically uses ~50–150), the caller falls
back to a pool-allocated buffer.
## Consequences
- **Positive:** The `MapKey` is never invalidated between capture and
`ExitBootServices`. The boot sequence is simpler and more reliable.
- **Positive:** No pool memory leaks — the static buffer lives in `.bss`
and costs nothing to keep.
- **Negative:** 64 KB of `.bss` is permanently reserved (irrelevant on a
kernel that owns all memory).
- **Negative:** The buffer size is fixed at compile time; pathological
firmware with thousands of entries would require a fallback path
(implemented but never hit in practice).
|