@@ -81,9 +81,29 @@ impl Display for Error {
81
81
}
82
82
}
83
83
84
- pub struct ElfLoader ;
84
+ /// * `kernel_load` - The actual `guest_mem` address where kernel image is loaded start.
85
+ /// * `kernel_end` - The offset of `guest_mem` where kernel image load is loaded finish, return
86
+ /// in case of loading initrd adjacent to kernel image.
87
+ #[ derive( Debug , Default , Copy , Clone , PartialEq ) ]
88
+ pub struct KernelLoaderResult {
89
+ pub kernel_load : GuestAddress ,
90
+ pub kernel_end : GuestUsize ,
91
+ }
92
+
93
+ pub trait KernelLoader {
94
+ fn load < F > (
95
+ guest_mem : & GuestMemoryMmap ,
96
+ kernel_start : Option < GuestAddress > ,
97
+ kernel_image : & mut F ,
98
+ lowest_kernel_start : Option < GuestAddress > ,
99
+ ) -> Result < ( KernelLoaderResult ) >
100
+ where
101
+ F : Read + Seek ;
102
+ }
103
+
104
+ pub struct Elf ;
85
105
86
- impl ElfLoader {
106
+ impl KernelLoader for Elf {
87
107
/// Loads a kernel from a vmlinux elf image to a slice
88
108
///
89
109
/// kernel is loaded into guest memory at offset phdr.p_paddr specified by elf image.
@@ -96,15 +116,13 @@ impl ElfLoader {
96
116
/// * `lowest_kernel_start` - This is the start of the high memory, kernel should above it.
97
117
///
98
118
/// # Returns
99
- /// * GuestAddress - GuestAddress where kernel is loaded.
100
- /// * usize - the length of kernel image. Return this in case of other part
101
- /// like initrd will be loaded adjacent to the kernel part.
102
- pub fn load_kernel < F > (
119
+ /// * KernelLoaderResult
120
+ fn load < F > (
103
121
guest_mem : & GuestMemoryMmap ,
104
122
kernel_start : Option < GuestAddress > ,
105
123
kernel_image : & mut F ,
106
124
lowest_kernel_start : Option < GuestAddress > ,
107
- ) -> Result < ( GuestAddress , GuestUsize ) >
125
+ ) -> Result < ( KernelLoaderResult ) >
108
126
where
109
127
F : Read + Seek ,
110
128
{
@@ -140,8 +158,10 @@ impl ElfLoader {
140
158
return Err ( Error :: InvalidEntryAddress ) ;
141
159
}
142
160
}
161
+
162
+ let mut loader_result: KernelLoaderResult = Default :: default ( ) ;
143
163
// where the kernel will be start loaded.
144
- let kernel_loaded_addr = match kernel_start {
164
+ loader_result . kernel_load = match kernel_start {
145
165
Some ( start) => GuestAddress ( start. raw_value ( ) + ( ehdr. e_entry as u64 ) ) ,
146
166
None => GuestAddress ( ehdr. e_entry as u64 ) ,
147
167
} ;
@@ -155,8 +175,6 @@ impl ElfLoader {
155
175
. map_err ( |_| Error :: ReadProgramHeader ) ?
156
176
} ;
157
177
158
- let mut kernel_end: GuestUsize = 0 ;
159
-
160
178
// Read in each section pointed to by the program headers.
161
179
for phdr in & phdrs {
162
180
if phdr. p_type != elf:: PT_LOAD || phdr. p_filesz == 0 {
@@ -180,10 +198,11 @@ impl ElfLoader {
180
198
. read_exact_from ( mem_offset, kernel_image, phdr. p_filesz as usize )
181
199
. map_err ( |_| Error :: ReadKernelImage ) ?;
182
200
183
- kernel_end = mem_offset. raw_value ( ) as GuestUsize + phdr. p_memsz as GuestUsize ;
201
+ loader_result. kernel_end =
202
+ mem_offset. raw_value ( ) as GuestUsize + phdr. p_memsz as GuestUsize ;
184
203
}
185
204
186
- Ok ( ( kernel_loaded_addr , kernel_end ) )
205
+ Ok ( loader_result )
187
206
}
188
207
}
189
208
@@ -221,8 +240,8 @@ pub fn load_cmdline(
221
240
#[ cfg( test) ]
222
241
mod test {
223
242
use super :: * ;
224
- use vm_memory:: { Address , GuestAddress , GuestMemoryMmap } ;
225
243
use std:: io:: Cursor ;
244
+ use vm_memory:: { Address , GuestAddress , GuestMemoryMmap } ;
226
245
227
246
const MEM_SIZE : u64 = 0x1000000 ;
228
247
@@ -243,36 +262,45 @@ mod test {
243
262
let image = make_elf_bin ( ) ;
244
263
let kernel_addr = GuestAddress ( 0x200000 ) ;
245
264
let mut lowest_kernel_start = GuestAddress ( 0x0 ) ;
246
-
247
- let mut x = ElfLoader :: load_kernel (
265
+ let mut loader_result = Elf :: load (
248
266
& gm,
249
267
Some ( kernel_addr) ,
250
268
& mut Cursor :: new ( & image) ,
251
269
Some ( lowest_kernel_start) ,
270
+ )
271
+ . unwrap ( ) ;
272
+ println ! (
273
+ "load elf at address {:8x} \n " ,
274
+ loader_result. kernel_load. raw_value( )
252
275
) ;
253
- assert_eq ! ( x. is_ok( ) , true ) ;
254
- let mut entry_addr = x. unwrap ( ) . 0 ;
255
- println ! ( "load elf at address {:8x} \n " , entry_addr. raw_value( ) ) ;
256
276
257
- x = ElfLoader :: load_kernel ( & gm, Some ( kernel_addr) , & mut Cursor :: new ( & image) , None ) ;
258
- assert_eq ! ( x. is_ok( ) , true ) ;
259
- entry_addr = x. unwrap ( ) . 0 ;
260
- println ! ( "load elf at address {:8x} \n " , entry_addr. raw_value( ) ) ;
277
+ loader_result = Elf :: load ( & gm, Some ( kernel_addr) , & mut Cursor :: new ( & image) , None ) . unwrap ( ) ;
278
+ println ! (
279
+ "load elf at address {:8x} \n " ,
280
+ loader_result. kernel_load. raw_value( )
281
+ ) ;
261
282
262
- x = ElfLoader :: load_kernel (
283
+ loader_result = Elf :: load (
263
284
& gm,
264
285
None ,
265
286
& mut Cursor :: new ( & image) ,
266
287
Some ( lowest_kernel_start) ,
288
+ )
289
+ . unwrap ( ) ;
290
+ println ! (
291
+ "load elf at address {:8x} \n " ,
292
+ loader_result. kernel_load. raw_value( )
267
293
) ;
268
- assert_eq ! ( x. is_ok( ) , true ) ;
269
- entry_addr = x. unwrap ( ) . 0 ;
270
- println ! ( "load elf at address {:8x} \n " , entry_addr. raw_value( ) ) ;
271
294
272
295
lowest_kernel_start = GuestAddress ( 0xa00000 ) ;
273
296
assert_eq ! (
274
297
Err ( Error :: InvalidEntryAddress ) ,
275
- ElfLoader :: load_kernel( & gm, None , & mut Cursor :: new( & image) , Some ( lowest_kernel_start) )
298
+ Elf :: load(
299
+ & gm,
300
+ None ,
301
+ & mut Cursor :: new( & image) ,
302
+ Some ( lowest_kernel_start)
303
+ )
276
304
) ;
277
305
}
278
306
@@ -326,7 +354,7 @@ mod test {
326
354
bad_image[ 0x1 ] = 0x33 ;
327
355
assert_eq ! (
328
356
Err ( Error :: InvalidElfMagicNumber ) ,
329
- ElfLoader :: load_kernel ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
357
+ Elf :: load ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
330
358
) ;
331
359
}
332
360
@@ -339,7 +367,7 @@ mod test {
339
367
bad_image[ 0x5 ] = 2 ;
340
368
assert_eq ! (
341
369
Err ( Error :: BigEndianElfOnLittle ) ,
342
- ElfLoader :: load_kernel ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
370
+ Elf :: load ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
343
371
) ;
344
372
}
345
373
@@ -352,7 +380,7 @@ mod test {
352
380
bad_image[ 0x20 ] = 0x10 ;
353
381
assert_eq ! (
354
382
Err ( Error :: InvalidProgramHeaderOffset ) ,
355
- ElfLoader :: load_kernel ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
383
+ Elf :: load ( & gm, Some ( kernel_addr) , & mut Cursor :: new( & bad_image) , None )
356
384
) ;
357
385
}
358
386
}
0 commit comments