]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
merge mainline into newreloc
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 1 Apr 2010 20:17:26 +0000 (22:17 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 1 Apr 2010 20:17:26 +0000 (22:17 +0200)
24 files changed:
1  2 
conf/common.rmk
conf/i386-coreboot.rmk
conf/i386-ieee1275.rmk
conf/i386-pc.rmk
conf/i386.rmk
conf/mips.rmk
conf/powerpc-ieee1275.rmk
include/grub/aout.h
include/grub/misc.h
include/grub/multiboot.h
include/grub/xnu.h
kern/i386/coreboot/init.c
kern/i386/pc/init.c
kern/i386/pc/startup.S
kern/mm.c
loader/i386/bsd.c
loader/i386/linux.c
loader/i386/multiboot.c
loader/i386/multiboot_mbi.c
loader/i386/multiboot_mbi2.c
loader/i386/xnu.c
loader/xnu.c
term/serial.c
tests/util/grub-shell.in

diff --cc conf/common.rmk
index 538ba983272761fc71b80f7b5ae986b4e9e8832c,a7536d08e3113b505ca0f650da7c1dc37c88f1f7..fe1e11a1f5b075debd7c151f587e5246dd6ec372
@@@ -94,10 -105,27 +105,27 @@@ DISTCLEANFILES += grub_script.yy.c grub
  # For grub-script-check.
  bin_UTILITIES += grub-script-check
  util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h
- grub_script_check_SOURCES = gnulib/progname.c util/grub-script-check.c util/misc.c \
+ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \
+       util/grub-script-check.c util/misc.c \
        script/main.c script/script.c script/function.c script/lexer.c \
        kern/handler.c kern/err.c kern/parser.c kern/list.c \
-       kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c
+       kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \
+       grub_script.yy.c
+ grub_script_check_CFLAGS = $(GNULIB_CFLAGS)
+ MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+ DEFSYMFILES += kernel_syms.lst
+ 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 \
+       partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+       machine/memory.h machine/loader.h machine/kernel.h \
 -      list.h handler.h command.h i18n.h env_private.h
++      list.h handler.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)
+ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+       /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
  
  # For the parser.
  grub_script.tab.c grub_script.tab.h: script/parser.y
@@@ -718,14 -812,44 +812,50 @@@ password_pbkdf2_mod_SOURCES = commands/
  password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS)
  password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
  
+ # For memdisk.mod.
+ pkglib_MODULES += memdisk.mod
+ memdisk_mod_SOURCES = disk/memdisk.c
+ memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+ memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For reboot.mod.
+ pkglib_MODULES += reboot.mod
+ reboot_mod_SOURCES = commands/reboot.c
+ reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+ reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For date.mod
+ pkglib_MODULES += date.mod
+ date_mod_SOURCES = commands/date.c
+ date_mod_CFLAGS = $(COMMON_CFLAGS)
+ date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For datehook.mod
+ pkglib_MODULES += datehook.mod
+ datehook_mod_SOURCES = hook/datehook.c
+ datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+ datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For lsmmap.mod
+ pkglib_MODULES += lsmmap.mod
+ lsmmap_mod_SOURCES = commands/lsmmap.c
+ lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+ lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For boot.mod.
+ pkglib_MODULES += boot.mod
+ boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+ boot_mod_CFLAGS = $(COMMON_CFLAGS)
+ boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
  bin_UTILITIES += grub-mkpasswd-pbkdf2
- grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c
+ grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c
  grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1
  
 +# Randomly generated
 +SUCCESSFUL_BOOT_STRING=3e49994fd5d82b7c9298d672d774080d
 +BOOTCHECK_TIMEOUT=60
 +
 +bootcheck: $(BOOTCHECKS)
 +
  include $(srcdir)/conf/gcry.mk
index 445f637aa49b5d24f85805bdfb77696ff6e8e22a,3cef9313fa566e8f3a72a0b8f934593882d3f3f1..887df9ceea574e8b8d46b0fa868f81b1f1ae4748
@@@ -106,16 -35,7 +35,7 @@@ bin_SCRIPTS += grub-mkrescu
  grub_mkrescue_SOURCES = util/grub-mkrescue.in
  
  # Modules.
- pkglib_MODULES = play.mod             \
-       memdisk.mod pci.mod lspci.mod reboot.mod        \
-       halt.mod datetime.mod date.mod datehook.mod     \
-       lsmmap.mod mmap.mod
- # For boot.mod.
- pkglib_MODULES += boot.mod
- boot_mod_SOURCES = commands/boot.c
- boot_mod_CFLAGS = $(COMMON_CFLAGS)
- boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
++pkglib_MODULES = aout.mod halt.mod datetime.mod mmap.mod
  
  # For mmap.mod.
  mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
@@@ -123,11 -43,11 +43,6 @@@ mmap_mod_CFLAGS = $(COMMON_CFLAGS
  mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
  mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
  
- # For reboot.mod.
- reboot_mod_SOURCES = commands/reboot.c
- reboot_mod_CFLAGS = $(COMMON_CFLAGS)
- reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -# For linux.mod.
 -linux_mod_SOURCES = loader/i386/linux.c
 -linux_mod_CFLAGS = $(COMMON_CFLAGS)
 -linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
--
  # For halt.mod.
  halt_mod_SOURCES = commands/halt.c
  halt_mod_CFLAGS = $(COMMON_CFLAGS)
index b3397a8079f952182e0e522403a89fb78557d26e,d4a459b3e82ba5dbf31f3ca9816d2de1c9756003..2a2e9b0afbf465ebea3f1cfb5efa6d6bd09e194c
@@@ -54,15 -36,10 +36,7 @@@ sbin_SCRIPTS = grub-instal
  grub_install_SOURCES = util/ieee1275/grub-install.in
  
  # Modules.
- 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
- # For boot.mod.
- pkglib_MODULES += boot.mod
- boot_mod_SOURCES = commands/boot.c
- boot_mod_CFLAGS = $(COMMON_CFLAGS)
- boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -pkglib_MODULES = halt.mod suspend.mod         \
 -      aout.mod linux.mod      \
 -      nand.mod datetime.mod   \
 -      mmap.mod
++pkglib_MODULES = halt.mod suspend.mod aout.mod nand.mod datetime.mod mmap.mod
  
  # For mmap.mod.
  mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
index 41c55c8a97377da29ea06cc2b7fb71b338e0a814,ece88446b3847e4e8013e17197b7a8c3b57f919e..ea741cb7300ccf4e7ee64550a80e01672210d9c4
@@@ -116,20 -99,14 +99,10 @@@ grub_install_SOURCES = util/grub-instal
  bin_SCRIPTS += grub-mkrescue
  grub_mkrescue_SOURCES = util/grub-mkrescue.in
  
--pkglib_MODULES = biosdisk.mod chain.mod                               \
-       reboot.mod halt.mod                             \
-       vbe.mod vbetest.mod vbeinfo.mod play.mod                \
-       vga.mod memdisk.mod pci.mod lspci.mod                           \
-       pxe.mod pxecmd.mod datetime.mod date.mod        \
-       datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod                \
 -      halt.mod                                \
 -      vbe.mod vbetest.mod vbeinfo.mod                 \
 -      vga.mod                         \
 -      aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod        \
 -      ata_pthru.mod hdparm.mod                \
--      usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
--      efiemu.mod mmap.mod acpi.mod drivemap.mod
- # For boot.mod.
- pkglib_MODULES += boot.mod
- boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
- boot_mod_CFLAGS = $(COMMON_CFLAGS)
- boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
++pkglib_MODULES = biosdisk.mod chain.mod halt.mod vbe.mod vbetest.mod \
++      vbeinfo.mod vga.mod pxe.mod pxecmd.mod datetime.mod ata_pthru.mod \
++      hdparm.mod usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod \
++      usb_keyboard.mod efiemu.mod mmap.mod acpi.mod drivemap.mod
  
  # For drivemap.mod.
  drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
@@@ -217,21 -189,17 +180,6 @@@ vga_mod_SOURCES = term/i386/pc/vga.
  vga_mod_CFLAGS = $(COMMON_CFLAGS)
  vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
  
- # For memdisk.mod.
- memdisk_mod_SOURCES = disk/memdisk.c
- memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
- memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
- # For pci.mod
- pci_mod_SOURCES = bus/pci.c
- pci_mod_CFLAGS = $(COMMON_CFLAGS)
- pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -# For aout.mod
 -aout_mod_SOURCES = loader/aout.c
 -aout_mod_CFLAGS = $(COMMON_CFLAGS)
 -aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
--
- # For lspci.mod
- lspci_mod_SOURCES = commands/lspci.c
- lspci_mod_CFLAGS = $(COMMON_CFLAGS)
- lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -# For bsd.mod
 -bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
 -bsd_mod_CFLAGS = $(COMMON_CFLAGS)
 -bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
 -bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
--
  # For usb.mod
  usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
  usb_mod_CFLAGS = $(COMMON_CFLAGS)
diff --cc conf/i386.rmk
index 5dcb7cdfba62593ca5635d598eac85b692f30118,79a8e430b587c241f72f0806d602aaa531d9020f..87514cb1fbf9c43d928cc9a5f0f673a6b0df442d
@@@ -75,63 -52,21 +73,82 @@@ serial_mod_SOURCES = term/serial.
  serial_mod_CFLAGS = $(COMMON_CFLAGS)
  serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
  
 +linux.init.x86_64: $(srcdir)/tests/boot/linux.init-x86_64.S
 +      $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
 +
 +linux.init.i386: $(srcdir)/tests/boot/linux.init-i386.S
 +      $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
 +
 +kfreebsd.init.x86_64: $(srcdir)/tests/boot/kfreebsd.init-x86_64.S
 +      $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
 +
 +kfreebsd.init.i386: $(srcdir)/tests/boot/kfreebsd.init-i386.S
 +      $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
 +
 +knetbsd.init.i386: $(srcdir)/tests/boot/knetbsd.init-i386.S
 +      $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
 +
 +knetbsd.init.x86_64: $(srcdir)/tests/boot/knetbsd.init-x86_64.S
 +      $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
 +
 +linux-initramfs.%: linux.init.%
 +      TDIR=`mktemp -d`; cp $< $$TDIR/init; (cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR
 +
 +kfreebsd-mfsroot.%: kfreebsd.init.%
 +      TDIR=`mktemp -d`; mkdir $$TDIR/dev; mkdir $$TDIR/sbin; cp $< $$TDIR/sbin/init; makefs -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR; rm -rf $$TDIR
 +
 +knetbsd.image.%: knetbsd.init.%
 +      TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
 +
 +knetbsd.miniroot-image.i386: knetbsd.image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386
 +      $(OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@
 +
 +knetbsd.miniroot-image.x86_64: knetbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64
 +      $(OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $@
 +
 +CLEANFILES += linux.init.i386 kfreebsd.init.i386 linux.init.x86_64 linux-initramfs.i386 linux-initramfs.x86_64
 +
 +bootcheck-knetbsd-i386: knetbsd.miniroot-image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/tests/boot/knetbsd.cfg knetbsd.miniroot-image.i386 grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-i386 --files=/miniroot=knetbsd.miniroot-image.i386 --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64 $(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/tests/boot/knetbsd.cfg knetbsd.miniroot-image.x86_64 grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/miniroot=knetbsd.miniroot-image.x86_64 --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +bootcheck-kfreebsd-i386: kfreebsd-mfsroot.i386 $(GRUB_PAYLOADS_DIR)/kfreebsd.i386 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/tests/boot/kfreebsd.cfg grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-i386 --files=/mfsroot=kfreebsd-mfsroot.i386 --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.i386 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +bootcheck-kfreebsd-x86_64: kfreebsd-mfsroot.x86_64 $(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/tests/boot/kfreebsd.cfg grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/mfsroot=kfreebsd-mfsroot.x86_64 --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux.cfg grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-i386 --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +bootcheck-linux-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux.cfg grub-shell
 +      timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
 +
 +BOOTCHECKS+=bootcheck-linux-i386 bootcheck-linux-x86_64 \
 +      bootcheck-kfreebsd-i386 bootcheck-kfreebsd-x86_64 \
 +      bootcheck-knetbsd-i386 bootcheck-knetbsd-x86_64
 +
 +.PHONY: bootcheck-linux-i386 bootcheck-linux-x86_64 \
 +      bootcheck-kfreebsd-i386 bootcheck-kfreebsd-x86_64 \
 +      bootcheck-knetbsd-i386 bootcheck-knetbsd-x86_64
++
+ # For pci.mod
+ pkglib_MODULES += pci.mod
+ pci_mod_SOURCES = bus/pci.c
+ pci_mod_CFLAGS = $(COMMON_CFLAGS)
+ pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For lspci.mod
+ pkglib_MODULES += lspci.mod
+ lspci_mod_SOURCES = commands/lspci.c
+ lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+ lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For play.mod.
+ pkglib_MODULES += play.mod
+ play_mod_SOURCES = commands/i386/pc/play.c
+ play_mod_CFLAGS = $(COMMON_CFLAGS)
+ play_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --cc conf/mips.rmk
Simple merge
index 91f705bb434e1487210d76f6ed3b41198c289e59,86f6ddcb361c25b6834075a2c402e1c72015a0a0..7ebdb40334d3401fe8738e86bd67011091467451
@@@ -90,21 -60,10 +60,17 @@@ halt_mod_SOURCES = commands/halt.
  halt_mod_CFLAGS = $(COMMON_CFLAGS)
  halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
  
- # For memdisk.mod.
- memdisk_mod_SOURCES = disk/memdisk.c
- memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
- memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
- # For lsmmap.mod
- lsmmap_mod_SOURCES = commands/lsmmap.c
- lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
- lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+ # For datetime.mod
+ pkglib_MODULES += datetime.mod
+ datetime_mod_SOURCES = lib/ieee1275/datetime.c
+ datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+ datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
  
 +# For relocator.mod.
 +pkglib_MODULES += relocator.mod
 +relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/relocator.c lib/$(target_cpu)/relocator_asm.S
 +relocator_mod_CFLAGS = $(COMMON_CFLAGS)
 +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
 +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
 +
  include $(srcdir)/conf/common.mk
index b0b09abaf93fabbd944139b0037a2d06336f7f3b,f962a97b365d2aad8e67190b5cb14f2c0139f165..10d7dde61ececf0e980c6ad62420764fcefd5e67
@@@ -117,7 -120,9 +120,9 @@@ union grub_aout_heade
  int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header);
  
  grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset,
 -                                        grub_addr_t load_addr, int load_size,
 -                                        grub_addr_t bss_end_addr);
 +                                        void *load_addr, int load_size,
 +                                        grub_size_t bss_size);
  
+ #endif
  #endif /* ! GRUB_AOUT_HEADER */
Simple merge
index a74727e65c035dfbd947df546b97a1e219be6b1d,49d71fa09389b11597b946c89bd9c9cd92efaa2b..95b3f920fba258aeeeba4b243324436a15739103
@@@ -44,9 -45,30 +46,35 @@@ grub_err_t grub_multiboot_init_mbi (in
  grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
                                      int argc, char *argv[]);
  void grub_multiboot_set_bootdev (void);
 +void
 +grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
 +                          unsigned shndx, void *data);
  
+ grub_uint32_t grub_get_multiboot_mmap_count (void);
+ grub_err_t grub_multiboot_set_video_mode (void);
+ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+ #include <grub/i386/pc/vbe.h>
+ #define GRUB_MACHINE_HAS_VGA_TEXT 1
+ #else
+ #define GRUB_MACHINE_HAS_VGA_TEXT 0
+ #endif
+ #define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1
+ #define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 
+ grub_err_t
+ grub_multiboot_set_console (int console_type, int accepted_consoles,
+                           int width, int height, int depth,
+                           int console_required);
+ grub_err_t
+ grub_multiboot_load (grub_file_t file);
+ /* Load ELF32 or ELF64.  */
+ grub_err_t
+ grub_multiboot_load_elf (grub_file_t file, void *buffer);
+ extern grub_size_t grub_multiboot_pure_size;
+ extern grub_size_t grub_multiboot_alloc_mbi;
++extern grub_uint32_t grub_multiboot_payload_eip;
++
  
  #endif /* ! GRUB_MULTIBOOT_HEADER */
index 0b942d8557cd9c668d63dfd4dbd3a24fa334421e,6089aad341a6864f4390b9e43a9c946f9fa83dae..076aeb5ed359e18d03ac8d149183b501e4f0d90c
@@@ -102,12 -102,14 +102,15 @@@ grub_err_t grub_xnu_scan_dir_for_kexts 
                                        int maxrecursion);
  grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
                                        int maxrecursion);
 -void *grub_xnu_heap_malloc (int size);
 +grub_err_t grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target);
  grub_err_t grub_xnu_fill_devicetree (void);
 -extern grub_uint32_t grub_xnu_heap_real_start;
 +extern struct grub_relocator *grub_xnu_relocator;
 +
  extern grub_size_t grub_xnu_heap_size;
 -extern void *grub_xnu_heap_start;
  extern struct grub_video_bitmap *grub_xnu_bitmap;
+ typedef enum {GRUB_XNU_BITMAP_CENTER, GRUB_XNU_BITMAP_STRETCH}
+   grub_xnu_bitmap_mode_t;
+ extern grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;
  extern int grub_xnu_is_64bit;
 +extern grub_addr_t grub_xnu_heap_target_start;
  #endif
Simple merge
index 488d21425e9d1ed35df05f7c1d15281d1ee3c51d,fa646df1975195be594e28cc0a9c65f26ce9fb3f..ac859c2450f87a8a9101ab6f049c1f9813e47e66
@@@ -44,12 -44,9 +44,6 @@@ struct mem_regio
  static struct mem_region mem_regions[MAX_REGIONS];
  static int num_regions;
  
- void
- grub_arch_sync_caches (void *address __attribute__ ((unused)),
-                      grub_size_t len __attribute__ ((unused)))
- {
- }
 -grub_addr_t grub_os_area_addr;
 -grub_size_t grub_os_area_size;
--
  static char *
  make_install_device (void)
  {
Simple merge
diff --cc kern/mm.c
Simple merge
Simple merge
index a09c746321cad66458b982375150b2cc37a5e401,d3d935182ac3177506b7cc7f38e3055523336aaf..4a1068070484882732a17a028fb4889ff2a9c418
@@@ -628,20 -538,19 +620,25 @@@ grub_linux_boot (void
        grub_errno = GRUB_ERR_NONE;
      }
  
-   err = grub_linux_setup_video (params);
-   if (err)
+   if (! grub_linux_setup_video (params))
      {
-       grub_print_error ();
-       grub_errno = GRUB_ERR_NONE;
- #if HAS_VGA_TEXT
+       /* Use generic framebuffer unless VESA is known to be supported.  */
+       if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA)
+       params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
+       else
+       params->lfb_size >>= 16;
+     }
+   else
+     {
++#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
        params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
 -      params->video_width = 80;
 -      params->video_height = 25;
 +      params->video_mode = 0x3;
 +#else
 +      params->have_vga = 0;
 +      params->video_mode = 0;
 +      params->video_width = 0;
 +      params->video_height = 0;
 +#endif
      }
  
    /* Initialize these last, because terminal position could be affected by printfs above.  */
index 58e945f61a5d6263d9bd017f5557bcd81fcc5e1c,99d1cf9068f95c565e9097f682c95a08060804fc..e96788e2f4cdbef7448ebc167430de133425aec8
   *  - APM table
   */
  
- /* The bits in the required part of flags field we don't support.  */
- #define UNSUPPORTED_FLAGS                     0x0000fff8
  #include <grub/loader.h>
+ #include <grub/command.h>
+ #include <grub/machine/loader.h>
  #include <grub/multiboot.h>
 -#include <grub/cpu/multiboot.h>
 +#include <grub/machine/memory.h>
  #include <grub/elf.h>
  #include <grub/aout.h>
  #include <grub/file.h>
  #include <grub/efi/efi.h>
  #endif
  
- extern grub_dl_t my_mod;
 +struct grub_relocator *grub_multiboot_relocator = NULL;
- static grub_uint32_t grub_multiboot_payload_eip;
++grub_uint32_t grub_multiboot_payload_eip;
+ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+ #define DEFAULT_VIDEO_MODE "text"
+ #else
+ #define DEFAULT_VIDEO_MODE "auto"
+ #endif
 -grub_size_t grub_multiboot_alloc_mbi;
 -
 -char *grub_multiboot_payload_orig;
 -grub_addr_t grub_multiboot_payload_dest;
 -grub_size_t grub_multiboot_pure_size;
 -grub_uint32_t grub_multiboot_payload_eip;
+ static int accepts_video;
+ static int accepts_ega_text;
+ static int console_required;
+ static grub_dl_t my_mod;
+ /* Return the length of the Multiboot mmap that will be needed to allocate
+    our platform's map.  */
+ grub_uint32_t
+ grub_get_multiboot_mmap_count (void)
+ {
+   grub_size_t count = 0;
+   auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+   int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+                            grub_uint64_t size __attribute__ ((unused)),
+                            grub_uint32_t type __attribute__ ((unused)))
+     {
+       count++;
+       return 0;
+     }
+   grub_mmap_iterate (hook);
+   return count;
+ }
+ grub_err_t
+ grub_multiboot_set_video_mode (void)
+ {
+   grub_err_t err;
+   const char *modevar;
+   if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT)
+     {
+       modevar = grub_env_get ("gfxpayload");
+       if (! modevar || *modevar == 0)
+       err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
+       else
+       {
+         char *tmp;
+         tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
+         if (! tmp)
+           return grub_errno;
+         err = grub_video_set_mode (tmp, 0, 0);
+         grub_free (tmp);
+       }
+     }
+   else
+     err = grub_video_set_mode ("text", 0, 0);
+   return err;
+ }
  
  static grub_err_t
  grub_multiboot_boot (void)
@@@ -177,81 -262,13 +239,16 @@@ grub_cmd_multiboot (grub_command_t cmd 
    /* Skip filename.  */
    grub_multiboot_init_mbi (argc - 1, argv + 1);
  
 -  grub_relocator32_free (grub_multiboot_payload_orig);
 -  grub_multiboot_payload_orig = NULL;
++  grub_relocator_unload (grub_multiboot_relocator);
 +  grub_multiboot_relocator = grub_relocator_new ();
 +
 +  if (!grub_multiboot_relocator)
 +    goto fail;
  
-   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
-     {
-       int offset = ((char *) header - buffer -
-                   (header->header_addr - header->load_addr));
-       int load_size = ((header->load_end_addr == 0) ? file->size - offset :
-                      header->load_end_addr - header->load_addr);
-       grub_size_t code_size;
-       void *source;
-       if (header->bss_end_addr)
-       code_size = (header->bss_end_addr - header->load_addr);
-       else
-       code_size = load_size;
-       err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
-                                            &source, header->load_addr,
-                                            code_size);
-       if (err)
-       {
-         grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
-         goto fail;
-       }
-       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
-       goto fail;
-       grub_file_read (file, source, load_size);
-       if (grub_errno)
-       goto fail;
-       if (header->bss_end_addr)
-       grub_memset ((grub_uint32_t *) source + load_size, 0,
-                    header->bss_end_addr - header->load_addr - load_size);
-       grub_multiboot_payload_eip = header->entry_addr;
-     }
-   else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
+   err = grub_multiboot_load (file);
+   if (err)
      goto fail;
  
-   if (header->flags & MULTIBOOT_VIDEO_MODE)
-     {
-       switch (header->mode_type)
-       {
-       case 1:
-         grub_env_set ("gfxpayload", "text");
-         break;
-       case 0:
-         {
-           char *buf;
-           if (header->depth && header->width && header->height)
-             buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", header->width,
-                                  header->height, header->depth, header->width,
-                                  header->height);
-           else if (header->width && header->height)
-             buf = grub_xasprintf ("%dx%d,auto", header->width, header->height);
-           else
-             buf = grub_strdup ("auto");
-           if (!buf)
-             goto fail;
-           grub_env_set ("gfxpayload", buf);
-           grub_free (buf);
-           break;
-         }
-       }
-     }
-   grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE));
    grub_multiboot_set_bootdev ();
  
    grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
  
    if (grub_errno != GRUB_ERR_NONE)
      {
 -      grub_relocator32_free (grub_multiboot_payload_orig);
 -      grub_multiboot_free_mbi ();
 +      grub_relocator_unload (grub_multiboot_relocator);
++      grub_multiboot_relocator = NULL;
        grub_dl_unref (my_mod);
      }
+   return grub_errno;
  }
  
- void
- grub_module  (int argc, char *argv[])
+ static grub_err_t
+ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
  {
    grub_file_t file = 0;
    grub_ssize_t size;
    grub_err_t err;
  
    if (argc == 0)
-     {
-       grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-       goto fail;
-     }
+     return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
  
 -  if (!grub_multiboot_payload_orig)
 +  if (!grub_multiboot_relocator)
-     {
-       grub_error (GRUB_ERR_BAD_ARGUMENT,
-                 "you need to load the multiboot kernel first");
-       goto fail;
-     }
+     return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you need to load the multiboot kernel first");
  
    file = grub_gzfile_open (argv[0], 1);
    if (! file)
-     goto fail;
+     return grub_errno;
  
    size = grub_file_size (file);
 -  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
 -  if (! module)
 +  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &module, 
 +                                        &target,
 +                                        0, (0xffffffff - size) + 1,
 +                                        size, MULTIBOOT_MOD_ALIGN,
 +                                        GRUB_RELOCATOR_PREFERENCE_NONE);
 +  if (err)
-     goto fail;
+     {
+       grub_file_close (file);
 -      return grub_errno;
++      return err;
+     }
  
 -  err = grub_multiboot_add_module ((grub_addr_t) module, size,
 -                                 argc - 1, argv + 1);
 +  err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
    if (err)
-     goto fail;
+     {
+       grub_file_close (file);
+       return err;
+     }
  
    if (grub_file_read (file, module, size) != size)
      {
index e4a77911b274cc8163c133c3926bf990020a46e4,2a7c70f96f2e1a1bf0fd08cdf6bd90da327de771..989b92fd21ed7d464205253fa5bb9285c96f4f8b
  #include <grub/machine/biosnum.h>
  #endif
  #include <grub/multiboot.h>
 -#include <grub/cpu/multiboot.h>
+ #include <grub/cpu/relocator.h>
  #include <grub/disk.h>
  #include <grub/device.h>
  #include <grub/partition.h>
  #include <grub/mm.h>
  #include <grub/misc.h>
  #include <grub/env.h>
 +#include <grub/relocator.h>
  #include <grub/video.h>
+ #include <grub/file.h>
  
- #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
- #include <grub/i386/pc/vbe.h>
- #define DEFAULT_VIDEO_MODE "text"
- #define HAS_VGA_TEXT 1
- #else
- #define DEFAULT_VIDEO_MODE "auto"
- #define HAS_VGA_TEXT 0
- #endif
+ /* The bits in the required part of flags field we don't support.  */
+ #define UNSUPPORTED_FLAGS                     0x0000fff8
  
  struct module
  {
@@@ -56,45 -52,140 +52,141 @@@ static unsigned modcnt
  static char *cmdline = NULL;
  static grub_uint32_t bootdev;
  static int bootdev_set;
- static int accepts_video;
 +static grub_size_t elf_sec_num, elf_sec_entsize;
 +static unsigned elf_sec_shstrndx;
 +static void *elf_sections;
- void
- grub_multiboot_set_accepts_video (int val)
- {
-   accepts_video = val;
- }
 +
  
- /* Return the length of the Multiboot mmap that will be needed to allocate
-    our platform's map.  */
- static grub_uint32_t
- grub_get_multiboot_mmap_len (void)
+ grub_err_t
+ grub_multiboot_load (grub_file_t file)
  {
-   grub_size_t count = 0;
+   char *buffer;
+   grub_ssize_t len;
+   struct multiboot_header *header;
+   grub_err_t err;
  
-   auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-   int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
-                            grub_uint64_t size __attribute__ ((unused)),
-                            grub_uint32_t type __attribute__ ((unused)))
+   buffer = grub_malloc (MULTIBOOT_SEARCH);
+   if (!buffer)
+     return grub_errno;
+   len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+   if (len < 32)
      {
-       count++;
-       return 0;
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_BAD_OS, "file too small");
      }
  
-   grub_mmap_iterate (hook);
+   /* Look for the multiboot header in the buffer.  The header should
+      be at least 12 bytes and aligned on a 4-byte boundary.  */
+   for (header = (struct multiboot_header *) buffer;
+        ((char *) header <= buffer + len - 12) || (header = 0);
+        header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
+     {
+       if (header->magic == MULTIBOOT_HEADER_MAGIC
+         && !(header->magic + header->flags + header->checksum))
+       break;
+     }
+   if (header == 0)
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
+     }
  
-   return count * sizeof (struct multiboot_mmap_entry);
+   if (header->flags & UNSUPPORTED_FLAGS)
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_UNKNOWN_OS,
+                        "unsupported flag: 0x%x", header->flags);
+     }
+   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
+     {
+       int offset = ((char *) header - buffer -
+                   (header->header_addr - header->load_addr));
+       int load_size = ((header->load_end_addr == 0) ? file->size - offset :
+                      header->load_end_addr - header->load_addr);
+       grub_size_t code_size;
++      void *source;
+       if (header->bss_end_addr)
+       code_size = (header->bss_end_addr - header->load_addr);
+       else
+       code_size = load_size;
 -      grub_multiboot_payload_dest = header->load_addr;
 -
 -      grub_multiboot_pure_size += code_size;
 -
 -      /* Allocate a bit more to avoid relocations in most cases.  */
 -      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
 -      grub_multiboot_payload_orig
 -      = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
 -      if (! grub_multiboot_payload_orig)
++      err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
++                                           &source, header->load_addr,
++                                           code_size);
++      if (err)
+       {
++        grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
+         grub_free (buffer);
 -        return grub_errno;
++        return err;
+       }
+       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
 -      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
++      grub_file_read (file, source, load_size);
+       if (grub_errno)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+       if (header->bss_end_addr)
 -      grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
++      grub_memset ((grub_uint32_t *) source + load_size, 0,
+                    header->bss_end_addr - header->load_addr - load_size);
+       grub_multiboot_payload_eip = header->entry_addr;
 -
+     }
+   else
+     {
+       err = grub_multiboot_load_elf (file, buffer);
+       if (err)
+       {
+         grub_free (buffer);
+         return err;
+       }
+     }
+   if (header->flags & MULTIBOOT_VIDEO_MODE)
+     {
+       switch (header->mode_type)
+       {
+       case 1:
+         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
+                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
+                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           0, 0, 0, 0);
+         break;
+       case 0:
+         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
+                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           header->width, header->height,
+                                           header->depth, 0);
+         break;
+       }
+     }
+   else
+     err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
+                                     GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
+                                     0, 0, 0, 0);
+   return err;
  }
  
 -grub_size_t
 +static grub_size_t
  grub_multiboot_get_mbi_size (void)
  {
    return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
      + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
-     + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len ()
+     + ALIGN_UP (sizeof(PACKAGE_STRING), 4) 
+     + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
 +    + elf_sec_entsize * elf_sec_num
      + 256 * sizeof (struct multiboot_color);
  }
  
index 0000000000000000000000000000000000000000,1910d656ed4c2a19e59040056fe753db6e76470d..2b1a8022a3b97e4236085c9de4cafbf8f2309cd5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,700 +1,706 @@@
 -#include <grub/cpu/multiboot.h>
+ /*
+  *  GRUB  --  GRand Unified Bootloader
+  *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+  *
+  *  GRUB is free software: you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation, either version 3 of the License, or
+  *  (at your option) any later version.
+  *
+  *  GRUB is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *
+  *  You should have received a copy of the GNU General Public License
+  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+  */
+ #include <grub/machine/memory.h>
+ #include <grub/memory.h>
+ #ifdef GRUB_MACHINE_PCBIOS
+ #include <grub/machine/biosnum.h>
+ #endif
+ #include <grub/multiboot.h>
 -      grub_multiboot_payload_dest = addr_tag->load_addr;
+ #include <grub/cpu/relocator.h>
+ #include <grub/disk.h>
+ #include <grub/device.h>
+ #include <grub/partition.h>
+ #include <grub/mm.h>
+ #include <grub/misc.h>
+ #include <grub/env.h>
+ #include <grub/video.h>
+ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+ #include <grub/i386/pc/vbe.h>
+ #define HAS_VGA_TEXT 1
+ #else
+ #define HAS_VGA_TEXT 0
+ #endif
+ struct module
+ {
+   struct module *next;
+   grub_addr_t start;
+   grub_size_t size;
+   char *cmdline;
+   int cmdline_size;
+ };
+ struct module *modules, *modules_last;
+ static grub_size_t cmdline_size;
+ static grub_size_t total_modcmd;
+ static unsigned modcnt;
+ static char *cmdline = NULL;
+ static int bootdev_set;
+ static grub_uint32_t biosdev, slice, part;
+ grub_err_t
+ grub_multiboot_load (grub_file_t file)
+ {
+   char *buffer;
+   grub_ssize_t len;
+   struct multiboot_header *header;
+   grub_err_t err;
+   struct multiboot_header_tag *tag;
+   struct multiboot_header_tag_address *addr_tag = NULL;
+   int entry_specified = 0;
+   grub_addr_t entry = 0;
+   grub_uint32_t console_required = 0;
+   struct multiboot_header_tag_framebuffer *fbtag = NULL;
+   int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
+   buffer = grub_malloc (MULTIBOOT_SEARCH);
+   if (!buffer)
+     return grub_errno;
+   len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+   if (len < 32)
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_BAD_OS, "file too small");
+     }
+   /* Look for the multiboot header in the buffer.  The header should
+      be at least 12 bytes and aligned on a 4-byte boundary.  */
+   for (header = (struct multiboot_header *) buffer;
+        ((char *) header <= buffer + len - 12) || (header = 0);
+        header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
+     {
+       if (header->magic == MULTIBOOT_HEADER_MAGIC
+         && !(header->magic + header->architecture
+              + header->header_length + header->checksum))
+       break;
+     }
+   if (header == 0)
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
+     }
+   for (tag = (struct multiboot_header_tag *) (header + 1);
+        tag->type != MULTIBOOT_TAG_TYPE_END;
+        tag = (struct multiboot_header_tag *) ((char *) tag + tag->size))
+     switch (tag->type)
+       {
+       case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST:
+       {
+         unsigned i;
+         struct multiboot_header_tag_information_request *request_tag
+           = (struct multiboot_header_tag_information_request *) tag;
+         if (request_tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)
+           break;
+         for (i = 0; i < (request_tag->size - sizeof (request_tag))
+                / sizeof (request_tag->requests[0]); i++)
+           switch (request_tag->requests[i])
+             {
+             case MULTIBOOT_TAG_TYPE_END:
+             case MULTIBOOT_TAG_TYPE_CMDLINE:
+             case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
+             case MULTIBOOT_TAG_TYPE_MODULE:
+             case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
+             case MULTIBOOT_TAG_TYPE_BOOTDEV:
+             case MULTIBOOT_TAG_TYPE_MMAP:
+             case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
+               break;
+             case MULTIBOOT_TAG_TYPE_VBE:
+             case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
+             case MULTIBOOT_TAG_TYPE_APM:
+             default:
+               grub_free (buffer);
+               return grub_error (GRUB_ERR_UNKNOWN_OS,
+                                  "unsupported information tag: 0x%x",
+                                  request_tag->requests[i]);
+             }
+         break;
+       }
+              
+       case MULTIBOOT_HEADER_TAG_ADDRESS:
+       addr_tag = (struct multiboot_header_tag_address *) tag;
+       break;
+       case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS:
+       entry_specified = 1;
+       entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
+       break;
+       case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
+       if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
+           & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
+         accepted_consoles &= ~GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
+       if (((struct multiboot_header_tag_console_flags *) tag)->console_flags
+           & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED)
+         console_required = 1;
+       break;
+       case MULTIBOOT_HEADER_TAG_FRAMEBUFFER:
+       fbtag = (struct multiboot_header_tag_framebuffer *) tag;
+       accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
+       break;
+       /* GRUB always page-aligns modules.  */
+       case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
+       break;
+       default:
+       if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
+         {
+           grub_free (buffer);
+           return grub_error (GRUB_ERR_UNKNOWN_OS,
+                              "unsupported tag: 0x%x", tag->type);
+         }
+       break;
+       }
+   if (addr_tag && !entry_specified)
+     {
+       grub_free (buffer);
+       return grub_error (GRUB_ERR_UNKNOWN_OS,
+                        "load address tag without entry address tag");
+     }
+  
+   if (addr_tag)
+     {
+       int offset = ((char *) header - buffer -
+                   (addr_tag->header_addr - addr_tag->load_addr));
+       int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
+                      addr_tag->load_end_addr - addr_tag->load_addr);
+       grub_size_t code_size;
++      void *source;
+       if (addr_tag->bss_end_addr)
+       code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
+       else
+       code_size = load_size;
 -      grub_multiboot_pure_size += code_size;
 -
 -      /* Allocate a bit more to avoid relocations in most cases.  */
 -      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
 -      grub_multiboot_payload_orig
 -      = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
 -
 -      if (! grub_multiboot_payload_orig)
 -        return grub_errno;
++      err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
++                                           &source, addr_tag->load_addr,
++                                           code_size);
++      if (err)
+       {
++        grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
+         grub_free (buffer);
 -      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
++        return err;
+       }
+       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
 -      grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
++      grub_file_read (file, source, load_size);
+       if (grub_errno)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+       if (addr_tag->bss_end_addr)
 -grub_size_t
++      grub_memset ((grub_uint32_t *) source + load_size, 0,
+                    addr_tag->bss_end_addr - addr_tag->load_addr - load_size);
+     }
+   else
+     {
+       err = grub_multiboot_load_elf (file, buffer);
+       if (err)
+       {
+         grub_free (buffer);
+         return err;
+       }
+     }
+   if (entry_specified)
+     grub_multiboot_payload_eip = entry;
+   if (fbtag)
+     err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                     accepted_consoles,
+                                     fbtag->width, fbtag->height,
+                                     fbtag->depth, console_required);
+   else
+     err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
+                                     accepted_consoles,
+                                     0, 0, 0, console_required);
+   return err;
+ }
 -grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
 -                       grub_size_t bufsize)
++static grub_size_t
+ grub_multiboot_get_mbi_size (void)
+ {
+   return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+     + (sizeof (struct multiboot_tag_string)
+        + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
+     + (sizeof (struct multiboot_tag_string)
+        + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN))
+     + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
+     + sizeof (struct multiboot_tag_basic_meminfo)
+     + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
+     + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
+        * sizeof (struct multiboot_mmap_entry))
+     + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
+ }
+ /* Fill previously allocated Multiboot mmap.  */
+ static void
+ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
+ {
+   struct multiboot_mmap_entry *mmap_entry = tag->entries;
+   auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+   int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+     {
+       mmap_entry->addr = addr;
+       mmap_entry->len = size;
+       switch (type)
+       {
+       case GRUB_MACHINE_MEMORY_AVAILABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
+         break;
+ #ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE
+       case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
+         break;
+ #endif
+ #ifdef GRUB_MACHINE_MEMORY_NVS
+       case GRUB_MACHINE_MEMORY_NVS:
+         mmap_entry->type = MULTIBOOT_MEMORY_NVS;
+         break;
+ #endif          
+         
+       default:
+         mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
+         break;
+       }
+       mmap_entry++;
+       return 0;
+     }
+   tag->type = MULTIBOOT_TAG_TYPE_MMAP;
+   tag->size = sizeof (struct multiboot_tag_mmap)
+     + sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count (); 
+   tag->entry_size = sizeof (struct multiboot_mmap_entry);
+   tag->entry_version = 0;
+   grub_mmap_iterate (hook);
+ }
+ static grub_err_t
+ retrieve_video_parameters (grub_uint8_t **ptrorig)
+ {
+   grub_err_t err;
+   struct grub_video_mode_info mode_info;
+   void *framebuffer;
+   grub_video_driver_id_t driv_id;
+   struct grub_video_palette_data palette[256];
+   struct multiboot_tag_framebuffer *tag
+     = (struct multiboot_tag_framebuffer *) *ptrorig;
+   err = grub_multiboot_set_video_mode ();
+   if (err)
+     {
+       grub_print_error ();
+       grub_errno = GRUB_ERR_NONE;
+     }
+   grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
+   driv_id = grub_video_get_driver_id ();
+ #if HAS_VGA_TEXT
+   if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+     {
+       struct grub_vbe_mode_info_block vbe_mode_info;
+       grub_uint32_t vbe_mode;
+ #if defined (GRUB_MACHINE_PCBIOS)
+       {
+       grub_vbe_status_t status;
+       void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+       status = grub_vbe_bios_get_mode (scratch);
+       vbe_mode = *(grub_uint32_t *) scratch;
+       if (status != GRUB_VBE_STATUS_OK)
+         return GRUB_ERR_NONE;
+       }
+ #else
+       vbe_mode = 3;
+ #endif
+       /* get_mode_info isn't available for mode 3.  */
+       if (vbe_mode == 3)
+       {
+         grub_memset (&vbe_mode_info, 0,
+                      sizeof (struct grub_vbe_mode_info_block));
+         vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
+         vbe_mode_info.x_resolution = 80;
+         vbe_mode_info.y_resolution = 25;
+       }
+ #if defined (GRUB_MACHINE_PCBIOS)
+       else
+       {
+         grub_vbe_status_t status;
+         void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+         status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
+         if (status != GRUB_VBE_STATUS_OK)
+           return GRUB_ERR_NONE;
+         grub_memcpy (&vbe_mode_info, scratch,
+                      sizeof (struct grub_vbe_mode_info_block));
+       }
+ #endif
+       if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
+       {
+         tag = (struct multiboot_tag_framebuffer *) *ptrorig;
+         tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
+         tag->common.size = 0;
+         tag->common.framebuffer_addr = 0xb8000;
+         
+         tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution;       
+         tag->common.framebuffer_width = vbe_mode_info.x_resolution;
+         tag->common.framebuffer_height = vbe_mode_info.y_resolution;
+         tag->common.framebuffer_bpp = 16;
+         
+         tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
+         tag->common.size = sizeof (tag->common);
+         tag->common.reserved = 0;
+         *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
+       }
+       return GRUB_ERR_NONE;
+     }
+ #else
+   if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+     return GRUB_ERR_NONE;
+ #endif
+   err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+   if (err)
+     return err;
+   tag = (struct multiboot_tag_framebuffer *) *ptrorig;
+   tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
+   tag->common.size = 0;
+   tag->common.framebuffer_addr = (grub_addr_t) framebuffer;
+   tag->common.framebuffer_pitch = mode_info.pitch;
+   tag->common.framebuffer_width = mode_info.width;
+   tag->common.framebuffer_height = mode_info.height;
+   tag->common.framebuffer_bpp = mode_info.bpp;
+   tag->common.reserved = 0;
+       
+   if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
+     {
+       unsigned i;
+       tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
+       tag->framebuffer_palette_num_colors = mode_info.number_of_colors;
+       if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
+       tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
+       tag->common.size = sizeof (struct multiboot_tag_framebuffer_common)
+       + sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors
+       * sizeof (struct multiboot_color);
+       for (i = 0; i < tag->framebuffer_palette_num_colors; i++)
+       {
+         tag->framebuffer_palette[i].red = palette[i].r;
+         tag->framebuffer_palette[i].green = palette[i].g;
+         tag->framebuffer_palette[i].blue = palette[i].b;
+       }
+     }
+   else
+     {
+       tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
+       tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
+       tag->framebuffer_red_field_position = mode_info.green_field_pos;
+       tag->framebuffer_red_mask_size = mode_info.green_mask_size;
+       tag->framebuffer_green_field_position = mode_info.green_field_pos;
+       tag->framebuffer_green_mask_size = mode_info.green_mask_size;
+       tag->framebuffer_blue_field_position = mode_info.blue_field_pos;
+       tag->framebuffer_blue_mask_size = mode_info.blue_mask_size;
+       tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
+     }
+   *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
+   return GRUB_ERR_NONE;
+ }
+ grub_err_t
 -  grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off 
 -    + (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
++grub_multiboot_make_mbi (grub_uint32_t *target)
+ {
+   grub_uint8_t *ptrorig;
 -  if (bufsize < grub_multiboot_get_mbi_size ())
 -    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
++  grub_uint8_t *mbistart;
+   grub_err_t err;
++  grub_size_t bufsize;
++  grub_addr_t ptrdest;
++
++  bufsize = grub_multiboot_get_mbi_size ();
++
++  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, 
++                                        (void **) &ptrorig, &ptrdest,
++                                        0, 0xffffffff - bufsize,
++                                        bufsize, 4,
++                                        GRUB_RELOCATOR_PREFERENCE_NONE);
++  if (err)
++    return err;
 -  ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
++  *target = ptrdest;
 -      tag->mod_start = dest + cur->start;
++  mbistart = ptrorig;
++  ptrorig += 2 * sizeof (grub_uint32_t);
+   {
+     struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
+     tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
+     tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
+     grub_memcpy (tag->string, cmdline, cmdline_size);
+     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+   }
+   {
+     struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
+     tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
+     tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); 
+     grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
+     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+   }
+   {
+     unsigned i;
+     struct module *cur;
+     for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
+       {
+       struct multiboot_tag_module *tag
+         = (struct multiboot_tag_module *) ptrorig;
+       tag->type = MULTIBOOT_TAG_TYPE_MODULE;
+       tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
++      tag->mod_start = cur->start;
+       tag->mod_end = tag->mod_start + cur->size;
+       grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
+       ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+       }
+   }
+   {
+     struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
+     grub_fill_multiboot_mmap (tag);
+     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+   }
+   {
+     struct multiboot_tag_basic_meminfo *tag
+       = (struct multiboot_tag_basic_meminfo *) ptrorig;
+     tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
+     tag->size = sizeof (struct multiboot_tag_basic_meminfo); 
+     /* Convert from bytes to kilobytes.  */
+     tag->mem_lower = grub_mmap_get_lower () / 1024;
+     tag->mem_upper = grub_mmap_get_upper () / 1024;
+     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+   }
+   if (bootdev_set)
+     {
+       struct multiboot_tag_bootdev *tag
+       = (struct multiboot_tag_bootdev *) ptrorig;
+       tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV;
+       tag->size = sizeof (struct multiboot_tag_bootdev); 
+       tag->biosdev = biosdev;
+       tag->slice = slice;
+       tag->part = part;
+       ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+     }
+   {
+     err = retrieve_video_parameters (&ptrorig);
+     if (err)
+       {
+       grub_print_error ();
+       grub_errno = GRUB_ERR_NONE;
+       }
+   }
+   
+   {
+     struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
+     tag->type = MULTIBOOT_TAG_TYPE_END;
+     tag->size = sizeof (struct multiboot_tag);
+     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+   }
+   ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart;
+   ((grub_uint32_t *) mbistart)[1] = 0;
+   return GRUB_ERR_NONE;
+ }
+ void
+ grub_multiboot_free_mbi (void)
+ {
+   struct module *cur, *next;
+   cmdline_size = 0;
+   total_modcmd = 0;
+   modcnt = 0;
+   grub_free (cmdline);
+   cmdline = NULL;
+   bootdev_set = 0;
+   for (cur = modules; cur; cur = next)
+     {
+       next = cur->next;
+       grub_free (cur->cmdline);
+       grub_free (cur);
+     }
+   modules = NULL;
+   modules_last = NULL;
+ }
+ grub_err_t
+ grub_multiboot_init_mbi (int argc, char *argv[])
+ {
+   grub_ssize_t len = 0;
+   char *p;
+   int i;
+   grub_multiboot_free_mbi ();
+   for (i = 0; i < argc; i++)
+     len += grub_strlen (argv[i]) + 1;
+   if (len == 0)
+     len = 1;
+   cmdline = p = grub_malloc (len);
+   if (! cmdline)
+     return grub_errno;
+   cmdline_size = len;
+   for (i = 0; i < argc; i++)
+     {
+       p = grub_stpcpy (p, argv[i]);
+       *(p++) = ' ';
+     }
+   /* Remove the space after the last word.  */
+   if (p != cmdline)
+     p--;
+   *p = '\0';
+   return GRUB_ERR_NONE;
+ }
+ grub_err_t
+ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
+                          int argc, char *argv[])
+ {
+   struct module *newmod;
+   char *p;
+   grub_ssize_t len = 0;
+   int i;
+   newmod = grub_malloc (sizeof (*newmod));
+   if (!newmod)
+     return grub_errno;
+   newmod->start = start;
+   newmod->size = size;
+   for (i = 0; i < argc; i++)
+     len += grub_strlen (argv[i]) + 1;
+   if (len == 0)
+     len = 1;
+   newmod->cmdline = p = grub_malloc (len);
+   if (! newmod->cmdline)
+     {
+       grub_free (newmod);
+       return grub_errno;
+     }
+   newmod->cmdline_size = len;
+   total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
+   for (i = 0; i < argc; i++)
+     {
+       p = grub_stpcpy (p, argv[i]);
+       *(p++) = ' ';
+     }
+   /* Remove the space after the last word.  */
+   if (p != newmod->cmdline)
+     p--;
+   *p = '\0';
+   if (modules_last)
+     modules_last->next = newmod;
+   else
+     {
+       modules = newmod;
+       modules_last->next = NULL;
+     }
+   modules_last = newmod;
+   modcnt++;
+   return GRUB_ERR_NONE;
+ }
+ void
+ grub_multiboot_set_bootdev (void)
+ {
+   grub_device_t dev;
+   slice = ~0;
+   part = ~0;
+ #ifdef GRUB_MACHINE_PCBIOS
+   biosdev = grub_get_root_biosnumber ();
+ #else
+   biosdev = 0xffffffff;
+ #endif
+   if (biosdev == 0xffffffff)
+     return;
+   dev = grub_device_open (0);
+   if (dev && dev->disk && dev->disk->partition)
+     {
+       if (dev->disk->partition->parent)
+       {
+         part = dev->disk->partition->number;
+         slice = dev->disk->partition->parent->number;
+       }
+       else
+       slice = dev->disk->partition->number;
+     }
+   if (dev)
+     grub_device_close (dev);
+   bootdev_set = 1;
+ }
index 8040e65e3761579274dc8f6deb8fcd5f30309393,8000579d00f8d01d6c8643dabace404bcd057d5d..bdcd383c52ab47c329ecb1eedbeac009da75c5df
  #include <grub/command.h>
  #include <grub/gzio.h>
  #include <grub/i18n.h>
++#include <grub/bitmap_scale.h>
 +
 +#define min(a,b) (((a) < (b)) ? (a) : (b))
 +#define max(a,b) (((a) > (b)) ? (a) : (b))
 +
 +#define DEFAULT_VIDEO_MODE "auto"
  
  char grub_xnu_cmdline[1024];
 -grub_uint32_t grub_xnu_heap_will_be_at;
  grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
  
  /* Aliases set for some tables. */
@@@ -838,83 -834,8 +839,100 @@@ grub_xnu_boot_resume (void
    state.eip = grub_xnu_entry_point;
    state.eax = grub_xnu_arg1;
  
 -  return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
 -                              state); 
 +  return grub_relocator32_boot (grub_xnu_relocator, state); 
 +}
 +
 +/* Setup video for xnu. */
 +static grub_err_t
 +grub_xnu_set_video (struct grub_xnu_boot_params *params)
 +{
 +  struct grub_video_mode_info mode_info;
 +  int ret;
-   char *tmp, *modevar;
++  char *tmp;
++  const char *modevar;
 +  void *framebuffer;
 +  grub_err_t err;
++  struct grub_video_bitmap *bitmap = NULL;
 +
 +  modevar = grub_env_get ("gfxpayload");
 +  /* Consider only graphical 32-bit deep modes.  */
 +  if (! modevar || *modevar == 0)
 +    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
 +                             GRUB_VIDEO_MODE_TYPE_PURE_TEXT
 +                             | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
 +                             32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
 +  else
 +    {
 +      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
 +      if (! tmp)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "couldn't allocate temporary storag");
++      return grub_errno;
 +      err = grub_video_set_mode (tmp,
 +                               GRUB_VIDEO_MODE_TYPE_PURE_TEXT
 +                               | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
 +                               32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
 +      grub_free (tmp);
 +    }
 +
 +  if (err)
 +    return err;
 +
++  ret = grub_video_get_info (&mode_info);
++  if (ret)
++    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
++
 +  if (grub_xnu_bitmap)
++     {
++       if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
++       err = grub_video_bitmap_create_scaled (&bitmap,
++                                              mode_info.width,
++                                              mode_info.height,
++                                              grub_xnu_bitmap,
++                                              GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
++       else
++       bitmap = grub_xnu_bitmap;
++     }
++
++  if (bitmap)
 +    {
 +      int x, y;
 +
-       x = mode_info.width - grub_xnu_bitmap->mode_info.width;
++      x = mode_info.width - bitmap->mode_info.width;
 +      x /= 2;
-       y = mode_info.height - grub_xnu_bitmap->mode_info.height;
++      y = mode_info.height - bitmap->mode_info.height;
 +      y /= 2;
-       err = grub_video_blit_bitmap (grub_xnu_bitmap,
++      err = grub_video_blit_bitmap (bitmap,
 +                                  GRUB_VIDEO_BLIT_REPLACE,
 +                                  x > 0 ? x : 0,
 +                                  y > 0 ? y : 0,
 +                                  x < 0 ? -x : 0,
 +                                  y < 0 ? -y : 0,
-                                   min (grub_xnu_bitmap->mode_info.width,
++                                  min (bitmap->mode_info.width,
 +                                       mode_info.width),
-                                   min (grub_xnu_bitmap->mode_info.height,
++                                  min (bitmap->mode_info.height,
 +                                       mode_info.height));
 +      if (err)
 +      {
 +        grub_print_error ();
 +        grub_errno = GRUB_ERR_NONE;
 +        grub_xnu_bitmap = 0;
 +      }
 +      err = GRUB_ERR_NONE;
 +    }
 +
 +  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
 +  if (ret)
 +    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
 +
 +  params->lfb_width = mode_info.width;
 +  params->lfb_height = mode_info.height;
 +  params->lfb_depth = mode_info.bpp;
 +  params->lfb_line_len = mode_info.pitch;
 +
 +  params->lfb_base = PTR_TO_UINT32 (framebuffer);
-   params->lfb_mode = grub_xnu_bitmap
-     ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
++  params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH
++    : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
 +
 +  return GRUB_ERR_NONE;
  }
  
  /* Boot xnu. */
diff --cc loader/xnu.c
Simple merge
diff --cc term/serial.c
index 9a195f0e7b91606e9e15c4e42a190767296757df,05497ce40976e7980e1a2e0e494b169fc13f4108..5b1ce7032d02088b0b33d7ca1c77ef637b958453
@@@ -612,8 -620,12 +620,12 @@@ GRUB_MOD_INIT(serial
                              "Configure serial port.", options);
  
    /* Set default settings.  */
 -  serial_settings.port      = serial_hw_get_port (0);
 +  serial_settings.port      = grub_serial_hw_get_port (0);
+ #ifdef GRUB_MACHINE_MIPS_YEELOONG
+   serial_settings.divisor   = serial_get_divisor (115200);
+ #else
    serial_settings.divisor   = serial_get_divisor (9600);
+ #endif
    serial_settings.word_len  = UART_8BITS_WORD;
    serial_settings.parity    = UART_NO_PARITY;
    serial_settings.stop_bits = UART_1_STOP_BIT;
Simple merge