@@ -90,27 +90,137 @@ pub trait BootConfigurator {
9090 ///
9191 /// # Arguments
9292 ///
93- /// * `header` - header section of the boot parameters and address where to write it in guest
94- /// memory. The first element must be a POD struct that implements [`ByteValued`].
95- /// For the Linux protocol it's the [`boot_params`] struct, and for PVH the
96- /// [`hvm_start_info`] struct.
97- /// * `sections` - vector of sections that compose the boot parameters and address where to
98- /// write them in guest memory. Unused for the Linux protocol. For PVH, it's the
99- /// memory map table represented as a vector of [`hvm_memmap_table_entry`]. Must
100- /// be a `Vec` of POD data structs that implement [`ByteValued`].
93+ /// * `params` - struct containing the header section of the boot parameters, additional
94+ /// sections and modules, and their associated addresses in guest memory. These
95+ /// vary with the boot protocol used.
10196 /// * `guest_memory` - guest's physical memory.
97+ fn write_bootparams < M > ( params : BootParams , guest_memory : & M ) -> Result < ( ) >
98+ where
99+ M : GuestMemory ;
100+ }
101+
102+ /// Boot parameters to be written in guest memory.
103+ #[ derive( Clone ) ]
104+ pub struct BootParams {
105+ /// "Header section", always written in guest memory irrespective of boot protocol.
106+ pub header : ( Vec < u8 > , GuestAddress ) ,
107+ /// Optional sections containing boot configurations (e.g. E820 map).
108+ pub sections : Option < ( Vec < u8 > , GuestAddress ) > ,
109+ /// Optional modules specified at boot configuration time.
110+ pub modules : Option < ( Vec < u8 > , GuestAddress ) > ,
111+ }
112+
113+ impl BootParams {
114+ /// Creates a new [`BootParams`](struct.BootParams.html) struct with the specified header.
115+ ///
116+ /// # Arguments
117+ ///
118+ /// * `header` - [`ByteValued`] representation of mandatory boot parameters.
119+ /// * `header_addr` - address in guest memory where `header` will be written.
120+ ///
121+ /// [`ByteValued`]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued.html
122+ pub fn new < T : ByteValued > ( header : & T , header_addr : GuestAddress ) -> Self {
123+ BootParams {
124+ header : ( header. as_slice ( ) . to_vec ( ) , header_addr) ,
125+ sections : None ,
126+ modules : None ,
127+ }
128+ }
129+
130+ /// Adds or overwrites the boot sections and associated memory address.
131+ ///
132+ /// Unused on `aarch64` and for the Linux boot protocol.
133+ /// For the PVH boot protocol, the sections specify the memory map table in
134+ /// [`hvm_memmap_table_entry`] structs.
135+ ///
136+ /// # Arguments
137+ ///
138+ /// * `sections` - vector of [`ByteValued`] boot configurations.
139+ /// * `sections_addr` - address where the sections will be written in guest memory.
102140 ///
103- /// [`boot_params `]: ../loader/bootparam/struct.boot_e820_entry .html
141+ /// [`ByteValued `]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued .html
104142 /// [`hvm_memmap_table_entry`]: ../loader/elf/start_info/struct.hvm_memmap_table_entry.html
105- /// [`hvm_start_info`]: ../loader/elf/start_info/struct.hvm_start_info.html
143+ pub fn add_sections < T : ByteValued > ( & mut self , sections : & Vec < T > , sections_addr : GuestAddress ) {
144+ self . sections = Some ( (
145+ sections
146+ . iter ( )
147+ . flat_map ( |section| section. as_slice ( ) . to_vec ( ) )
148+ . collect ( ) ,
149+ sections_addr,
150+ ) ) ;
151+ }
152+
153+ /// Adds or overwrites the boot modules and associated memory address.
154+ ///
155+ /// Unused on `aarch64` and for the Linux boot protocol.
156+ /// For the PVH boot protocol, the modules are specified in [`hvm_modlist_entry`] structs.
157+ ///
158+ /// # Arguments
159+ ///
160+ /// * `modules` - vector of [`ByteValued`] boot configurations.
161+ /// * `modules_addr` - address where the modules will be written in guest memory.
162+ ///
106163 /// [`ByteValued`]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued.html
107- fn write_bootparams < T , S , M > (
108- header : ( T , GuestAddress ) ,
109- sections : Option < ( Vec < S > , GuestAddress ) > ,
110- guest_memory : & M ,
111- ) -> Result < ( ) >
112- where
113- T : ByteValued ,
114- S : ByteValued ,
115- M : GuestMemory ;
164+ /// [`hvm_modlist_entry`]: ../loader/elf/start_info/struct.hvm_modlist_entry.html
165+ pub fn add_modules < T : ByteValued > ( & mut self , modules : & Vec < T > , modules_addr : GuestAddress ) {
166+ self . modules = Some ( (
167+ modules
168+ . iter ( )
169+ . flat_map ( |module| module. as_slice ( ) . to_vec ( ) )
170+ . collect ( ) ,
171+ modules_addr,
172+ ) ) ;
173+ }
174+ }
175+
176+ #[ cfg( test) ]
177+ mod tests {
178+ use super :: * ;
179+
180+ #[ test]
181+ fn test_error_messages ( ) {
182+ #[ cfg( target_arch = "x86_64" ) ]
183+ {
184+ // Linux
185+ assert_eq ! (
186+ format!( "{}" , Error :: Linux ( linux:: Error :: ZeroPagePastRamEnd ) ) ,
187+ "Boot Configurator Error: The zero page extends past the end of guest memory."
188+ ) ;
189+ assert_eq ! (
190+ format!( "{}" , Error :: Linux ( linux:: Error :: ZeroPageSetup ) ) ,
191+ "Boot Configurator Error: Error writing to the zero page of guest memory."
192+ ) ;
193+
194+ // PVH
195+ assert_eq ! (
196+ format!( "{}" , Error :: Pvh ( pvh:: Error :: MemmapTableMissing ) ) ,
197+ "Boot Configurator Error: No memory map was passed to the boot configurator."
198+ ) ;
199+ assert_eq ! (
200+ format!( "{}" , Error :: Pvh ( pvh:: Error :: MemmapTablePastRamEnd ) ) ,
201+ "Boot Configurator Error: \
202+ The memory map table extends past the end of guest memory."
203+ ) ;
204+ assert_eq ! (
205+ format!( "{}" , Error :: Pvh ( pvh:: Error :: MemmapTableSetup ) ) ,
206+ "Boot Configurator Error: Error writing memory map table to guest memory."
207+ ) ;
208+ assert_eq ! (
209+ format!( "{}" , Error :: Pvh ( pvh:: Error :: StartInfoPastRamEnd ) ) ,
210+ "Boot Configurator Error: \
211+ The hvm_start_info structure extends past the end of guest memory."
212+ ) ;
213+ assert_eq ! (
214+ format!( "{}" , Error :: Pvh ( pvh:: Error :: StartInfoSetup ) ) ,
215+ "Boot Configurator Error: Error writing hvm_start_info to guest memory."
216+ ) ;
217+ }
218+
219+ #[ cfg( target_arch = "aarch64" ) ]
220+ // FDT
221+ assert_eq ! (
222+ format!( "{}" , Error :: Fdt ( fdt:: Error :: WriteFDTToMemory ) ) ,
223+ "Boot Configurator Error: Error writing FDT in guest memory."
224+ ) ;
225+ }
116226}
0 commit comments