summaryrefslogtreecommitdiffstats
path: root/docs/adr/0001-static-buffer-for-memory-map.md
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).