181
182
#define FOUR_MB (4 * 1024 * 1024)
184
/* Context for alloc_phys. */
185
struct alloc_phys_ctx
191
/* Helper for alloc_phys. */
193
alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
194
grub_memory_type_t type, void *data)
196
struct alloc_phys_ctx *ctx = data;
197
grub_addr_t end = addr + len;
202
addr = ALIGN_UP (addr, FOUR_MB);
203
if (addr + ctx->size >= end)
206
if (addr >= grub_phys_start && addr < grub_phys_end)
208
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
209
if (addr + ctx->size >= end)
212
if ((addr + ctx->size) >= grub_phys_start
213
&& (addr + ctx->size) < grub_phys_end)
215
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
216
if (addr + ctx->size >= end)
222
grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
224
if (addr >= linux_paddr && addr < linux_end)
227
if (addr + ctx->size >= end)
230
if ((addr + ctx->size) >= linux_paddr
231
&& (addr + ctx->size) < linux_end)
234
if (addr + ctx->size >= end)
183
243
static grub_addr_t
184
244
alloc_phys (grub_addr_t size)
186
grub_addr_t ret = (grub_addr_t) -1;
188
auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len,
189
grub_memory_type_t type);
190
int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len,
191
grub_memory_type_t type)
193
grub_addr_t end = addr + len;
198
addr = ALIGN_UP (addr, FOUR_MB);
199
if (addr + size >= end)
202
if (addr >= grub_phys_start && addr < grub_phys_end)
204
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
205
if (addr + size >= end)
208
if ((addr + size) >= grub_phys_start
209
&& (addr + size) < grub_phys_end)
211
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
212
if (addr + size >= end)
218
grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
220
if (addr >= linux_paddr && addr < linux_end)
223
if (addr + size >= end)
226
if ((addr + size) >= linux_paddr
227
&& (addr + size) < linux_end)
230
if (addr + size >= end)
239
grub_machine_mmap_iterate (choose);
246
struct alloc_phys_ctx ctx = {
248
.ret = (grub_addr_t) -1
251
grub_machine_mmap_iterate (alloc_phys_choose, &ctx);
244
256
static grub_err_t
275
287
base = linux_entry - off;
277
289
/* Now load the segments into the area we claimed. */
278
auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
279
grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
281
if (phdr->p_type != PT_LOAD)
288
/* Adjust the program load address to linux_addr. */
289
*addr = (phdr->p_paddr - base) + (linux_addr - off);
292
return grub_elf64_load (elf, filename, offset_phdr, 0, 0);
290
return grub_elf64_load (elf, filename, (void *) (linux_addr - off - base), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
295
293
static grub_err_t
395
files = grub_zalloc (argc * sizeof (files[0]));
390
if (grub_initrd_init (argc, argv, &initrd_ctx))
399
for (i = 0; i < argc; i++)
401
grub_file_filter_disable_compression ();
402
files[i] = grub_file_open (argv[i]);
406
size += ALIGN_UP(grub_file_size (files[i]), 4);
393
size = grub_get_initrd_size (&initrd_ctx);
409
395
addr = 0x60000000;
426
412
grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
427
413
addr, paddr, size);
430
for (i = 0; i < nfiles; i++)
432
grub_ssize_t cursize = grub_file_size (files[i]);
433
if (grub_file_read (files[i], ptr, cursize) != cursize)
436
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
441
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
442
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
415
if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
445
418
initrd_addr = addr;
446
419
initrd_paddr = paddr;
447
420
initrd_size = size;
450
for (i = 0; i < nfiles; i++)
451
grub_file_close (files[i]);
423
grub_initrd_close (&initrd_ctx);
454
425
return grub_errno;
428
/* Helper for determine_phys_base. */
430
get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__ ((unused)),
431
grub_memory_type_t type, void *data __attribute__ ((unused)))
435
if (addr < phys_base)
458
441
determine_phys_base (void)
460
auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
461
int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
465
if (addr < phys_base)
470
443
phys_base = ~(grub_uint64_t) 0;
471
grub_machine_mmap_iterate (get_physbase);
444
grub_machine_mmap_iterate (get_physbase, NULL);