1
- use core:: { ops, slice} ;
1
+ use core:: { ops, slice, str } ;
2
2
3
3
use crate :: config:: ApiVersion ;
4
4
@@ -22,6 +22,8 @@ use crate::config::ApiVersion;
22
22
pub struct BootInfo {
23
23
/// The version of the `bootloader_api` crate. Must match the `bootloader` version.
24
24
pub api_version : ApiVersion ,
25
+ /// The size of the boot info.
26
+ pub size : usize ,
25
27
/// A map of the physical memory regions of the underlying machine.
26
28
///
27
29
/// The bootloader queries this information from the BIOS/UEFI firmware and translates this
@@ -52,21 +54,28 @@ pub struct BootInfo {
52
54
pub rsdp_addr : Optional < u64 > ,
53
55
/// The thread local storage (TLS) template of the kernel executable, if present.
54
56
pub tls_template : Optional < TlsTemplate > ,
57
+ /// Files stored in the modules subdirectory of the kernel image.
58
+ pub modules : Modules ,
59
+ /// The ELF sections of the kernel executable.
60
+ pub elf_sections : ElfSections ,
55
61
}
56
62
57
63
impl BootInfo {
58
- /// Create a new boot info structure with the given memory map.
64
+ /// Create a new boot info structure with the given memory map, modules, and elf sections .
59
65
///
60
66
/// The other fields are initialized with default values.
61
- pub fn new ( memory_regions : MemoryRegions ) -> Self {
67
+ pub fn new ( memory_regions : MemoryRegions , modules : Modules , elf_sections : ElfSections ) -> Self {
62
68
Self {
63
69
api_version : ApiVersion :: new_default ( ) ,
70
+ size : 0 ,
64
71
memory_regions,
65
72
framebuffer : Optional :: None ,
66
73
physical_memory_offset : Optional :: None ,
67
74
recursive_index : Optional :: None ,
68
75
rsdp_addr : Optional :: None ,
69
76
tls_template : Optional :: None ,
77
+ modules,
78
+ elf_sections,
70
79
}
71
80
}
72
81
}
@@ -275,6 +284,134 @@ pub struct TlsTemplate {
275
284
pub mem_size : u64 ,
276
285
}
277
286
287
+ /// FFI-safe slice of [`Module`] structs, semantically equivalent to
288
+ /// `&'static mut [Module]`.
289
+ #[ derive( Debug ) ]
290
+ #[ repr( C ) ]
291
+ pub struct Modules {
292
+ pub ( crate ) ptr : * mut Module ,
293
+ pub ( crate ) len : usize ,
294
+ }
295
+
296
+ impl ops:: Deref for Modules {
297
+ type Target = [ Module ] ;
298
+
299
+ fn deref ( & self ) -> & Self :: Target {
300
+ unsafe { slice:: from_raw_parts ( self . ptr , self . len ) }
301
+ }
302
+ }
303
+
304
+ impl ops:: DerefMut for Modules {
305
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
306
+ unsafe { slice:: from_raw_parts_mut ( self . ptr , self . len ) }
307
+ }
308
+ }
309
+
310
+ impl From < & ' static mut [ Module ] > for Modules {
311
+ fn from ( modules : & ' static mut [ Module ] ) -> Self {
312
+ Self {
313
+ ptr : modules. as_mut_ptr ( ) ,
314
+ len : modules. len ( ) ,
315
+ }
316
+ }
317
+ }
318
+
319
+ impl From < Modules > for & ' static mut [ Module ] {
320
+ fn from ( modules : Modules ) -> Self {
321
+ unsafe { slice:: from_raw_parts_mut ( modules. ptr , modules. len ) }
322
+ }
323
+ }
324
+
325
+ /// A file.
326
+ #[ derive( Debug , Clone , Copy ) ]
327
+ #[ repr( C ) ]
328
+ pub struct Module {
329
+ /// The name of the module encoded as a null-terminated UTF-8 string.
330
+ pub name : [ u8 ; 64 ] ,
331
+ /// The offset in bytes from the start of the modules.
332
+ ///
333
+ /// The offset is guaranteed to be page aligned.
334
+ pub offset : usize ,
335
+ /// The length of the module in bytes.
336
+ pub len : usize ,
337
+ }
338
+
339
+ impl Module {
340
+ /// The name of the module.
341
+ pub fn name ( & self ) -> & str {
342
+ let end = self
343
+ . name
344
+ . iter ( )
345
+ . position ( |byte| * byte == 0 )
346
+ . unwrap_or_else ( || self . name . len ( ) ) ;
347
+ str:: from_utf8 ( & self . name [ ..end] ) . expect ( "invalid bytes in module name" )
348
+ }
349
+ }
350
+
351
+ /// FFI-safe slice of [`ElfSection`] structs, semantically equivalent to
352
+ /// `&'static mut [ElfSection]`.
353
+ #[ derive( Debug ) ]
354
+ #[ repr( C ) ]
355
+ pub struct ElfSections {
356
+ pub ( crate ) ptr : * mut ElfSection ,
357
+ pub ( crate ) len : usize ,
358
+ }
359
+
360
+ impl ops:: Deref for ElfSections {
361
+ type Target = [ ElfSection ] ;
362
+
363
+ fn deref ( & self ) -> & Self :: Target {
364
+ unsafe { slice:: from_raw_parts ( self . ptr , self . len ) }
365
+ }
366
+ }
367
+
368
+ impl ops:: DerefMut for ElfSections {
369
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
370
+ unsafe { slice:: from_raw_parts_mut ( self . ptr , self . len ) }
371
+ }
372
+ }
373
+
374
+ impl From < & ' static mut [ ElfSection ] > for ElfSections {
375
+ fn from ( elf_sections : & ' static mut [ ElfSection ] ) -> Self {
376
+ Self {
377
+ ptr : elf_sections. as_mut_ptr ( ) ,
378
+ len : elf_sections. len ( ) ,
379
+ }
380
+ }
381
+ }
382
+
383
+ impl From < ElfSections > for & ' static mut [ ElfSection ] {
384
+ fn from ( elf_sections : ElfSections ) -> Self {
385
+ unsafe { slice:: from_raw_parts_mut ( elf_sections. ptr , elf_sections. len ) }
386
+ }
387
+ }
388
+
389
+ /// An ELF section.
390
+ #[ derive( Debug , Clone , Copy ) ]
391
+ #[ repr( C ) ]
392
+ pub struct ElfSection {
393
+ /// The name of the section encoded as a null-terminated UTF-8 string.
394
+ pub name : [ u8 ; 64 ] ,
395
+ /// The starting virtual address of the section.
396
+ pub start : usize ,
397
+ /// The size of the section in bytes.
398
+ pub size : usize ,
399
+ /// The section flags.
400
+ pub flags : u64 ,
401
+ }
402
+
403
+ impl ElfSection {
404
+ /// The name of the section.
405
+ pub fn name ( & self ) -> & str {
406
+ let end = self
407
+ . name
408
+ . iter ( )
409
+ . position ( |byte| * byte == 0 )
410
+ . unwrap_or_else ( || self . name . len ( ) ) ;
411
+ str:: from_utf8 ( & self . name [ ..end] ) . expect ( "invalid bytes in section name" )
412
+ }
413
+ }
414
+
278
415
/// FFI-safe variant of [`Option`].
279
416
///
280
417
/// Implements the [`From`] and [`Into`] traits for easy conversion to and from [`Option`].
0 commit comments