@@ -90,27 +90,137 @@ pub trait BootConfigurator {
90
90
///
91
91
/// # Arguments
92
92
///
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.
101
96
/// * `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.
102
140
///
103
- /// [`boot_params `]: ../loader/bootparam/struct.boot_e820_entry .html
141
+ /// [`ByteValued `]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued .html
104
142
/// [`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 : & [ 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
+ ///
106
163
/// [`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 : & [ 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
+ }
116
226
}
0 commit comments