1
1
use crate :: memory_region:: MemoryRegion ;
2
- use core:: slice;
2
+ use core:: { ops , slice} ;
3
3
4
4
/// This structure represents the information that the bootloader passes to the kernel.
5
5
///
@@ -14,6 +14,8 @@ use core::slice;
14
14
/// use the correct argument types. To ensure that the entry point function has the correct
15
15
/// signature, use the [`entry_point`] macro.
16
16
#[ derive( Debug ) ]
17
+ #[ repr( C ) ]
18
+ #[ non_exhaustive]
17
19
pub struct BootInfo {
18
20
/// Bootloader version (major).
19
21
pub version_major : u16 ,
@@ -32,9 +34,9 @@ pub struct BootInfo {
32
34
/// information to Rust types. It also marks any memory regions that the bootloader uses in
33
35
/// the memory map before passing it to the kernel. Regions marked as usable can be freely
34
36
/// used by the kernel.
35
- pub memory_regions : & ' static mut [ MemoryRegion ] ,
37
+ pub memory_regions : MemoryRegions ,
36
38
/// Information about the framebuffer for screen output if available.
37
- pub framebuffer : Option < FrameBuffer > ,
39
+ pub framebuffer : Optional < FrameBuffer > ,
38
40
/// The virtual address at which the mapping of the physical memory starts.
39
41
///
40
42
/// Physical addresses can be converted to virtual addresses by adding this offset to them.
@@ -45,21 +47,63 @@ pub struct BootInfo {
45
47
/// can be safely accessed.
46
48
///
47
49
/// Only available if the `map-physical-memory` config option is enabled.
48
- pub physical_memory_offset : Option < u64 > ,
50
+ pub physical_memory_offset : Optional < u64 > ,
49
51
/// The virtual address of the recursively mapped level 4 page table.
50
52
///
51
53
/// Only available if the `map-page-table-recursively` config option is enabled.
52
- pub recursive_index : Option < u16 > ,
54
+ pub recursive_index : Optional < u16 > ,
53
55
/// The address of the `RSDP` data structure, which can be use to find the ACPI tables.
54
56
///
55
57
/// This field is `None` if no `RSDP` was found (for BIOS) or reported (for UEFI).
56
- pub rsdp_addr : Option < u64 > ,
58
+ pub rsdp_addr : Optional < u64 > ,
57
59
/// The thread local storage (TLS) template of the kernel executable, if present.
58
- pub tls_template : Option < TlsTemplate > ,
59
- pub ( crate ) _non_exhaustive : ( ) ,
60
+ pub tls_template : Optional < TlsTemplate > ,
61
+ }
62
+
63
+ /// FFI-safe slice of [`MemoryRegion`] structs, semantically equivalent to
64
+ /// `&'static mut [MemoryRegion]`.
65
+ ///
66
+ /// This type implements the [`Deref`][core::ops::Deref] and [`DerefMut`][core::ops::DerefMut]
67
+ /// traits, so it can be used like a `&mut [MemoryRegion]` slice. It also implements [`From`]
68
+ /// and [`Into`] for easy conversions from and to `&'static mut [MemoryRegion]`.
69
+ #[ derive( Debug ) ]
70
+ #[ repr( C ) ]
71
+ pub struct MemoryRegions {
72
+ pub ( crate ) ptr : * mut MemoryRegion ,
73
+ pub ( crate ) len : usize ,
74
+ }
75
+
76
+ impl ops:: Deref for MemoryRegions {
77
+ type Target = [ MemoryRegion ] ;
78
+
79
+ fn deref ( & self ) -> & Self :: Target {
80
+ unsafe { slice:: from_raw_parts ( self . ptr , self . len ) }
81
+ }
82
+ }
83
+
84
+ impl ops:: DerefMut for MemoryRegions {
85
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
86
+ unsafe { slice:: from_raw_parts_mut ( self . ptr , self . len ) }
87
+ }
88
+ }
89
+
90
+ impl From < & ' static mut [ MemoryRegion ] > for MemoryRegions {
91
+ fn from ( regions : & ' static mut [ MemoryRegion ] ) -> Self {
92
+ MemoryRegions {
93
+ ptr : regions. as_mut_ptr ( ) ,
94
+ len : regions. len ( ) ,
95
+ }
96
+ }
97
+ }
98
+
99
+ impl Into < & ' static mut [ MemoryRegion ] > for MemoryRegions {
100
+ fn into ( self ) -> & ' static mut [ MemoryRegion ] {
101
+ unsafe { slice:: from_raw_parts_mut ( self . ptr , self . len ) }
102
+ }
60
103
}
61
104
62
105
#[ derive( Debug ) ]
106
+ #[ repr( C ) ]
63
107
pub struct FrameBuffer {
64
108
pub ( crate ) buffer_start : u64 ,
65
109
pub ( crate ) buffer_byte_len : usize ,
@@ -81,6 +125,7 @@ impl FrameBuffer {
81
125
}
82
126
83
127
#[ derive( Debug , Clone , Copy ) ]
128
+ #[ repr( C ) ]
84
129
pub struct FrameBufferInfo {
85
130
pub byte_len : usize ,
86
131
pub horizontal_resolution : usize ,
@@ -92,6 +137,7 @@ pub struct FrameBufferInfo {
92
137
93
138
#[ derive( Debug , Clone , Copy ) ]
94
139
#[ non_exhaustive]
140
+ #[ repr( C ) ]
95
141
pub enum PixelFormat {
96
142
RGB ,
97
143
BGR ,
@@ -106,6 +152,7 @@ pub enum PixelFormat {
106
152
/// ___location. The additional `mem_size - file_size` bytes must be initialized with
107
153
/// zero.
108
154
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
155
+ #[ repr( C ) ]
109
156
pub struct TlsTemplate {
110
157
/// The virtual start address of the thread local storage template.
111
158
pub start_addr : u64 ,
@@ -119,8 +166,33 @@ pub struct TlsTemplate {
119
166
pub mem_size : u64 ,
120
167
}
121
168
122
- /// Check that the _pointer_ is FFI-safe.
169
+ /// FFI-safe variant of [`Option`] .
123
170
///
124
- /// Note that the `BootInfo` struct is not FFI-safe, so it needs to be compiled by the same Rust
125
- /// compiler as the kernel in order to be safely accessed.
126
- extern "C" fn _assert_ffi ( _boot_info : & ' static mut BootInfo ) { }
171
+ /// Implements the [`From`] and [`Into`] traits for easy conversion to and from [`Option`].
172
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
173
+ #[ repr( C ) ]
174
+ pub enum Optional < T > {
175
+ Some ( T ) ,
176
+ None ,
177
+ }
178
+
179
+ impl < T > From < Option < T > > for Optional < T > {
180
+ fn from ( v : Option < T > ) -> Self {
181
+ match v {
182
+ Some ( v) => Optional :: Some ( v) ,
183
+ None => Optional :: None ,
184
+ }
185
+ }
186
+ }
187
+
188
+ impl < T > Into < Option < T > > for Optional < T > {
189
+ fn into ( self ) -> Option < T > {
190
+ match self {
191
+ Optional :: Some ( v) => Some ( v) ,
192
+ Optional :: None => None ,
193
+ }
194
+ }
195
+ }
196
+
197
+ /// Check that bootinfo is FFI-safe
198
+ extern "C" fn _assert_ffi ( _boot_info : BootInfo ) { }
0 commit comments