@@ -63,8 +63,8 @@ pub use memory_map::{
6363pub use module:: { ModuleIter , ModuleTag } ;
6464pub use rsdp:: { RsdpV1Tag , RsdpV2Tag } ;
6565pub use smbios:: SmbiosTag ;
66- use tag_type:: TagIter ;
6766pub use tag_type:: { EndTag , Tag , TagType , TagTypeId } ;
67+ use tag_type:: { TagIter , TagIterMut } ;
6868pub use vbe_info:: {
6969 VBECapabilities , VBEControlInfo , VBEDirectColorAttributes , VBEField , VBEInfoTag ,
7070 VBEMemoryModel , VBEModeAttributes , VBEModeInfo , VBEWindowAttributes ,
@@ -276,6 +276,11 @@ impl BootInformation {
276276 self . get_tag :: < MemoryMapTag , _ > ( TagType :: Mmap )
277277 }
278278
279+ /// Search for the Memory map tag, return a mutable reference.
280+ pub fn memory_map_tag_mut ( & mut self ) -> Option < & mut MemoryMapTag > {
281+ self . get_tag_mut :: < MemoryMapTag , _ > ( TagType :: Mmap )
282+ }
283+
279284 /// Get an iterator of all module tags.
280285 pub fn module_tags ( & self ) -> ModuleIter {
281286 module:: module_iter ( self . tags ( ) )
@@ -427,9 +432,23 @@ impl BootInformation {
427432 . map ( |tag| tag. cast_tag :: < TagT > ( ) )
428433 }
429434
435+ fn get_tag_mut < TagT : TagTrait + ?Sized , TagType : Into < TagTypeId > > (
436+ & mut self ,
437+ typ : TagType ,
438+ ) -> Option < & mut TagT > {
439+ let typ = typ. into ( ) ;
440+ self . tags_mut ( )
441+ . find ( |tag| tag. typ == typ)
442+ . map ( |tag| tag. cast_tag_mut :: < TagT > ( ) )
443+ }
444+
430445 fn tags ( & self ) -> TagIter {
431446 TagIter :: new ( unsafe { self . inner . offset ( 1 ) } as * const _ )
432447 }
448+
449+ fn tags_mut ( & mut self ) -> TagIterMut {
450+ TagIterMut :: new ( unsafe { self . inner . offset ( 1 ) } as * mut _ )
451+ }
433452}
434453
435454impl BootInformationInner {
@@ -567,6 +586,19 @@ pub trait TagTrait: Pointee {
567586 let ptr = ptr_meta:: from_raw_parts ( ptr, Self :: dst_size ( tag) ) ;
568587 & * ptr
569588 }
589+
590+ /// Creates a mutable reference to a (dynamically sized) tag type in a safe way.
591+ /// DST tags need to implement a proper [`Self::dst_size`] implementation.
592+ ///
593+ /// # Safety
594+ /// Callers must be sure that the "size" field of the provided [`Tag`] is
595+ /// sane and the underlying memory valid. The implementation of this trait
596+ /// **must have** a correct [`Self::dst_size`] implementation.
597+ unsafe fn from_base_tag_mut < ' a > ( tag : & mut Tag ) -> & ' a mut Self {
598+ let ptr = tag as * mut _ as * mut ( ) ;
599+ let ptr = ptr_meta:: from_raw_parts_mut ( ptr, Self :: dst_size ( tag) ) ;
600+ & mut * ptr
601+ }
570602}
571603
572604// All sized tags automatically have a Pointee implementation where
0 commit comments