Skip to content

Commit 35b2e0b

Browse files
Add doc on freestanding function migration
This is in its own file so that we can conveniently link to it in [deprecation] diagnostics. [deprecation]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute
1 parent 86727ee commit 35b2e0b

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

docs/funcs_migration.md

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# API migration: Deprecating SystemTable/BootServices/RuntimeServices
2+
3+
Starting in uefi-0.31.0, a significant API change has been introduced. We are
4+
transitioning away from modeling UEFI tables with structs, and instead providing
5+
an API based on freestanding functions. These functions make use of a global
6+
system table pointer that is set automatically by the `entry` macro.
7+
8+
A short example:
9+
10+
```rust
11+
// Old API:
12+
use uefi::table::boot::{BootServices, HandleBuffer};
13+
fn find_loaded_image_handles(bt: &BootServices) -> Result<HandleBuffer> {
14+
bt.locate_handle_buffer(SearchType::from_proto::<LoadedImage>())
15+
}
16+
17+
// New API:
18+
use uefi::boot::{self, HandleBuffer};
19+
fn find_loaded_image_handles() -> Result<HandleBuffer> {
20+
boot::locate_handle_buffer(SearchType::from_proto::<LoadedImage>())
21+
}
22+
```
23+
24+
The new functions generally have almost the same signature as the methods they
25+
are replacing, so in most cases migration should be as simple as updating
26+
imports and calling the freestanding function instead of a method on
27+
`SystemTable`, `BootServices`, or `RuntimeServices`.
28+
29+
In uefi-0.31.0, the old API has been deprecated, but can still be used. It will
30+
be fully removed in a later release.
31+
32+
If you run into any issues with this migration, please feel free to chat with us
33+
on [Zulip] or file an [issue].
34+
35+
## Reason for the change
36+
37+
See [issue #893][RFC] for the discussion that lead to this change.
38+
39+
### Safety of `exit_boot_services`
40+
41+
One of the main motivations for the old API was to make transitioning from boot
42+
services to runtime services a safe operation. Calling `exit_boot_services`
43+
would consume `SystemTable<Boot>` and return a `SystemTable<Runtime>`, ensuring
44+
that it was no longer possible to call boot services methods.
45+
46+
That was the theory, but in practice it didn't always work. Many real-world
47+
programs had to call `SystemTable::unsafe_clone` in order to get another handle
48+
to the system table, and that immediately reintroduced the possibility of
49+
unintentionally access boot services after calling `exit_boot_services`.
50+
51+
In addition, there are a great many kinds of resources that should not be
52+
accessed after calling `exit_boot_services`, so even if the `SystemTable<Boot>`
53+
was gone, it's very hard to _statically_ ensure that all references to
54+
boot-services resources are dropped.
55+
56+
Realistically the `exit_boot_services` operation is just too complex to model as
57+
part of Rust's safety guarantees. So in the end, we decided it is better to make
58+
`exit_boot_services` an `unsafe` operation. We do make use of runtime checks
59+
when possible to help catch mistakes (for example, calling a `boot` function
60+
after exiting boot services will panic).
61+
62+
### API complexity
63+
64+
Some parts of the API need to free a pool allocation on drop. For example,
65+
[`DevicePathToText`]. That means the user has to pass in a reference to
66+
`BootServices`, and it means the object containing the allocation needs to hang
67+
on to that reference, so it needs a lifetime parameter. That may require adding
68+
references and lifetimes to calling functions and to types containing the
69+
returned value. By using a global table pointer instead, this complexity is
70+
hidden and the API becomes simpler.
71+
72+
[`DevicePathToText`]: https://docs.rs/uefi/latest/uefi/proto/device_path/text/struct.DevicePathToText.html
73+
[RFC]: https://github.com/rust-osdev/uefi-rs/issues/893
74+
[Zulip]: https://rust-osdev.zulipchat.com/#narrow/stream/426438-uefi-rs
75+
[issue]: https://github.com/rust-osdev/uefi-rs/issues/new

uefi/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# uefi - [Unreleased]
22

3+
See [Deprecating SystemTable/BootServices/RuntimeServices][funcmigrate] for
4+
details of a significant change to the API in this release.
5+
36
## Added
47
- `uefi::system` is a new module that provides freestanding functions for
58
accessing fields of the global system table.
@@ -39,6 +42,7 @@
3942
> use uefi::table::boot::BootServices;
4043
```
4144

45+
[funcmigrate]: ../docs/funcs_migration.md
4246

4347
# uefi - 0.30.0 (2024-08-02)
4448

0 commit comments

Comments
 (0)