15
15
#include "system/reset.h"
16
16
#include "system/qtest.h"
17
17
18
+ /*
19
+ * Linux Image Format
20
+ * https://docs.kernel.org/arch/loongarch/booting.html
21
+ */
22
+ #define LINUX_PE_MAGIC 0x818223cd
23
+ #define MZ_MAGIC 0x5a4d /* "MZ" */
24
+
25
+ struct loongarch_linux_hdr {
26
+ uint32_t mz_magic ;
27
+ uint32_t res0 ;
28
+ uint64_t kernel_entry ;
29
+ uint64_t kernel_size ;
30
+ uint64_t load_offset ;
31
+ uint64_t res1 ;
32
+ uint64_t res2 ;
33
+ uint64_t res3 ;
34
+ uint32_t linux_pe_magic ;
35
+ uint32_t pe_header_offset ;
36
+ } QEMU_PACKED ;
37
+
18
38
struct memmap_entry * memmap_table ;
19
39
unsigned memmap_entries ;
20
40
@@ -171,6 +191,50 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
171
191
return addr & MAKE_64BIT_MASK (0 , TARGET_PHYS_ADDR_SPACE_BITS );
172
192
}
173
193
194
+ static int64_t load_loongarch_linux_image (const char * filename ,
195
+ uint64_t * kernel_entry ,
196
+ uint64_t * kernel_low ,
197
+ uint64_t * kernel_high )
198
+ {
199
+ gsize len ;
200
+ ssize_t size ;
201
+ uint8_t * buffer ;
202
+ struct loongarch_linux_hdr * hdr ;
203
+
204
+ /* Load as raw file otherwise */
205
+ if (!g_file_get_contents (filename , (char * * )& buffer , & len , NULL )) {
206
+ return -1 ;
207
+ }
208
+ size = len ;
209
+
210
+ /* Unpack the image if it is a EFI zboot image */
211
+ if (unpack_efi_zboot_image (& buffer , & size ) < 0 ) {
212
+ g_free (buffer );
213
+ return -1 ;
214
+ }
215
+
216
+ hdr = (struct loongarch_linux_hdr * )buffer ;
217
+
218
+ if (extract32 (le32_to_cpu (hdr -> mz_magic ), 0 , 16 ) != MZ_MAGIC ||
219
+ le32_to_cpu (hdr -> linux_pe_magic ) != LINUX_PE_MAGIC ) {
220
+ g_free (buffer );
221
+ return -1 ;
222
+ }
223
+
224
+ /* Early kernel versions may have those fields in virtual address */
225
+ * kernel_entry = extract64 (le64_to_cpu (hdr -> kernel_entry ),
226
+ 0 , TARGET_PHYS_ADDR_SPACE_BITS );
227
+ * kernel_low = extract64 (le64_to_cpu (hdr -> load_offset ),
228
+ 0 , TARGET_PHYS_ADDR_SPACE_BITS );
229
+ * kernel_high = * kernel_low + size ;
230
+
231
+ rom_add_blob_fixed (filename , buffer , size , * kernel_low );
232
+
233
+ g_free (buffer );
234
+
235
+ return size ;
236
+ }
237
+
174
238
static int64_t load_kernel_info (struct loongarch_boot_info * info )
175
239
{
176
240
uint64_t kernel_entry , kernel_low , kernel_high ;
@@ -181,6 +245,11 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
181
245
& kernel_entry , & kernel_low ,
182
246
& kernel_high , NULL , 0 ,
183
247
EM_LOONGARCH , 1 , 0 );
248
+ if (kernel_size < 0 ) {
249
+ kernel_size = load_loongarch_linux_image (info -> kernel_filename ,
250
+ & kernel_entry , & kernel_low ,
251
+ & kernel_high );
252
+ }
184
253
185
254
if (kernel_size < 0 ) {
186
255
error_report ("could not load kernel '%s': %s" ,
0 commit comments