From: Vladimir 'phcoder' Serbinenko Date: Sat, 30 Jan 2010 15:46:16 +0000 (+0100) Subject: merge mainline into newreloc X-Git-Tag: 1.99~629^2~114 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6e308bd94203ba085f6cad222f29d89c5db655bb;p=thirdparty%2Fgrub.git merge mainline into newreloc --- 6e308bd94203ba085f6cad222f29d89c5db655bb diff --cc conf/i386-coreboot.rmk index a4b132023,9563c0b2b..445f637aa --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@@ -32,10 -32,11 +32,11 @@@ kernel_img_SOURCES = kern/i386/coreboot term/i386/pc/vga_text.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h list.h handler.h command.h i18n.h mm_private.h - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ - env_private.h ++ machine/memory.h list.h handler.h command.h i18n.h \ ++ env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic @@@ -78,10 -79,11 +79,11 @@@ kernel_img_SOURCES = kern/i386/qemu/sta term/i386/pc/vga_text.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h list.h handler.h command.h i18n.h mm_private.h - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ - env_private.h ++ machine/memory.h list.h handler.h command.h i18n.h \ ++ env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) diff --cc conf/i386-efi.rmk index 3170784be,c03abb429..71a569a19 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@@ -50,9 -50,10 +50,10 @@@ kernel_img_SOURCES = kern/i386/efi/star kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h mm_private.h + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ - i18n.h env_private.h ++ i18n.h env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --cc conf/i386-ieee1275.rmk index 7750fef97,e19f6e9a1..b3397a807 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@@ -30,10 -30,10 +30,10 @@@ kernel_img_SOURCES = kern/i386/ieee1275 disk/ieee1275/ofdisk.c \ symlist.c kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \ - list.h handler.h command.h i18n.h env_private.h + ieee1275/ieee1275.h machine/kernel.h machine/memory.h \ - list.h handler.h command.h i18n.h mm_private.h ++ list.h handler.h command.h i18n.h env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic @@@ -54,7 -54,8 +54,7 @@@ sbin_SCRIPTS = grub-instal grub_install_SOURCES = util/ieee1275/grub-install.in # Modules. - pkglib_MODULES = halt.mod reboot.mod suspend.mod serial.mod \ -pkglib_MODULES = halt.mod reboot.mod suspend.mod \ - aout.mod serial.mod linux.mod \ ++pkglib_MODULES = halt.mod reboot.mod suspend.mod \ nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ date.mod datehook.mod lsmmap.mod mmap.mod @@@ -85,11 -91,16 +85,6 @@@ halt_mod_SOURCES = commands/halt. halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) --# For serial.mod. --serial_mod_SOURCES = term/serial.c --serial_mod_CFLAGS = $(COMMON_CFLAGS) --serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For linux.mod. -linux_mod_SOURCES = loader/i386/ieee1275/linux.c -linux_mod_CFLAGS = $(COMMON_CFLAGS) -linux_mod_LDFLAGS = $(COMMON_LDFLAGS) -- # For nand.mod. nand_mod_SOURCES = disk/ieee1275/nand.c nand_mod_CFLAGS = $(COMMON_CFLAGS) diff --cc conf/i386-pc.rmk index dd15979d4,580bfea0a..41c55c8a9 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@@ -64,7 -64,8 +64,8 @@@ kernel_img_HEADERS = boot.h cache.h dev partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ - machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i18n.h mm_private.h + machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ - i18n.h env_private.h ++ i18n.h env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) diff --cc conf/i386.rmk index aa2ec21df,d240858fe..5dcb7cdfb --- a/conf/i386.rmk +++ b/conf/i386.rmk @@@ -28,25 -26,12 +28,31 @@@ ata_mod_SOURCES = disk/ata. ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For linux.mod. +pkglib_MODULES += linux.mod +linux_mod_SOURCES = loader/i386/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod +pkglib_MODULES += aout.mod +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +pkglib_MODULES += bsd.mod +bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) + + # For setpci.mod + pkglib_MODULES += setpci.mod + setpci_mod_SOURCES = commands/setpci.c + setpci_mod_CFLAGS = $(COMMON_CFLAGS) + setpci_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += multiboot.mod multiboot_mod_SOURCES = loader/i386/multiboot.c \ loader/i386/multiboot_mbi.c \ diff --cc conf/mips.rmk index 0e96caeb4,1ef4fc395..845940189 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@@ -17,7 -17,7 +17,8 @@@ kernel_img_HEADERS = boot.h cache.h dev env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h mm_private.h - command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h env_private.h ++ command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h \ ++ env_private.h mm_private.h ifeq ($(platform), yeeloong) kernel_img_HEADERS += pci.h diff --cc conf/powerpc-ieee1275.rmk index fd6230771,23bd2d620..2a3334a4f --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@@ -15,9 -15,9 +15,9 @@@ DEFSYMFILES += kernel_syms.ls kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ - symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ + symbol.h term.h time.h types.h powerpc/libgcc.h partition.h \ msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ - command.h i18n.h mm_private.h - command.h i18n.h env_private.h ++ command.h i18n.h env_private.h mm_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --cc conf/sparc64-ieee1275.rmk index a056ddc67,befc7dce5..ece00e740 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@@ -31,7 -31,7 +31,7 @@@ kernel_img_HEADERS = boot.h cache.h dev partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ list.h handler.h command.h i18n.h \ sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ - sparc64/ieee1275/ieee1275.h mm_private.h - sparc64/ieee1275/ieee1275.h env_private.h ++ sparc64/ieee1275/ieee1275.h mm_private.h env_private.h kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ diff --cc conf/x86_64-efi.rmk index a4d1970aa,d5c3c24cb..0c196beeb --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@@ -52,7 -52,7 +52,7 @@@ kernel_img_HEADERS = boot.h cache.h dev env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ - handler.h command.h i18n.h mm_private.h - handler.h command.h i18n.h env_private.h ++ handler.h command.h i18n.h env_private.h mm_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --cc include/grub/i386/bsd.h index f0cce840e,4d55f04fb..a6abd7e90 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@@ -54,55 -50,46 +51,50 @@@ enum bsd_kernel_type #define FREEBSD_MODTYPE_ELF_MODULE_OBJ "elf obj module" #define FREEBSD_MODTYPE_RAW "raw" + #define FREEBSD_BOOTINFO_VERSION 1 + struct grub_freebsd_bootinfo { - grub_uint32_t bi_version; - grub_uint32_t bi_kernelname; - grub_uint32_t bi_nfs_diskless; - grub_uint32_t bi_n_bios_used; - grub_uint32_t bi_bios_geom[FREEBSD_N_BIOS_GEOM]; - grub_uint32_t bi_size; - grub_uint8_t bi_memsizes_valid; - grub_uint8_t bi_bios_dev; - grub_uint8_t bi_pad[2]; - grub_uint32_t bi_basemem; - grub_uint32_t bi_extmem; - grub_uint32_t bi_symtab; - grub_uint32_t bi_esymtab; - grub_uint32_t bi_kernend; - grub_uint32_t bi_envp; - grub_uint32_t bi_modulep; + grub_uint32_t version; + grub_uint8_t unused1[44]; + grub_uint32_t length; + grub_uint8_t unused2; + grub_uint8_t boot_device; + grub_uint8_t unused3[18]; + grub_uint32_t kern_end; + grub_uint32_t environment; + grub_uint32_t tags; } __attribute__ ((packed)); -struct grub_openbsd_bios_mmap +struct freebsd_tag_header { - grub_uint64_t addr; - grub_uint64_t len; -#define OPENBSD_MMAP_AVAILABLE 1 -#define OPENBSD_MMAP_RESERVED 2 -#define OPENBSD_MMAP_ACPI 3 -#define OPENBSD_MMAP_NVS 4 grub_uint32_t type; + grub_uint32_t len; }; -void grub_unix_real_boot (grub_addr_t entry, ...) - __attribute__ ((cdecl,noreturn)); -grub_err_t grub_freebsd_load_elfmodule32 (grub_file_t file, int argc, +grub_err_t grub_freebsd_load_elfmodule32 (struct grub_relocator *relocator, + grub_file_t file, int argc, char *argv[], grub_addr_t *kern_end); -grub_err_t grub_freebsd_load_elfmodule_obj64 (grub_file_t file, int argc, +grub_err_t grub_freebsd_load_elfmodule_obj64 (struct grub_relocator *relocator, + grub_file_t file, int argc, char *argv[], grub_addr_t *kern_end); -grub_err_t grub_freebsd_load_elf_meta32 (grub_file_t file, +grub_err_t grub_freebsd_load_elf_meta32 (struct grub_relocator *relocator, + grub_file_t file, grub_addr_t *kern_end); -grub_err_t grub_freebsd_load_elf_meta64 (grub_file_t file, +grub_err_t grub_freebsd_load_elf_meta64 (struct grub_relocator *relocator, + grub_file_t file, grub_addr_t *kern_end); -grub_err_t grub_freebsd_add_meta (grub_uint32_t type, void *data, - grub_uint32_t len); +grub_err_t grub_netbsd_load_elf_meta32 (struct grub_relocator *relocator, + grub_file_t file, + grub_addr_t *kern_end); +grub_err_t grub_netbsd_load_elf_meta64 (struct grub_relocator *relocator, + grub_file_t file, + grub_addr_t *kern_end); + +grub_err_t grub_bsd_add_meta (grub_uint32_t type, + void *data, grub_uint32_t len); grub_err_t grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv, grub_addr_t addr, grub_uint32_t size); diff --cc loader/i386/bsd.c index 9e222244e,3dd3c70c5..e7a8f5734 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@@ -584,44 -468,9 +584,44 @@@ grub_freebsd_boot (void bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); - bi.bi_bios_dev = biosdev; + bi.boot_device = biosdev; - p = (char *) kern_end; + p_size = 0; + grub_env_iterate (iterate_env_count); + + if (p_size) + p_size = ALIGN_PAGE (kern_end + p_size + 1) - kern_end; + + if (is_elf_kernel) + { + struct bsd_tag *tag; + + err = grub_bsd_add_mmap (); + if (err) + return err; + + err = grub_bsd_add_meta (FREEBSD_MODINFO_END, 0, 0); + if (err) + return err; + + tag_buf_len = 0; + for (tag = tags; tag; tag = tag->next) + tag_buf_len = ALIGN_VAR (tag_buf_len + + sizeof (struct freebsd_tag_header) + + tag->len); + p_size = ALIGN_PAGE (kern_end + p_size + tag_buf_len) - kern_end; + } + + if (is_64bit) + p_size += 4096 * 3; + + err = grub_relocator_alloc_chunk_addr (relocator, (void **) &p, + kern_end, p_size); + if (err) + return err; + p_target = kern_end; + p0 = p; + kern_end += p_size; grub_env_iterate (iterate_env); @@@ -629,127 -478,88 +629,127 @@@ { *(p++) = 0; - bi.bi_envp = p_target; - bi.environment = kern_end; - kern_end = ALIGN_PAGE ((grub_uint32_t) p); ++ bi.environment = p_target; } if (is_elf_kernel) { - grub_addr_t md_ofs; - int ofs; + grub_uint8_t *p_tag = p; + struct bsd_tag *tag; + + for (tag = tags; tag; tag = tag->next) + { + struct freebsd_tag_header *head + = (struct freebsd_tag_header *) p_tag; + head->type = tag->type; + head->len = tag->len; + p_tag += sizeof (struct freebsd_tag_header); + switch (tag->type) + { + case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_HOWTO: + if (is_64bit) + *(grub_uint64_t *) p_tag = bootflags; + else + *(grub_uint32_t *) p_tag = bootflags; + break; - if (grub_freebsd_add_meta (FREEBSD_MODINFO_END, 0, 0)) - return grub_errno; + case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ENVP: + if (is_64bit) - *(grub_uint64_t *) p_tag = bi.bi_envp; ++ *(grub_uint64_t *) p_tag = bi.environment; + else - *(grub_uint32_t *) p_tag = bi.bi_envp; ++ *(grub_uint32_t *) p_tag = bi.environment; + break; - grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len); - bi.tags = kern_end; + case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_KERNEND: + if (is_64bit) + *(grub_uint64_t *) p_tag = kern_end; + else + *(grub_uint32_t *) p_tag = kern_end; + break; - kern_end = ALIGN_PAGE (kern_end + mod_buf_len); + default: + grub_memcpy (p_tag, tag->data, tag->len); + break; + } + p_tag += tag->len; + p_tag = ALIGN_VAR (p_tag - p) + p; + } - bi.bi_modulep = (p - p0) + p_target; - if (is_64bit) - kern_end += 4096 * 4; ++ bi.tags = (p - p0) + p_target; - md_ofs = bi.tags + kern_end_mdofs; - ofs = (is_64bit) ? 16 : 12; - *((grub_uint32_t *) md_ofs) = kern_end; - md_ofs -= ofs; - *((grub_uint32_t *) md_ofs) = bi.environment; - md_ofs -= ofs; - *((grub_uint32_t *) md_ofs) = bootflags; + p = (ALIGN_PAGE ((p_tag - p0) + p_target) - p_target) + p0; } - bi.bi_kernend = kern_end; + bi.kern_end = kern_end; grub_video_set_mode ("text", 0, 0); if (is_64bit) { - grub_uint32_t *gdt; - grub_uint8_t *trampoline; - void (*launch_trampoline) (grub_addr_t entry_lo, ...) - __attribute__ ((cdecl, regparm (0))); + struct grub_relocator64_state state; grub_uint8_t *pagetable; + grub_uint32_t *stack; + grub_addr_t stack_target; + + err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack, + &stack_target, + 0x10000, 0x90000, + 3 * sizeof (grub_uint32_t) + + sizeof (bi), 4, + GRUB_RELOCATOR_PREFERENCE_NONE); + if (err) + return err; + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif - struct gdt_descriptor *gdtdesc; - - pagetable = (grub_uint8_t *) (kern_end - 16384); - fill_bsd64_pagetable (pagetable); - - /* Create GDT. */ - gdt = (grub_uint32_t *) (kern_end - 4096); - gdt[0] = 0; - gdt[1] = 0; - gdt[2] = 0; - gdt[3] = 0x00209800; - gdt[4] = 0; - gdt[5] = 0x00008000; - - /* Create GDT descriptor. */ - gdtdesc = (struct gdt_descriptor *) (kern_end - 4096 + 24); - gdtdesc->limit = 24; - gdtdesc->base = gdt; - - /* Prepare trampoline. */ - trampoline = (grub_uint8_t *) (kern_end - 4096 + 24 - + sizeof (struct gdt_descriptor)); - launch_trampoline = (void __attribute__ ((cdecl, regparm (0))) - (*) (grub_addr_t entry_lo, ...)) trampoline; - grub_bsd64_trampoline_gdt = (grub_uint32_t) gdtdesc; - grub_bsd64_trampoline_selfjump - = (grub_uint32_t) (trampoline + 6 - + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump - - &grub_bsd64_trampoline_start)); - - /* Copy trampoline. */ - grub_memcpy (trampoline, &grub_bsd64_trampoline_start, - &grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start); - - /* Launch trampoline. */ - launch_trampoline (entry, entry_hi, pagetable, bi.tags, - kern_end); + pagetable = p; + fill_bsd64_pagetable (pagetable, (pagetable - p0) + p_target); + + state.cr3 = (pagetable - p0) + p_target; + state.rsp = stack_target; + state.rip = (((grub_uint64_t) entry_hi) << 32) | entry; + + stack[0] = entry; - stack[1] = bi.bi_modulep; ++ stack[1] = bi.tags; + stack[2] = kern_end; + return grub_relocator64_boot (relocator, state, 0, 0x40000000); } else - grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev, - 0, 0, 0, &bi, bi.tags, kern_end); + { + struct grub_relocator32_state state; + grub_uint32_t *stack; + grub_addr_t stack_target; + err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack, + &stack_target, + 0x10000, 0x90000, + 9 * sizeof (grub_uint32_t) + + sizeof (bi), 4, + GRUB_RELOCATOR_PREFERENCE_NONE); + if (err) + return err; + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + + grub_memcpy (&stack[9], &bi, sizeof (bi)); + state.eip = entry; + state.esp = stack_target; + stack[0] = entry; /* "Return" address. */ + stack[1] = bootflags | FREEBSD_RB_BOOTINFO; + stack[2] = bootdev; + stack[3] = 0; + stack[4] = 0; + stack[5] = 0; + stack[6] = stack_target + 9 * sizeof (grub_uint32_t); - stack[7] = bi.bi_modulep; ++ stack[7] = bi.tags; + stack[8] = kern_end; + return grub_relocator32_boot (relocator, state); + } /* Not reached. */ return GRUB_ERR_NONE; diff --cc loader/mips/linux.c index 09c7f1275,64497f466..4c59e31d0 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@@ -325,18 -322,16 +325,18 @@@ grub_cmd_initrd (grub_command_t cmd __a { grub_file_t file = 0; grub_ssize_t size; - grub_size_t overhead; + void *initrd_src; + grub_addr_t initrd_dest; + grub_err_t err; if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No initrd specified"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); if (!loaded) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load Linux first."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load Linux first."); if (initrd_loaded) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one initrd can be loaded."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd can be loaded."); file = grub_file_open (argv[0]); if (! file) @@@ -344,22 -339,21 +344,22 @@@ size = grub_file_size (file); - overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000) - - (target_addr + linux_size); - - playground = grub_relocator32_realloc (playground, - linux_size + overhead + size); + err = grub_relocator_alloc_chunk_align (relocator, &initrd_src, + &initrd_dest, + target_addr + linux_size + 0x10000, + (0xffffffff - size) + 1, + size, 0x10000, + GRUB_RELOCATOR_PREFERENCE_NONE); - if (!playground) + if (err) { grub_file_close (file); - return grub_errno; + return err; } - if (grub_file_read (file, playground + linux_size + overhead, size) != size) + if (grub_file_read (file, initrd_src, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); grub_file_close (file); return grub_errno;