merge with mainline
This commit is contained in:
commit
e5a73c4247
182 changed files with 9977 additions and 5276 deletions
|
@ -69,6 +69,7 @@ Makefile
|
||||||
mod-*.c
|
mod-*.c
|
||||||
missing
|
missing
|
||||||
*.pf2
|
*.pf2
|
||||||
|
*.pp
|
||||||
po/*.mo
|
po/*.mo
|
||||||
po/grub.pot
|
po/grub.pot
|
||||||
stamp-h
|
stamp-h
|
||||||
|
@ -91,7 +92,10 @@ texinfo.tex
|
||||||
grub-core/lib/libgcrypt-grub
|
grub-core/lib/libgcrypt-grub
|
||||||
**/.deps-util
|
**/.deps-util
|
||||||
**/.deps-core
|
**/.deps-core
|
||||||
|
**/.dirstamp
|
||||||
Makefile.util.am
|
Makefile.util.am
|
||||||
grub-core/Makefile.core.am
|
grub-core/Makefile.core.am
|
||||||
grub-core/Makefile.gcry.am
|
grub-core/Makefile.gcry.am
|
||||||
grub-core/Makefile.gcry.def
|
grub-core/Makefile.gcry.def
|
||||||
|
grub-core/*.module
|
||||||
|
grub-core/*.pp
|
||||||
|
|
912
ChangeLog
912
ChangeLog
|
@ -1,3 +1,915 @@
|
||||||
|
2010-09-04 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
|
Multi-line quoted strings support.
|
||||||
|
|
||||||
|
* grub-core/script/lexer.c (append_newline): Removed.
|
||||||
|
(grub_script_lexer_yywrap): Refactored.
|
||||||
|
(grub_script_lexer_init): Refactored.
|
||||||
|
* grub-core/script/yylex.l (yywrap): New function.
|
||||||
|
(grub_lexer_resplit): New function.
|
||||||
|
(grub_lexer_unput): New function.
|
||||||
|
* include/grub/script_sh.h (grub_lexer_param): New members, unput
|
||||||
|
and resplit.
|
||||||
|
* tests/grub_script_echo1.in: Added few more testcases.
|
||||||
|
|
||||||
|
2010-09-04 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/misc.c: Don't add abort alias in utils.
|
||||||
|
Reported by: echoline.
|
||||||
|
|
||||||
|
2010-09-03 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
|
Add missing files into "make dist" tarball for other platforms.
|
||||||
|
|
||||||
|
* gentpl.py (script): Use dist_noinst_DATA instead of EXTRA_DIST.
|
||||||
|
* conf/Makefile.common (dist_noinst_DATA): New variable.
|
||||||
|
* conf/Makefile.extra-dist: Added missing make dist files.
|
||||||
|
* grub-core/Makefile.core.def: Likewise.
|
||||||
|
|
||||||
|
2010-09-03 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Compress grub_prefix.
|
||||||
|
|
||||||
|
* grub-core/boot/i386/pc/lnxboot.S: Use
|
||||||
|
GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE.
|
||||||
|
* grub-core/kern/i386/pc/startup.S: Move grub_prefix to compressed part.
|
||||||
|
* include/grub/offsets.h: Rename GRUB_MACHINE_DATA_END to
|
||||||
|
GRUB_MACHINE_PREFIX_END. All users updated.
|
||||||
|
(GRUB_KERNEL_I386_PC_PREFIX): Set to GRUB_KERNEL_I386_PC_RAW_SIZE.
|
||||||
|
(GRUB_KERNEL_I386_PC_PREFIX_END): Set to GRUB_KERNEL_I386_PC_PREFIX
|
||||||
|
+ 0x40.
|
||||||
|
(GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease.
|
||||||
|
* util/grub-mkimage.c (image_target_desc): Change data_end to
|
||||||
|
prefix_end. All users updated.
|
||||||
|
|
||||||
|
2010-09-03 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane
|
||||||
|
value.
|
||||||
|
(grub_openbsd_boot): Likewise.
|
||||||
|
(grub_netbsd_boot): Likewise.
|
||||||
|
* grub-core/loader/i386/xnu.c (grub_xnu_boot_resume): Likewise.
|
||||||
|
(grub_xnu_boot): Likewise.
|
||||||
|
|
||||||
|
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* configure.ac: Clean LIBS variable after tests.
|
||||||
|
|
||||||
|
2010-09-02 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* INSTALL: Document that libdevmapper needs to be 1.02.34 or later.
|
||||||
|
|
||||||
|
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* configure.ac: Check for dm_log_with_errno_init in libdevmapper and
|
||||||
|
echo if libdevmapper will be used.
|
||||||
|
|
||||||
|
2010-09-02 Ian Turner <Ian.Turner@deshaw.com>
|
||||||
|
|
||||||
|
* grub-core/fs/i386/pc/pxe.c (grub_pxefs_read): Keep the blocksize
|
||||||
|
constant for the same file.
|
||||||
|
|
||||||
|
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/i386/multiboot_mmap.c: Remove leftover include.
|
||||||
|
|
||||||
|
2010-09-02 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* .bzrignore: Add *.pp, **/.dirstamp, grub-core/*.module, and
|
||||||
|
grub-core/*.pp.
|
||||||
|
|
||||||
|
2010-09-02 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
Zero %ebp and %edi when entering Linux's 32-bit entry point, as
|
||||||
|
required by the boot protocol.
|
||||||
|
|
||||||
|
* include/grub/i386/relocator.h (struct grub_relocator32_state): Add
|
||||||
|
ebp and edi members.
|
||||||
|
* grub-core/lib/i386/relocator.c (grub_relocator_boot): Handle
|
||||||
|
state.ebp and state.edi.
|
||||||
|
* grub-core/lib/i386/relocator32.S (grub_relocator32_start): Set
|
||||||
|
%ebp and %edi according to grub_relocator32_ebp and
|
||||||
|
grub_relocator32_edi respectively.
|
||||||
|
* grub-core/loader/i386/linux.c (grub_linux_boot): Zero state.ebp
|
||||||
|
and state.edi.
|
||||||
|
|
||||||
|
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Add i386-pc-pxe image target.
|
||||||
|
|
||||||
|
* util/grub-mkimage.c (image_target_desc): New enum value
|
||||||
|
IMAGE_I386_PC_PXE.
|
||||||
|
(image_targets): New target i386-pc-pxe.
|
||||||
|
(generate_image): Handle i386-pc-pxe image.
|
||||||
|
|
||||||
|
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fix grub_pxe_scan.
|
||||||
|
|
||||||
|
* grub-core/fs/i386/pc/pxe.c (grub_pxe_pxenv): Put correct type bangpxe.
|
||||||
|
(grub_pxe_scan): Fix types and pxe_rm_entry computation.
|
||||||
|
All users updated.
|
||||||
|
* include/grub/i386/pc/pxe.h (grub_pxe_bangpxe): New struct.
|
||||||
|
(grub_pxe_pxenv): Correct type.
|
||||||
|
|
||||||
|
2010-09-01 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* NEWS: Document most of the important changes since 1.98.
|
||||||
|
|
||||||
|
2010-09-01 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub-mkrescue.in (usage): Tidy up usage output (and hence
|
||||||
|
generated manual page) a little.
|
||||||
|
|
||||||
|
2010-09-01 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* docs/grub.texi: Add myself as an author.
|
||||||
|
|
||||||
|
2010-09-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrub.a): Add missing sunpc.
|
||||||
|
Reported by: Seth Goldberg.
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Interrupt wrapping and code simplifications.
|
||||||
|
|
||||||
|
* Makefile.util.def (grub-mkrescue): Use x86 tg instead of
|
||||||
|
x86_noieee1275 which are functionaly equivalent in this case.
|
||||||
|
(grub-install): Make source on each platform explicit. Enable on
|
||||||
|
all noemu.
|
||||||
|
* gentpl.py (x86_efi_pc): Removed group.
|
||||||
|
(x86_noefi): Likewise.
|
||||||
|
(i386_noefi): Likewise.
|
||||||
|
(x86_noieee1275): Likewise.
|
||||||
|
(i386_noieee1275): Likewise.
|
||||||
|
(i386_noefi_noieee1275): Likewise.
|
||||||
|
(i386_pc_qemu_coreboot): Likewise.
|
||||||
|
(i386_coreboot_multiboot): Likewise.
|
||||||
|
(i386_pc_coreboot_multiboot_qemu): Likewise.
|
||||||
|
(x86_noefi_mips): Likewise.
|
||||||
|
(noieee1275): Likewise.
|
||||||
|
(ieee1275_mips): Likewise.
|
||||||
|
(noemu_noieee1275): Likewise.
|
||||||
|
(cmos): New group.
|
||||||
|
(usb): Likewise.
|
||||||
|
(videoinkernel): Likewise.
|
||||||
|
(videomodules): Likewise.
|
||||||
|
* grub-core/Makefile.am (KERNEL_HEADER_FILES): Remove
|
||||||
|
include/grub/elf.h, include/grub/elfload.h, include/grub/net.h,
|
||||||
|
include/grub/reader.h, include/grub/symbol.h, include/grub/types.h,
|
||||||
|
include/grub/loader.h, include/grub/msdos_partition.h,
|
||||||
|
include/grub/machine/biosdisk.h, include/grub/machine/boot.h,
|
||||||
|
include/grub/machine/console.h, include/grub/machine/vga.h,
|
||||||
|
include/grub/machine/vbe.h, include/grub/machine/init.h,
|
||||||
|
include/grub/machine/kernel.h, include/grub/cpu/time.h,
|
||||||
|
include/grub/cpu/types.h, include/grub/gzio.h and include/grub/menu.h
|
||||||
|
(KERNEL_HEADER_FILES) [i386-pc]: Add include/grub/machine/int.h.
|
||||||
|
(KERNEL_HEADER_FILES) [i386-ieee1275]: Add include/grub/i386/pit.h
|
||||||
|
* grub-core/Makefile.core.def (kernel): Explicit the source for
|
||||||
|
startup. Explicit the platforms using kern/generic/rtc_get_time_ms.c.
|
||||||
|
Split ieee1275_mips. Remove kern/i386/halt.c. Remove kern/i386/misc.S.
|
||||||
|
Enable kern/i386/pit.c on all x86. Remove kern/i386/ieee1275/init.c.
|
||||||
|
Use videoinkernel tag.
|
||||||
|
(usb): Enable on all usb.
|
||||||
|
(usbserial_common): Likewise.
|
||||||
|
(usbserial_pl2303): Likewise.
|
||||||
|
(usbserial_ftdi): Likewise.
|
||||||
|
(uhci): Enable on all x86.
|
||||||
|
(ohci): Enable on all pci.
|
||||||
|
(cmostest): Enable on all CMOS.
|
||||||
|
(acpi): Include commands/acpi.c on all platforms.
|
||||||
|
(halt): Add relevant lib/*/halt.c.
|
||||||
|
(hdparm): Enable on all pci.
|
||||||
|
(lspci): Likewise.
|
||||||
|
(usbtest): Enable on all usb.
|
||||||
|
(ata): Enable on all pci.
|
||||||
|
(ata_pthru): Likewise.
|
||||||
|
(usbms): Enable on all usb.
|
||||||
|
(usb_keyboard): Likewise.
|
||||||
|
(font): Use tag videomodules.
|
||||||
|
(bufio): Likewise.
|
||||||
|
(datetime): Use tag cmos. Enable on all noemu.
|
||||||
|
(mmap): Use tags common and x86.
|
||||||
|
(gfxterm): Use tag videomodules.
|
||||||
|
(bitmap): Likewise.
|
||||||
|
(bitmap_scale): Likewise.
|
||||||
|
(video_fb): Likewise.
|
||||||
|
(video): Likewise.
|
||||||
|
* grub-core/bus/usb/ohci.c (grub_ohci_td): Make link_td a pointer and
|
||||||
|
adjust padding accordingly. All users updated.
|
||||||
|
(grub_ohci_transaction): Fix bad format specification.
|
||||||
|
(GRUB_MOD_INIT): Add asserts for struct size.
|
||||||
|
* grub-core/bus/usb/uhci.c (grub_uhci_pci_iter): Add explicit casts.
|
||||||
|
(grub_alloc_td): Likewise.
|
||||||
|
(grub_free_queue): Likewise.
|
||||||
|
(grub_uhci_transfer): Likewise.
|
||||||
|
(grub_uhci_transaction): Fix bad format specification.
|
||||||
|
* grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Likewise.
|
||||||
|
(grub_usb_bulk_readwrite): Likewise.
|
||||||
|
* grub-core/kern/i386/misc.S (grub_stop): Moved from here ...
|
||||||
|
* grub-core/commands/i386/pc/halt.c (stop): ...here. Transformed into C.
|
||||||
|
Made static.
|
||||||
|
* grub-core/lib/i386/halt.c (stop): ... and here. Transformed into C.
|
||||||
|
Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_halt): Moved from here ...
|
||||||
|
* grub-core/commands/i386/pc/halt.c (grub_halt): ...here.
|
||||||
|
Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_biosdisk_rw_int13_extensions):
|
||||||
|
Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_rw_int13_extensions):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_biosdisk_rw_standard):
|
||||||
|
Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_rw_standard):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_biosdisk_check_int13_extensions): Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c
|
||||||
|
(grub_biosdisk_check_int13_extensions): ... here. Transformed into C.
|
||||||
|
Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_biosdisk_get_cdinfo_int13_extensions): Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c
|
||||||
|
(grub_biosdisk_get_cdinfo_int13_extensions): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_biosdisk_get_diskinfo_int13_extensions): Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c
|
||||||
|
(grub_biosdisk_get_diskinfo_int13_extensions): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_biosdisk_get_diskinfo_standard): Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c
|
||||||
|
(grub_biosdisk_get_diskinfo_standard): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_biosdisk_get_num_floppies): Moved from here ...
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c
|
||||||
|
(grub_biosdisk_get_num_floppies): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_get_diskinfo_real):
|
||||||
|
New function.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_pxe_scan): Moved from here ...
|
||||||
|
* grub-core/fs/i386/pc/pxe.c (grub_pxe_scan): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_rm_entry): Moved from here ...
|
||||||
|
* grub-core/fs/i386/pc/pxe.c (grub_rm_entry): ... here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/ieee1275/init.c: Removed.
|
||||||
|
* grub-core/kern/i386/misc.S: Likewise.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_get_memsize):
|
||||||
|
Splitted from here ...
|
||||||
|
* grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): ... here.
|
||||||
|
Transformed into C. Made static. All users updated.
|
||||||
|
* grub-core/kern/i386/pc/mmap.c (grub_get_ext_memsize): ... and here.
|
||||||
|
Transformed into C. Made static. All users updated.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_get_eisa_mmap):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/kern/i386/pc/mmap.c (grub_get_eisa_mmap): ... here.
|
||||||
|
Transformed into C. Made static. All users updated.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_get_mmap_entry):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/kern/i386/pc/mmap.c (grub_get_mmap_entry): ... here.
|
||||||
|
Transformed into C. Made static. All users updated.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_stop_floppy):
|
||||||
|
Removed (replaced by C version).
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vga_set_mode):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vga.c (grub_vga_set_mode): ...here.
|
||||||
|
Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_controller_info):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_controller_info):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_mode_info):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_mode_info):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_mode):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_mode):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_mode):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_mode):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S
|
||||||
|
(grub_vbe_bios_getset_dac_palette_width):Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c
|
||||||
|
(grub_vbe_bios_getset_dac_palette_width):... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_memory_window):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_memory_window):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_memory_window):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_memory_window):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_scanline_length):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_scanline_length):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_scanline_length):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_scanline_length):
|
||||||
|
... here. Transformed into C.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_display_start):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_display_start):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_display_start):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_display_start):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_palette_data):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_palette_data):
|
||||||
|
... here. Transformed into C. Made static.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_pxe_call): Receive
|
||||||
|
pxe_rm_entry as third argument.
|
||||||
|
(grub_bios_interrupt): New function.
|
||||||
|
* grub-core/kern/i386/qemu/mmap.c: Remove useless include.
|
||||||
|
* grub-core/kern/i386/qemu/startup.S (codestart): Do cli;hlt instead
|
||||||
|
of calling grub_stop.
|
||||||
|
* grub-core/kern/efi/efi.c (grub_halt): Moved from here ...
|
||||||
|
* grub-core/lib/efi/halt.c (grub_halt): ...here.
|
||||||
|
* grub-core/kern/emu/main.c (grub_halt): Moved from here ...
|
||||||
|
* grub-core/lib/emu/halt.c (grub_halt): ... here.
|
||||||
|
* grub-core/lib/i386/halt.c: Moved from here ...
|
||||||
|
* grub-core/lib/i386/halt.c: ... here.
|
||||||
|
* grub-core/kern/ieee1275/openfw.c (grub_halt): Moved from here ...
|
||||||
|
* grub-core/lib/ieee1275/halt.c (grub_halt): ... here.
|
||||||
|
* grub-core/loader/i386/pc/linux.c (grub_linux16_boot): Call
|
||||||
|
grub_stop_floppy.
|
||||||
|
* grub-core/loader/i386/xnu.c (guessfsb) [IEEE1275]: Enable.
|
||||||
|
* include/grub/i386/coreboot/init.h: Removed.
|
||||||
|
* include/grub/i386/multiboot/init.h: Likewise.
|
||||||
|
* include/grub/i386/pc/biosdisk.h: Removed all function prototypes.
|
||||||
|
* include/grub/i386/pc/init.h: Likewise except grub_gate_a20.
|
||||||
|
* include/grub/i386/pc/int.h: New file.
|
||||||
|
* include/grub/i386/pc/pxe.h (GRUB_PXE_SIGNATURE): New definition.
|
||||||
|
(grub_pxe_scan): Removed.
|
||||||
|
(grub_pxe_call): Update prototype.
|
||||||
|
* include/grub/i386/pc/vbe.h: Removed EXPORT_FUNC and useless
|
||||||
|
prototypes.
|
||||||
|
* include/grub/i386/pc/vga.h (grub_vga_set_mode): Removed.
|
||||||
|
* include/grub/i386/qemu/init.h: Removed.
|
||||||
|
* include/grub/mips/yeeloong/kernel.h (grub_reboot): Add missing
|
||||||
|
noreturn.
|
||||||
|
(grub_halt): Likewise.
|
||||||
|
* include/grub/misc.h (grub_halt): Removed EXPORT_FUNC.
|
||||||
|
(grub_reboot): Likewise.
|
||||||
|
* grub-core/kern/i386/coreboot/init.c (grub_stop_floppy): Moved from here...
|
||||||
|
* include/grub/i386/floppy.h (grub_stop_floppy): ...here. Inlined.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_hard_stop): Removed.
|
||||||
|
|
||||||
|
2010-08-30 Robert Millan <rmh@gnu.org>
|
||||||
|
|
||||||
|
* NEWS: Document addition of ZFS support in `grub-install' and
|
||||||
|
`grub-mkconfig'.
|
||||||
|
|
||||||
|
2010-08-30 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
|
* conf/Makefile.common (CPPFLAGS_DEFAULT): Remove leading / from
|
||||||
|
dprintf output.
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Remove leftover embedding of font objects.
|
||||||
|
|
||||||
|
* include/grub/kernel.h (OBJ_TYPE_FONT): Removed.
|
||||||
|
* util/grub-install.in (font): Removed.
|
||||||
|
* util/grub-mkimage.c (generate_image): Remove font support. All users
|
||||||
|
updated.
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* docs/grub.texi (Network): Fix reference to pxe_blksize.
|
||||||
|
Reported by: Ian Turner
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/menu.c (grub_wait_after_message): Add a 10 second
|
||||||
|
timeout to avoid indefinite boot stalling.
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/color.c (grub_env_write_color_normal): Fix a warning.
|
||||||
|
(grub_env_write_color_highlight): Likewise.
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/term.c (print_more): Return to normal and not
|
||||||
|
to standard state after printing "---MORE---".
|
||||||
|
|
||||||
|
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/term/i386/vga_common.c (grub_console_setcolorstate):
|
||||||
|
Mask out the bit 0x80 since it has other meaning that specifiing color.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
New relocator. Allows for more kernel support and more straightforward
|
||||||
|
loader writing.
|
||||||
|
|
||||||
|
* Makefile.am (BOOTTARGET): New variable.
|
||||||
|
(QEMU32): Likewise.
|
||||||
|
(linux.init.x86_64): New target.
|
||||||
|
(linux.init.i386): Likewise.
|
||||||
|
(multiboot.elf): Likewise.
|
||||||
|
(kfreebsd.elf): Likewise.
|
||||||
|
(kfreebsd.aout): Likewise.
|
||||||
|
(pc-chainloader.elf): Likewise.
|
||||||
|
(pc-chainloader.bin): Likewise.
|
||||||
|
(ntldr.elf): Likewise.
|
||||||
|
(ntldr.bin): Likewise.
|
||||||
|
(multiboot2.elf): Likewise.
|
||||||
|
(kfreebsd.init.x86_64): Likewise.
|
||||||
|
(kfreebsd.init.i386): Likewise.
|
||||||
|
(knetbsd.init.i386): Likewise.
|
||||||
|
(kopenbsd.init.i386): Likewise.
|
||||||
|
(knetbsd.init.x86_64): Likewise.
|
||||||
|
(kopenbsd.init.x86_64): Likewise.
|
||||||
|
(linux-initramfs.i386): Likewise.
|
||||||
|
(linux-initramfs.x86_64): Likewise.
|
||||||
|
(kfreebsd-mfsroot.i386.img): Likewise.
|
||||||
|
(knetbsd.image.i386): Likewise.
|
||||||
|
(kopenbsd.image.i386): Likewise.
|
||||||
|
(kopenbsd.image.x86_64): Likewise.
|
||||||
|
(knetbsd.miniroot-image.i386.img): Likewise.
|
||||||
|
(kfreebsd-mfsroot.x86_64.img): Likewise.
|
||||||
|
(knetbsd.image.x86_64): Likewise.
|
||||||
|
(knetbsd.miniroot-image.x86_64.img): Likewise.
|
||||||
|
(kfreebsd-mfsroot.i386.gz): Likewise.
|
||||||
|
(bootcheck-kfreebsd-i386): Likewise.
|
||||||
|
(kfreebsd-mfsroot.x86_64.gz): Likewise.
|
||||||
|
(bootcheck-kfreebsd-x86_64): Likewise.
|
||||||
|
(knetbsd.miniroot-image.i386.gz): Likewise.
|
||||||
|
(bootcheck-knetbsd-i386): Likewise.
|
||||||
|
(bootcheck-kopenbsd-i386): Likewise.
|
||||||
|
(bootcheck-kopenbsd-x86_64): Likewise.
|
||||||
|
(knetbsd.miniroot-image.x86_64.gz): Likewise.
|
||||||
|
(bootcheck-knetbsd-x86_64): Likewise.
|
||||||
|
(bootcheck-linux-i386): Likewise.
|
||||||
|
(bootcheck-linux-x86_64): Likewise.
|
||||||
|
(bootcheck-linux16-i386): Likewise.
|
||||||
|
(bootcheck-linux16-x86_64): Likewise.
|
||||||
|
(bootcheck-multiboot): Likewise.
|
||||||
|
(bootcheck-multiboot2): Likewise.
|
||||||
|
(bootcheck-kfreebsd-aout): Likewise.
|
||||||
|
(bootcheck-pc-chainloader): Likewise.
|
||||||
|
(bootcheck-ntldr): Likewise.
|
||||||
|
(CLEANFILES): Add new targets.
|
||||||
|
(BOOTCHECKS): New variable.
|
||||||
|
(.PHONY): Add bootchecks.
|
||||||
|
(SUCCESSFUL_BOOT_STRING): New variable.
|
||||||
|
(BOOTCHECK_TIMEOUT): Likewise.
|
||||||
|
(bootcheck): New target
|
||||||
|
* Makefile.util.def (grub-mkrescue): Enable on i386-multiboot.
|
||||||
|
* configure.ac: Correct efiemu excuse.
|
||||||
|
* docs/grub.texi (Supported kernels): New chapter.
|
||||||
|
* grub-core/Makefile.am (KERNEL_HEADER_FILES): Add
|
||||||
|
include/grub/mm_private.h. Simplify inclusion of
|
||||||
|
include/grub/boot.h, include/grub/loader.h
|
||||||
|
and include/grub/msdos_partition.h
|
||||||
|
(KERNEL_HEADER_FILES) [i386_coreboot]:
|
||||||
|
Remove include/grub/machine/loader.h. Add include/grub/i386/pit.h.
|
||||||
|
(KERNEL_HEADER_FILES) [i386_multiboot]: Likewise.
|
||||||
|
(KERNEL_HEADER_FILES) [i386_qemu]: Likewise.
|
||||||
|
(KERNEL_HEADER_FILES) [i386_ieee1275]: Remove
|
||||||
|
include/grub/machine/loader.h.
|
||||||
|
(KERNEL_HEADER_FILES) [x86_64-efi]: Likewise.
|
||||||
|
* grub-core/Makefile.core.def (kernel): Remove kern/i386/loader.S from
|
||||||
|
extra_dist.
|
||||||
|
(pci.mod): Enable on i386-multiboot.
|
||||||
|
(acpi.mod): Enable on i386-multiboot and i386-coreboot.
|
||||||
|
(efiemu.mod): Enable on i386-coreboot, i386-ieee1275, i386-multiboot and
|
||||||
|
i386-qemu.
|
||||||
|
(relocator.mod): Rewritten.
|
||||||
|
(aout.mod): Enable on all x86.
|
||||||
|
(bsd.mod): Likewise.
|
||||||
|
(ntldr.mod): New module.
|
||||||
|
(linux.mod): Use loader/i386/linux.c on all x86.
|
||||||
|
(xnu.mod): Enable on all x86.
|
||||||
|
(vga_text.mod): disable on EFI and QEMU.
|
||||||
|
* grub-core/efiemu/i386/coredetect.c: Remove useless include.
|
||||||
|
* grub-core/efiemu/i386/pc/cfgtables.c: Likewise.
|
||||||
|
* grub-core/efiemu/loadcore.c: Likewise.
|
||||||
|
* grub-core/efiemu/main.c: Likewise.
|
||||||
|
(grub_efiemu_exit_boot_services): Removed.
|
||||||
|
(grub_efiemu_finish_boot_services): Likewise.
|
||||||
|
* grub-core/efiemu/mm.c (grub_efiemu_finish_boot_services): New
|
||||||
|
function.
|
||||||
|
* grub-core/efiemu/i386/nocfgtables.c: New file.
|
||||||
|
* grub-core/kern/dl.c (grub_dl_unload_all): Removed.
|
||||||
|
* grub-core/kern/efi/efi.c (grub_efi_exit_boot_services): Removed.
|
||||||
|
(grub_efi_finish_boot_services): Moved from here ...
|
||||||
|
* grub-core/kern/efi/mm.c (grub_efi_finish_boot_services): ...here.
|
||||||
|
Fille finish memory map and related data.
|
||||||
|
(finish_mmap_buf): New variable.
|
||||||
|
(grub_efi_uintn_t finish_mmap_size): Likewise.
|
||||||
|
(grub_efi_uintn_t finish_key): Likewise.
|
||||||
|
(grub_efi_uintn_t finish_desc_size): Likewise.
|
||||||
|
(grub_efi_uint32_t finish_desc_version): Likewise.
|
||||||
|
(grub_efi_is_finished): Likewise.
|
||||||
|
(grub_efi_get_memory_map): Use saved memory map if EFI is already
|
||||||
|
finished.
|
||||||
|
* grub-core/kern/elf.c (grub_elf32_phdr_iterate): Make global.
|
||||||
|
(grub_elf64_phdr_iterate): Likewise.
|
||||||
|
* grub-core/kern/i386/coreboot/init.c (grub_os_area_addr): Removed.
|
||||||
|
(grub_os_area_size): Likewise.
|
||||||
|
(grub_machine_init): Don't reserve os area.
|
||||||
|
* grub-core/kern/i386/coreboot/startup.S: Don't include loader.S.
|
||||||
|
* grub-core/kern/i386/ieee1275/startup.S: Likewise.
|
||||||
|
* grub-core/kern/i386/loader.S: Removed.
|
||||||
|
* grub-core/kern/i386/pc/init.c (grub_os_area_addr): Removed.
|
||||||
|
(grub_os_area_size): Likewise.
|
||||||
|
(grub_machine_init): Don't reserve os area.
|
||||||
|
* grub-core/kern/i386/pc/startup.S (grub_chainloader_real_boot):
|
||||||
|
Don't call grub_dl_unload_all.
|
||||||
|
Don't include loader.S.
|
||||||
|
* grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate):
|
||||||
|
Declare the memory after _end as available.
|
||||||
|
* grub-core/kern/mm.c (GRUB_MM_FREE_MAGIC): Moved from here...
|
||||||
|
* include/grub/mm_private.h (GRUB_MM_FREE_MAGIC): ... here.
|
||||||
|
(GRUB_MM_ALLOC_MAGIC): Moved from here...
|
||||||
|
* include/grub/mm_private.h (GRUB_MM_ALLOC_MAGIC): ... here.
|
||||||
|
* grub-core/kern/mm.c (grub_mm_header): Moved from here...
|
||||||
|
* include/grub/mm_private.h (grub_mm_header): ... here.
|
||||||
|
* grub-core/kern/mm.c (GRUB_MM_ALIGN): Moved from here...
|
||||||
|
* include/grub/mm_private.h (GRUB_MM_ALIGN): ... here.
|
||||||
|
* grub-core/kern/mm.c (grub_mm_region): Moved from here ...
|
||||||
|
(grub_mm_region): ..here. Removed addr. Added pre_size.
|
||||||
|
All users updated.
|
||||||
|
* grub-core/kern/mm.c (base): Renamed to ...
|
||||||
|
(grub_mm_base): ... this. Made global.
|
||||||
|
(grub_real_malloc): Alloc from end of region.
|
||||||
|
(grub_memalign): Don't attempt to malloc if grub_mm_base is NULL.
|
||||||
|
* grub-core/kern/powerpc/cache.S (grub_arch_sync_caches): Move to ...
|
||||||
|
* grub-core/kern/powerpc/cache_flush.S: ... here.
|
||||||
|
* grub-core/lib/efi/relocator.c: New file.
|
||||||
|
* grub-core/lib/i386/relocator.c: Rewritten.
|
||||||
|
* grub-core/lib/i386/relocator16.S: New file.
|
||||||
|
* grub-core/lib/i386/relocator32.S: Likewise.
|
||||||
|
* grub-core/lib/i386/relocator64.S: Likewise.
|
||||||
|
* grub-core/lib/i386/relocator_asm.S: Rewritten.
|
||||||
|
* grub-core/lib/i386/relocator_common.S: New file.
|
||||||
|
* grub-core/lib/ieee1275/relocator.c: Likewise.
|
||||||
|
* grub-core/lib/mips/relocator.c: Rewritten.
|
||||||
|
* grub-core/lib/mips/relocator_asm.S: Renamed variables and minor
|
||||||
|
stylistic adjustments.
|
||||||
|
* grub-core/lib/powerpc/relocator.c: New file.
|
||||||
|
* grub-core/lib/powerpc/relocator_asm.S: Likewise.
|
||||||
|
* grub-core/lib/relocator.c: Rewritten.
|
||||||
|
* grub-core/lib/x86_64/relocator_asm.S: New file.
|
||||||
|
* grub-core/loader/aout.c (grub_aout_load): Make load_addr a void *.
|
||||||
|
* grub-core/loader/i386/bsd.c (NETBSD_DEFAULT_VIDEO_MODE): New const.
|
||||||
|
(bsd_tag): New struct.
|
||||||
|
(tags): New variable.
|
||||||
|
(tags_last): Likewise.
|
||||||
|
(netbsd_module): New struct.
|
||||||
|
(netbsd_mods): New variable.
|
||||||
|
(netbsd_mods_last): Likewise.
|
||||||
|
(openbsd_opts): New parameter "serial".
|
||||||
|
(OPENBSD_SERIAL_ARG): New definition.
|
||||||
|
(netbsd_opts): New parameter "serial".
|
||||||
|
(NETBSD_SERIAL_ARG): New definition.
|
||||||
|
(grub_freebsd_add_meta): Reorganised into ...
|
||||||
|
(grub_bsd_add_meta): ...this. All users updated.
|
||||||
|
(grub_freebsd_add_mmap): Reorganised into ...
|
||||||
|
(generate_e820_mmap): ...this...
|
||||||
|
(grub_bsd_add_mmap): ...and this. All users updated.
|
||||||
|
(grub_freebsd_list_modules): Use tags.
|
||||||
|
(grub_netbsd_add_meta_module): New function.
|
||||||
|
(grub_netbsd_list_modules): Likewise.
|
||||||
|
(grub_freebsd_boot): Use relocator and finish EFI.
|
||||||
|
(grub_openbsd_boot): Likewise.
|
||||||
|
(grub_netbsd_setup_video): New function.
|
||||||
|
(grub_netbsd_add_modules): Likewise.
|
||||||
|
(grub_netbsd_boot): Use grub_netbsd_add_modules, relocator, netbsd_tags
|
||||||
|
and finish EFI.
|
||||||
|
(grub_bsd_unload): Unload tags.
|
||||||
|
(grub_bsd_load_aout): Use relocator.
|
||||||
|
(grub_bsd_elf32_size_hook): New function.
|
||||||
|
(grub_bsd_elf32_hook): Use relocator.
|
||||||
|
(grub_bsd_elf64_size_hook): New function.
|
||||||
|
(grub_bsd_elf64_hook): Use relocator.
|
||||||
|
(grub_bsd_load_elf): Use relocator and call grub_openbsd_find_ramdisk.
|
||||||
|
(grub_bsd_load): Zero-out openbsd_ramdisk.
|
||||||
|
(grub_bsd_load): Use relocator.
|
||||||
|
(grub_cmd_openbsd): Support serial.
|
||||||
|
(grub_cmd_netbsd): Support modules.
|
||||||
|
(grub_cmd_freebsd_module): Use relocator.
|
||||||
|
(grub_netbsd_module_load): New function.
|
||||||
|
(grub_cmd_netbsd_module): Likewise.
|
||||||
|
(grub_cmd_openbsd_ramdisk): Likewise.
|
||||||
|
(GRUB_MOD_INIT): Register knetbsd_module, knetbsd_module_elf and
|
||||||
|
kopenbsd_ramdisk.
|
||||||
|
(GRUB_MOD_FINI): Unregister new commands.
|
||||||
|
* grub-core/loader/i386/bsdXX.c (load): Remove useless checks.
|
||||||
|
(grub_freebsd_load_elfmodule_obj): Use relocator.
|
||||||
|
(grub_freebsd_load_elfmodule): Likewise.
|
||||||
|
(grub_freebsd_load_elf_meta): Likewise.
|
||||||
|
(grub_netbsd_load_elf_meta): New function.
|
||||||
|
(grub_openbsd_find_ramdisk): Likewise.
|
||||||
|
* grub-core/loader/i386/bsd_helper.S: Removed.
|
||||||
|
* grub-core/loader/i386/bsd_pagetable.c: Support relocator.
|
||||||
|
* grub-core/loader/i386/bsd_trampoline.S: Removed.
|
||||||
|
* grub-core/loader/i386/efi/linux.c: Likewise.
|
||||||
|
* grub-core/loader/i386/ieee1275/linux.c: Likewise.
|
||||||
|
* grub-core/loader/i386/linux.c (HAS_VGA_TEXT): New const.
|
||||||
|
(DEFAULT_VIDEO_MODE): Likewise.
|
||||||
|
(real_mode_target): New variable.
|
||||||
|
(prot_mode_target): Likewise.
|
||||||
|
(initrd_mem_target): Likewise.
|
||||||
|
(relocator): Likewise.
|
||||||
|
(efi_mmap_buf): Likewise.
|
||||||
|
(efi_mmap_size): Likewise.
|
||||||
|
(find_efi_mmap_size): Moved from grub-core/loader/i386/efi/linux.c.
|
||||||
|
(free_pages): Use relocator.
|
||||||
|
(allocate_pages): Account for efi_mmap and use relocator. Return error.
|
||||||
|
(grub_linux_setup_video): Return error.
|
||||||
|
(grub_linux_trampoline_start): Removed.
|
||||||
|
(grub_linux_trampoline_end): Likewise.
|
||||||
|
(grub_linux_boot): Use relocator and DEFAULT_VIDEO_MODE. Pass console
|
||||||
|
andd video parameters depending on firmware.
|
||||||
|
[GRUB_MACHINE_IEEE1275]: Pass OFW parameters.
|
||||||
|
[GRUB_MACHINE_EFI]: Pass EFI parameters.
|
||||||
|
(grub_cmd_linux) [GRUB_MACHINE_EFI]: Likewise.
|
||||||
|
(grub_cmd_initrd): Use relocator.
|
||||||
|
* grub-core/loader/i386/linux_trampoline.S: Removed.
|
||||||
|
* grub-core/loader/i386/multiboot_mbi.c (elf_sec_num): New variable.
|
||||||
|
(elf_sec_entsize): Likewise.
|
||||||
|
(elf_sec_shstrndx): Likewise.
|
||||||
|
(elf_sections): Likewise.
|
||||||
|
(grub_multiboot_load): Use relocator.
|
||||||
|
(grub_multiboot_get_mbi_size): Account for sections.
|
||||||
|
(grub_multiboot_make_mbi): Use relocator and support sections.
|
||||||
|
(grub_multiboot_add_elfsyms): New function.
|
||||||
|
(grub_multiboot_free_mbi): Free sections.
|
||||||
|
* grub-core/loader/i386/pc/linux.c (relocator): New variable.
|
||||||
|
(grub_linux_real_target): Likewise.
|
||||||
|
(grub_linux_real_chunk): Likewise.
|
||||||
|
(grub_linux16_prot_size): Likewise.
|
||||||
|
(grub_linux16_boot): Use relocator.
|
||||||
|
(grub_linux_unload): Unload relocator.
|
||||||
|
(grub_cmd_linux): Use relocator.
|
||||||
|
(grub_cmd_initrd): Likewise.
|
||||||
|
* grub-core/loader/i386/pc/ntldr.c: New file.
|
||||||
|
* grub-core/loader/i386/xnu.c (guessfsb) [GRUB_MACHINE_IEEE1275]:
|
||||||
|
Don't try to guess CPU frequency.
|
||||||
|
(grub_xnu_set_video): Stretch bitmap.
|
||||||
|
(grub_xnu_boot): Use relocator.
|
||||||
|
* grub-core/loader/mips/linux.c (grub_linux_boot): Use relocator.
|
||||||
|
(grub_linux_unload): Free relocator.
|
||||||
|
(grub_linux_load32): Use relocator.
|
||||||
|
(grub_linux_load64): Likewise.
|
||||||
|
(grub_cmd_initrd): Likewise.
|
||||||
|
* grub-core/loader/multiboot.c (grub_multiboot_boot): Use relocator.
|
||||||
|
(grub_multiboot_unload): Unload relocator.
|
||||||
|
(grub_cmd_multiboot): Use relocator.
|
||||||
|
(grub_cmd_module): Likewise.
|
||||||
|
* grub-core/loader/multiboot_elfxx.c (grub_multiboot_load_elfXX):
|
||||||
|
Use relocator and support sections.
|
||||||
|
* grub-core/loader/multiboot_mbi2.c(elf_sec_num): New variable.
|
||||||
|
(elf_sec_entsize): Likewise.
|
||||||
|
(elf_sec_shstrndx): Likewise.
|
||||||
|
(elf_sections): Likewise.
|
||||||
|
(grub_multiboot_load): Use relocator.
|
||||||
|
(grub_multiboot_get_mbi_size): Account for sections.
|
||||||
|
(grub_multiboot_make_mbi): Use relocator and support sections.
|
||||||
|
(grub_multiboot_add_elfsyms): New function.
|
||||||
|
* grub-core/loader/powerpc/ieee1275/linux.c: Remove useless include.
|
||||||
|
* grub-core/loader/sparc64/ieee1275/linux.c: Likewise.
|
||||||
|
* grub-core/loader/xnu.c (grub_xnu_heap_malloc): Use relocator.
|
||||||
|
Prototype changed. All users updated.
|
||||||
|
(grub_xnu_align_heap): Simplified.
|
||||||
|
(grub_xnu_writetree_toheap): Likewise.
|
||||||
|
(grub_xnu_unload): Unload relocator.
|
||||||
|
(grub_cmd_xnu_kernel): Use relocator.
|
||||||
|
(grub_cmd_xnu_kernel64): Likewise.
|
||||||
|
(grub_xnu_register_memory): Simplified.
|
||||||
|
* grub-core/loader/xnu_resume.c (grub_xnu_resume): Use relocator.
|
||||||
|
* grub-core/term/efi/console.c (grub_console_putchar): Abort if
|
||||||
|
EFI is finished.
|
||||||
|
(grub_console_checkkey): Likewise.
|
||||||
|
(grub_console_getkey): Likewise.
|
||||||
|
(grub_console_getwh): Likewise.
|
||||||
|
(grub_console_getxy): Likewise.
|
||||||
|
(grub_console_gotoxy): Likewise.
|
||||||
|
(grub_console_cls): Likewise.
|
||||||
|
(grub_console_setcolorstate): Likewise.
|
||||||
|
(grub_console_setcursor): Likewise.
|
||||||
|
* grub-core/term/ns8250.c (grub_ns8250_hw_get_port): New function.
|
||||||
|
* grub-core/tests/boot/kbsd.init-i386.S: New file.
|
||||||
|
* grub-core/tests/boot/kbsd.init-x86_64.S: Likewise.
|
||||||
|
* grub-core/tests/boot/kbsd.spec.txt: Likewise.
|
||||||
|
* grub-core/tests/boot/kernel-8086.S: Likewise.
|
||||||
|
* grub-core/tests/boot/kernel-i386.S: Likewise.
|
||||||
|
* grub-core/tests/boot/kfreebsd-aout.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/kfreebsd.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/kfreebsd.init-i386.S: Likewise.
|
||||||
|
* grub-core/tests/boot/kfreebsd.init-x86_64.S: Likewise.
|
||||||
|
* grub-core/tests/boot/knetbsd.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/kopenbsd.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/kopenbsdlabel.txt: Likewise.
|
||||||
|
* grub-core/tests/boot/linux.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/linux.init-i386.S: Likewise.
|
||||||
|
* grub-core/tests/boot/linux.init-x86_64.S: Likewise.
|
||||||
|
* grub-core/tests/boot/linux16.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/multiboot.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/multiboot2.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/ntldr.cfg: Likewise.
|
||||||
|
* grub-core/tests/boot/pc-chainloader.cfg: Likewise.
|
||||||
|
* include/grub/aout.h (grub_aout_load): Make load_addr a void *.
|
||||||
|
* include/grub/autoefi.h (grub_autoefi_finish_boot_services):
|
||||||
|
New definition.
|
||||||
|
* include/grub/dl.h (grub_dl_unload_all): Removed.
|
||||||
|
* include/grub/efi/efi.h (grub_efi_exit_boot_services): Likewise.
|
||||||
|
(grub_efi_finish_boot_services): Change prototype.
|
||||||
|
(grub_efi_is_finished): New variable.
|
||||||
|
* include/grub/efiemu/efiemu.h (grub_efiemu_finish_boot_services):
|
||||||
|
Changed prototype.
|
||||||
|
(grub_efiemu_finish_boot_services): Removed.
|
||||||
|
(grub_machine_efiemu_init_tables): New prototype.
|
||||||
|
* include/grub/elfload.h (grub_elf32_phdr_iterate): Likewise.
|
||||||
|
(grub_elf64_phdr_iterate): Likewise.
|
||||||
|
* include/grub/i386/bsd.h: Include relocator.h.
|
||||||
|
(freebsd_tag_header): New struct.
|
||||||
|
(grub_openbsd_bios_mmap): Removed.
|
||||||
|
(grub_unix_real_boot): Removed.
|
||||||
|
(grub_freebsd_load_elfmodule32): Changed prototype.
|
||||||
|
(grub_freebsd_load_elfmodule_obj64): Likewise.
|
||||||
|
(grub_freebsd_load_elf_meta32): Likewise.
|
||||||
|
(grub_freebsd_load_elf_meta64): Likewise.
|
||||||
|
(grub_freebsd_add_meta): Removed.
|
||||||
|
(grub_netbsd_load_elf_meta32): New prototype.
|
||||||
|
(grub_netbsd_load_elf_meta64): Likewise.
|
||||||
|
(grub_bsd_add_meta): Likewise.
|
||||||
|
(grub_openbsd_ramdisk_descriptor): New struct.
|
||||||
|
(grub_openbsd_find_ramdisk32): New prototype.
|
||||||
|
(grub_openbsd_find_ramdisk64): Likewise.
|
||||||
|
* include/grub/i386/coreboot/loader.h: Removed.
|
||||||
|
* include/grub/i386/efi/loader.h: Likewise.
|
||||||
|
* include/grub/i386/ieee1275/loader.h: Likewise.
|
||||||
|
* include/grub/i386/linux.h (linux_kernel_header): Change void *
|
||||||
|
to grub_uint32_t.
|
||||||
|
* include/grub/i386/loader.h: Removed.
|
||||||
|
* include/grub/i386/memory.h (GRUB_MEMORY_CPU_CR4_PAE_ON): Correct the
|
||||||
|
value.
|
||||||
|
(GRUB_MEMORY_CPU_CR4_PSE_ON): New definition.
|
||||||
|
(grub_phys_addr_t): New type.
|
||||||
|
(grub_vtop): New inline function.
|
||||||
|
(grub_map_memory): Likewise.
|
||||||
|
(grub_unmap_memory): Likewise.
|
||||||
|
* include/grub/i386/multiboot/loader.h: Removed.
|
||||||
|
* include/grub/i386/netbsd_bootinfo.h (NETBSD_BTINFO_BOOTDISK): Removed.
|
||||||
|
(NETBSD_BTINFO_CONSOLE): New definition.
|
||||||
|
(NETBSD_BTINFO_SYMTAB): Likewise.
|
||||||
|
(NETBSD_BTINFO_MODULES): Likewise.
|
||||||
|
(NETBSD_BTINFO_FRAMEBUF): Likewise.
|
||||||
|
(grub_netbsd_bootinfo): New struct.
|
||||||
|
(grub_netbsd_btinfo_common): Use explicit bitsize.
|
||||||
|
(grub_netbsd_btinfo_mmap_entry): Removed.
|
||||||
|
(GRUB_NETBSD_MAX_BOOTPATH_LEN): New definition.
|
||||||
|
(grub_netbsd_btinfo_bootdisk): New struct.
|
||||||
|
(grub_netbsd_btinfo_symtab): Likewise.
|
||||||
|
(grub_netbsd_btinfo_serial): Likewise.
|
||||||
|
(grub_netbsd_btinfo_modules): Likewise.
|
||||||
|
(grub_netbsd_btinfo_framebuf): Likewise.
|
||||||
|
(GRUB_NETBSD_MAX_ROOTDEVICE_LEN): New definition.
|
||||||
|
* include/grub/i386/openbsd_bootarg.h (OPENBSD_BOOTARG_CONSOLE):
|
||||||
|
Likewise.
|
||||||
|
(grub_openbsd_bootargs): Use explicit bitsize.
|
||||||
|
(grub_openbsd_bootarg_console): New struct.
|
||||||
|
(GRUB_OPENBSD_COM_MAJOR): New definition.
|
||||||
|
(GRUB_OPENBSD_VGA_MAJOR): Likewise.
|
||||||
|
* include/grub/i386/pc/efiemu.h: Removed.
|
||||||
|
* include/grub/i386/pc/loader.h: Don't include cpu/loader.h.
|
||||||
|
* include/grub/i386/qemu/loader.h: Removed.
|
||||||
|
* include/grub/i386/relocator.h: Rewritten.
|
||||||
|
* include/grub/i386/xnu.h (grub_xnu_heap_will_be_at): Removed.
|
||||||
|
* include/grub/mips/memory.h: New file.
|
||||||
|
* include/grub/mips/multiboot.h: Rewritten.
|
||||||
|
* include/grub/mips/relocator.h: Rewritten.
|
||||||
|
* include/grub/mips/yeeloong/memory.h (grub_phys_addr_t): New type.
|
||||||
|
(grub_vtop): New function.
|
||||||
|
(grub_map_memory): Likewise.
|
||||||
|
(grub_unmap_memory): Likewise.
|
||||||
|
* include/grub/misc.h (ALIGN_DOWN): New definition.
|
||||||
|
* include/grub/mm.h (grub_mm_check_real): New proto.
|
||||||
|
(GRUB_MM_CHECK): New definition.
|
||||||
|
* include/grub/mm_private.h: New file.
|
||||||
|
* include/grub/multiboot.h (grub_multiboot_relocator): New variable.
|
||||||
|
(grub_multiboot_get_mbi_size): Removed.
|
||||||
|
(grub_multiboot_make_mbi): Change prottype.
|
||||||
|
(grub_multiboot_set_accepts_video): New proto.
|
||||||
|
(grub_multiboot_add_elfsyms): Likewise.
|
||||||
|
(grub_multiboot_payload_eip): New variable.
|
||||||
|
* include/grub/ns8250.h (grub_ns8250_hw_get_port) [!ASM_FILE]:
|
||||||
|
New prototype.
|
||||||
|
* include/grub/offsets.h (GRUB_KERNEL_I386_MULTIBOOT_PREFIX):
|
||||||
|
New definition.
|
||||||
|
(GRUB_KERNEL_I386_MULTIBOOT_DATA_END): Likewise.
|
||||||
|
(GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN): Likewise.
|
||||||
|
* include/grub/powerpc/ieee1275/loader.h: Removed.
|
||||||
|
* include/grub/powerpc/memory.h: New file.
|
||||||
|
* include/grub/powerpc/relocator.h: Likewise.
|
||||||
|
* include/grub/relocator.h: Likewise.
|
||||||
|
* include/grub/relocator_private.h: Likewise.
|
||||||
|
* include/grub/sparc64/ieee1275/loader.h: Removed.
|
||||||
|
* include/grub/x86_64/memory.h: New file.
|
||||||
|
* include/grub/xnu.h (grub_xnu_writetree_toheap): Changed prototype.
|
||||||
|
(grub_xnu_heap_malloc): Likewise.
|
||||||
|
(grub_xnu_heap_real_start): Removed.
|
||||||
|
(grub_xnu_heap_start): Likewise.
|
||||||
|
(grub_xnu_relocator): New variable.
|
||||||
|
(grub_xnu_heap_target_start): Likewise.
|
||||||
|
* tests/util/grub-shell.in: Support non-pc.
|
||||||
|
* util/grub-mkimage.c (image_targets): Fix multiboot target.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/charset.c (grub_utf8_to_ucs4_alloc): Avoid deadloop
|
||||||
|
on malloc error.
|
||||||
|
(grub_bidi_logical_to_visual): Check that malloc succeded.
|
||||||
|
* grub-core/normal/term.c (grub_puts_terminal): Fix fallback to dumb
|
||||||
|
puts.
|
||||||
|
(grub_xputs_normal): Likewise.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/Makefile.core.def (kernel): Add kern/mips/cache_flush.S to
|
||||||
|
extra_dist.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/efiemu/runtime/efiemu.sh: Removed.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* Makefile.util.def (grub-ofpathname): Add missing ldadd.
|
||||||
|
|
||||||
|
2010-08-29 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/misc.c (grub_real_dprintf): Always refresh after
|
||||||
|
dprintf.
|
||||||
|
|
||||||
|
2010-08-29 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
|
* Makefile.util.def: Use ldadd instead of ldflags for libraries.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/term.c (print_more): Fix a memory leak.
|
||||||
|
(grub_puts_terminal): Revert to dumb puts if memory allocation fails.
|
||||||
|
(grub_xputs_normal): Likewise.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/script/lexer.c (grub_script_lexer_init): Don't look before
|
||||||
|
the begining of the string
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/script/script.c (grub_script_parse): Free parsed on
|
||||||
|
failure.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/completion.c (grub_normal_do_completion): Free argv
|
||||||
|
on failure.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/normal/cmdline.c (grub_cmdline_get): Free cl_terms on
|
||||||
|
return.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/term/gfxterm.c (grub_gfxterm_term_fini): Free the text buffer.
|
||||||
|
(scroll_up): Fix a memory leak.
|
||||||
|
|
||||||
|
2010-08-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/fs/nilfs2.c (grub_nilfs2_load_sb): Handle grub_disk_read
|
||||||
|
errors.
|
||||||
|
|
||||||
|
2010-08-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Handle USB pendrives exposed as floppies.
|
||||||
|
|
||||||
|
* grub-core/boot/i386/pc/boot.S: Check LBA even on what appears to be
|
||||||
|
floppy.
|
||||||
|
* grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Likewise.
|
||||||
|
Check for partitions on all devices.
|
||||||
|
|
||||||
|
2010-08-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/term/ieee1275/ofconsole.c (put): Correct prototype.
|
||||||
|
(readkey): Likewise.
|
||||||
|
|
||||||
2010-08-25 BVK Chaitanya <bvk.groups@gmail.com>
|
2010-08-25 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
Multiple variable names support to "export" command.
|
Multiple variable names support to "export" command.
|
||||||
|
|
2
INSTALL
2
INSTALL
|
@ -21,7 +21,7 @@ configuring the GRUB.
|
||||||
|
|
||||||
On GNU/Linux, you also need:
|
On GNU/Linux, you also need:
|
||||||
|
|
||||||
* libdevmapper (recommended)
|
* libdevmapper 1.02.34 or later (recommended)
|
||||||
|
|
||||||
To build grub-emu, you need:
|
To build grub-emu, you need:
|
||||||
|
|
||||||
|
|
219
Makefile.am
219
Makefile.am
|
@ -83,3 +83,222 @@ platform_HEADERS = config.h
|
||||||
|
|
||||||
pkglib_DATA += grub-mkconfig_lib
|
pkglib_DATA += grub-mkconfig_lib
|
||||||
pkglib_DATA += update-grub_lib
|
pkglib_DATA += update-grub_lib
|
||||||
|
|
||||||
|
|
||||||
|
if COND_i386_coreboot
|
||||||
|
BOOTTARGET=coreboot
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_i386_multiboot
|
||||||
|
BOOTTARGET=cd
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_i386_ieee1275
|
||||||
|
BOOTTARGET=cd
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_i386_qemu
|
||||||
|
BOOTTARGET=qemu
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_i386_pc
|
||||||
|
BOOTTARGET=cd
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_i386_efi
|
||||||
|
QEMU32=qemu-system-i386
|
||||||
|
BOOTTARGET=cd
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_x86_64_efi
|
||||||
|
QEMU32=qemu-system-x86_64
|
||||||
|
BOOTTARGET=cd
|
||||||
|
endif
|
||||||
|
|
||||||
|
linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||||
|
|
||||||
|
kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||||
|
|
||||||
|
kfreebsd.aout: kfreebsd.elf
|
||||||
|
$(OBJCOPY) -O a.out-i386-linux $< $@ -R .note.gnu.build-id
|
||||||
|
|
||||||
|
pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S
|
||||||
|
$(TARGET_CC) -o $@ $< -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x7c00 -m32
|
||||||
|
|
||||||
|
pc-chainloader.bin: pc-chainloader.elf
|
||||||
|
$(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@;
|
||||||
|
|
||||||
|
ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S
|
||||||
|
$(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0 -m32
|
||||||
|
|
||||||
|
ntldr.bin: ntldr.elf
|
||||||
|
$(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@;
|
||||||
|
|
||||||
|
multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1
|
||||||
|
|
||||||
|
kfreebsd.init.x86_64: $(srcdir)/grub-core/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)/grub-core/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)/grub-core/tests/boot/kbsd.init-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S
|
||||||
|
$(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||||
|
|
||||||
|
linux-initramfs.i386: linux.init.i386 Makefile
|
||||||
|
TDIR=`mktemp -d`; cp $< $$TDIR/init; (cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR
|
||||||
|
|
||||||
|
linux-initramfs.x86_64: linux.init.x86_64 Makefile
|
||||||
|
TDIR=`mktemp -d`; cp $< $$TDIR/init; (cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR
|
||||||
|
|
||||||
|
kfreebsd-mfsroot.i386.img: kfreebsd.init.i386 Makefile
|
||||||
|
TDIR=`mktemp -d`; mkdir $$TDIR/dev; mkdir $$TDIR/sbin; cp $< $$TDIR/sbin/init; makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR; rm -rf $$TDIR
|
||||||
|
|
||||||
|
knetbsd.image.i386: knetbsd.init.i386 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt
|
||||||
|
TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||||
|
|
||||||
|
kopenbsd.image.i386: kopenbsd.init.i386 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt
|
||||||
|
TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||||
|
|
||||||
|
kopenbsd.image.x86_64: kopenbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt
|
||||||
|
TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||||
|
|
||||||
|
knetbsd.miniroot-image.i386.img: knetbsd.image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386
|
||||||
|
$(OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@
|
||||||
|
|
||||||
|
kfreebsd-mfsroot.x86_64.img: kfreebsd.init.x86_64 Makefile
|
||||||
|
TDIR=`mktemp -d`; mkdir $$TDIR/dev; mkdir $$TDIR/sbin; cp $< $$TDIR/sbin/init; makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR; rm -rf $$TDIR
|
||||||
|
|
||||||
|
knetbsd.image.x86_64: knetbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt
|
||||||
|
TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||||
|
|
||||||
|
knetbsd.miniroot-image.x86_64.img: 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
|
||||||
|
|
||||||
|
kfreebsd-mfsroot.i386.gz: kfreebsd-mfsroot.i386.img
|
||||||
|
gzip < $< > $@
|
||||||
|
|
||||||
|
bootcheck-kfreebsd-i386: kfreebsd-mfsroot.i386.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.i386 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/mfsroot.gz=kfreebsd-mfsroot.i386.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.i386 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
kfreebsd-mfsroot.x86_64.gz: kfreebsd-mfsroot.x86_64.img
|
||||||
|
gzip < $< > $@
|
||||||
|
|
||||||
|
bootcheck-kfreebsd-x86_64: kfreebsd-mfsroot.x86_64.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/mfsroot.gz=kfreebsd-mfsroot.x86_64.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
knetbsd.miniroot-image.i386.gz: knetbsd.miniroot-image.i386.img
|
||||||
|
gzip < $< > $@
|
||||||
|
|
||||||
|
bootcheck-knetbsd-i386: knetbsd.miniroot-image.i386.gz $(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/miniroot.gz=knetbsd.miniroot-image.i386.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-kopenbsd-i386: kopenbsd.image.i386 $(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/ramdisk=kopenbsd.image.i386 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-kopenbsd-x86_64: kopenbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/ramdisk=kopenbsd.image.x86_64 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
knetbsd.miniroot-image.x86_64.gz: knetbsd.miniroot-image.x86_64.img
|
||||||
|
gzip < $< > $@
|
||||||
|
|
||||||
|
bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64.gz $(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/miniroot.gz=knetbsd.miniroot-image.x86_64.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/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)/grub-core/tests/boot/linux.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-linux16-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-linux16-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-multiboot: multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/multiboot.elf=multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-multiboot2: multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/multiboot2.elf=multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-kfreebsd-aout: kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/kfreebsd.aout=kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-pc-chainloader: pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/pc-chainloader.bin=pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
bootcheck-ntldr: ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg grub-shell
|
||||||
|
timeout -s KILL $(BOOTCHECK_TIMEOUT) ./grub-shell --qemu-opts="$(GRUB_QEMU_OPTS)" --boot=$(BOOTTARGET) --qemu=$(QEMU32) --files=/ntldr.bin=ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||||
|
|
||||||
|
BOOTCHECKS=
|
||||||
|
|
||||||
|
if COND_i386_pc
|
||||||
|
#pc chainloader by definition is only for i386-pc
|
||||||
|
BOOTCHECKS += bootcheck-pc-chainloader
|
||||||
|
#ntldr and bootmgr require BIOS.
|
||||||
|
BOOTCHECKS += bootcheck-ntldr
|
||||||
|
#legacy protocol makes early BIOS calls.
|
||||||
|
BOOTCHECKS += bootcheck-linux16-i386 bootcheck-linux16-x86_64
|
||||||
|
# Crashes early on non-BIOS
|
||||||
|
BOOTCHECKS += bootcheck-knetbsd-i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !COND_i386_coreboot
|
||||||
|
# Crashes because memory at 0-0x1000 is occupied
|
||||||
|
BOOTCHECKS += bootcheck-knetbsd-x86_64
|
||||||
|
|
||||||
|
# Likewise and require ACPI.
|
||||||
|
if !COND_i386_multiboot
|
||||||
|
if !COND_i386_qemu
|
||||||
|
BOOTCHECKS += bootcheck-kfreebsd-x86_64
|
||||||
|
BOOTCHECKS += bootcheck-kfreebsd-i386
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
BOOTCHECKS += bootcheck-kfreebsd-aout
|
||||||
|
|
||||||
|
BOOTCHECKS += bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64
|
||||||
|
|
||||||
|
BOOTCHECKS += bootcheck-multiboot bootcheck-multiboot2
|
||||||
|
|
||||||
|
BOOTCHECKS += bootcheck-linux-i386 bootcheck-linux-x86_64
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: bootcheck-linux-i386 bootcheck-linux-x86_64 \
|
||||||
|
bootcheck-kfreebsd-i386 bootcheck-kfreebsd-x86_64 \
|
||||||
|
bootcheck-knetbsd-i386 bootcheck-knetbsd-x86_64
|
||||||
|
|
||||||
|
# Randomly generated
|
||||||
|
SUCCESSFUL_BOOT_STRING=3e49994fd5d82b7c9298d672d774080d
|
||||||
|
# tianocore cd access is very slow
|
||||||
|
BOOTCHECK_TIMEOUT=180
|
||||||
|
|
||||||
|
bootcheck: $(BOOTCHECKS)
|
||||||
|
|
|
@ -88,6 +88,7 @@ library = {
|
||||||
common = grub-core/partmap/gpt.c;
|
common = grub-core/partmap/gpt.c;
|
||||||
common = grub-core/partmap/msdos.c;
|
common = grub-core/partmap/msdos.c;
|
||||||
common = grub-core/partmap/sun.c;
|
common = grub-core/partmap/sun.c;
|
||||||
|
common = grub-core/partmap/sunpc.c;
|
||||||
common = grub-core/script/function.c;
|
common = grub-core/script/function.c;
|
||||||
common = grub-core/script/lexer.c;
|
common = grub-core/script/lexer.c;
|
||||||
common = grub-core/script/main.c;
|
common = grub-core/script/main.c;
|
||||||
|
@ -99,7 +100,7 @@ program = {
|
||||||
name = grub-bin2h;
|
name = grub-bin2h;
|
||||||
common = util/bin2h.c;
|
common = util/bin2h.c;
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
mansection = 1;
|
mansection = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ program = {
|
||||||
extra_dist = util/grub-mkimagexx.c;
|
extra_dist = util/grub-mkimagexx.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"';
|
cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +124,7 @@ program = {
|
||||||
common = util/grub-mkrelpath.c;
|
common = util/grub-mkrelpath.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -133,7 +134,7 @@ program = {
|
||||||
common = util/grub-script-check.c;
|
common = util/grub-script-check.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -143,7 +144,7 @@ program = {
|
||||||
common = util/grub-editenv.c;
|
common = util/grub-editenv.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -153,7 +154,7 @@ program = {
|
||||||
common = util/grub-mkpasswd-pbkdf2.c;
|
common = util/grub-mkpasswd-pbkdf2.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
cflags = '$(CFLAGS_GCRY)';
|
cflags = '$(CFLAGS_GCRY)';
|
||||||
cppflags = '$(CPPFLAGS_GCRY)';
|
cppflags = '$(CPPFLAGS_GCRY)';
|
||||||
};
|
};
|
||||||
|
@ -171,7 +172,7 @@ program = {
|
||||||
common = util/grub-pe2elf.c;
|
common = util/grub-pe2elf.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL)';
|
ldadd = '$(LIBINTL)';
|
||||||
condition = COND_GRUB_PE2ELF;
|
condition = COND_GRUB_PE2ELF;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,7 +182,7 @@ program = {
|
||||||
common = util/grub-fstest.c;
|
common = util/grub-fstest.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
condition = COND_GRUB_FSTEST;
|
condition = COND_GRUB_FSTEST;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,8 +195,8 @@ program = {
|
||||||
cflags = '$(freetype_cflags)';
|
cflags = '$(freetype_cflags)';
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
ldflags = '$(freetype_libs)';
|
ldadd = '$(freetype_libs)';
|
||||||
condition = COND_GRUB_MKFONT;
|
condition = COND_GRUB_MKFONT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ program = {
|
||||||
sparc64_ieee1275 = util/ieee1275/devicemap.c;
|
sparc64_ieee1275 = util/ieee1275/devicemap.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -222,7 +223,7 @@ program = {
|
||||||
common = util/grub-probe.c;
|
common = util/grub-probe.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -239,7 +240,7 @@ program = {
|
||||||
sparc64_ieee1275 = util/lvm.c;
|
sparc64_ieee1275 = util/lvm.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||||
|
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = sparc64_ieee1275;
|
enable = sparc64_ieee1275;
|
||||||
|
@ -252,6 +253,7 @@ program = {
|
||||||
ieee1275 = util/ieee1275/ofpath.c;
|
ieee1275 = util/ieee1275/ofpath.c;
|
||||||
|
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||||
enable = sparc64_ieee1275;
|
enable = sparc64_ieee1275;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -329,11 +331,12 @@ script = {
|
||||||
script = {
|
script = {
|
||||||
mansection = 1;
|
mansection = 1;
|
||||||
name = grub-mkrescue;
|
name = grub-mkrescue;
|
||||||
x86_noieee1275 = util/grub-mkrescue.in;
|
x86 = util/grub-mkrescue.in;
|
||||||
powerpc_ieee1275 = util/powerpc/ieee1275/grub-mkrescue.in;
|
powerpc_ieee1275 = util/powerpc/ieee1275/grub-mkrescue.in;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = x86_efi;
|
enable = x86_efi;
|
||||||
enable = i386_qemu;
|
enable = i386_qemu;
|
||||||
|
enable = i386_multiboot;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
enable = powerpc_ieee1275;
|
enable = powerpc_ieee1275;
|
||||||
};
|
};
|
||||||
|
@ -344,15 +347,17 @@ script = {
|
||||||
name = grub-install;
|
name = grub-install;
|
||||||
|
|
||||||
mips = util/grub-install.in;
|
mips = util/grub-install.in;
|
||||||
i386_noefi_noieee1275 = util/grub-install.in;
|
i386_pc = util/grub-install.in;
|
||||||
|
i386_qemu = util/grub-install.in;
|
||||||
|
i386_coreboot = util/grub-install.in;
|
||||||
|
i386_multiboot = util/grub-install.in;
|
||||||
|
sparc64_ieee1275 = util/grub-install.in;
|
||||||
|
|
||||||
x86_efi = util/i386/efi/grub-install.in;
|
x86_efi = util/i386/efi/grub-install.in;
|
||||||
i386_ieee1275 = util/ieee1275/grub-install.in;
|
i386_ieee1275 = util/ieee1275/grub-install.in;
|
||||||
powerpc_ieee1275 = util/ieee1275/grub-install.in;
|
powerpc_ieee1275 = util/ieee1275/grub-install.in;
|
||||||
|
|
||||||
enable = x86;
|
enable = noemu;
|
||||||
enable = mips;
|
|
||||||
enable = powerpc_ieee1275;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
script = {
|
||||||
|
@ -512,5 +517,5 @@ program = {
|
||||||
common = grub-core/tests/lib/test.c;
|
common = grub-core/tests/lib/test.c;
|
||||||
cflags = -Wno-format;
|
cflags = -Wno-format;
|
||||||
ldadd = libgrub.a;
|
ldadd = libgrub.a;
|
||||||
ldflags = '$(LIBDEVMAPPER)';
|
ldadd = '$(LIBDEVMAPPER)';
|
||||||
};
|
};
|
||||||
|
|
95
NEWS
95
NEWS
|
@ -1,3 +1,98 @@
|
||||||
|
New in 1.99:
|
||||||
|
|
||||||
|
* New relocator. Allows for more kernel support and more
|
||||||
|
straightforward loader writing.
|
||||||
|
|
||||||
|
* Handle USB pendrives exposed as floppies.
|
||||||
|
|
||||||
|
* New Automake-based build system.
|
||||||
|
|
||||||
|
* Add `sendkey' command (i386-pc only).
|
||||||
|
|
||||||
|
* ZFS support in `grub-install' and `grub-mkconfig'. Note: complete
|
||||||
|
functionality requires external ZFS implementation (available from
|
||||||
|
grub-extras).
|
||||||
|
|
||||||
|
* Support 1.x versions of mdadm metadata.
|
||||||
|
|
||||||
|
* Fix corruption when reading Reiserfs directory entries.
|
||||||
|
|
||||||
|
* Bidirectional text and diacritics support.
|
||||||
|
|
||||||
|
* Skip LVM snapshots.
|
||||||
|
|
||||||
|
* MIPS Yeeloong firmware port.
|
||||||
|
|
||||||
|
* Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible
|
||||||
|
on GNU/Linux.
|
||||||
|
|
||||||
|
* Add `grub-mkconfig' support for Xen with Linux.
|
||||||
|
|
||||||
|
* Add `grub-mkconfig' support for initrd images on Fedora 13.
|
||||||
|
|
||||||
|
* Support >3GiB and <16MiB RAM in i386-qemu.
|
||||||
|
|
||||||
|
* Add support for Cirrus 5446 and Bochs video cards.
|
||||||
|
|
||||||
|
* Load more appropriate video drivers automatically in `grub-mkconfig'.
|
||||||
|
|
||||||
|
* USB improvements, including hotplugging/hotunplugging, hub support,
|
||||||
|
and USB serial support.
|
||||||
|
|
||||||
|
* AMD Geode CS5536 support.
|
||||||
|
|
||||||
|
* Extensive updates to the Texinfo documentation.
|
||||||
|
|
||||||
|
* Add `grub-probe' support for the btrfs filesystem, permitting / to
|
||||||
|
reside on btrfs as long as /boot is on a filesystem natively supported
|
||||||
|
by GRUB.
|
||||||
|
|
||||||
|
* Handle symbolic links under /dev/mapper on GNU/Linux.
|
||||||
|
|
||||||
|
* Handle installation across multiple partition table types.
|
||||||
|
|
||||||
|
* Add `cmostest' command (i386/x86_64 only).
|
||||||
|
|
||||||
|
* Add support for DM-RAID disk devices on GNU/Linux.
|
||||||
|
|
||||||
|
* Remove `grub-mkisofs'. `grub-mkrescue' now uses GNU xorriso to build
|
||||||
|
CD images.
|
||||||
|
|
||||||
|
* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms.
|
||||||
|
|
||||||
|
* Unify `grub-mkimage' source code across platforms.
|
||||||
|
|
||||||
|
* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver.
|
||||||
|
|
||||||
|
* Add menu hotkey support.
|
||||||
|
|
||||||
|
* Add support for the nilfs2 filesystem.
|
||||||
|
|
||||||
|
* `grub-probe' and `grub-mkconfig' support for NetBSD.
|
||||||
|
|
||||||
|
* Support setting a background image in `grub-mkconfig'.
|
||||||
|
|
||||||
|
* Support multiple terminals in `grub-mkconfig'.
|
||||||
|
|
||||||
|
* Regexp support.
|
||||||
|
|
||||||
|
* MIPS multiboot2 support.
|
||||||
|
|
||||||
|
* Multiboot2 tag support.
|
||||||
|
|
||||||
|
* sunpc partition table support.
|
||||||
|
|
||||||
|
* Add a number of new language features to GRUB script: `for', `while',
|
||||||
|
`until', `elif', function parameters, `break', `continue', and
|
||||||
|
`shift'.
|
||||||
|
|
||||||
|
* Support nested partition tables. GRUB now prefers to name partitions
|
||||||
|
in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'.
|
||||||
|
|
||||||
|
* Speed up consecutive hostdisk operations on the same device.
|
||||||
|
|
||||||
|
* Compile parts of `grub-emu' as modules.
|
||||||
|
|
||||||
New in 1.98 - 2010-03-06:
|
New in 1.98 - 2010-03-06:
|
||||||
|
|
||||||
* Multiboot on EFI support.
|
* Multiboot on EFI support.
|
||||||
|
|
|
@ -31,7 +31,7 @@ endif
|
||||||
|
|
||||||
# Other options
|
# Other options
|
||||||
|
|
||||||
CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir),,$<)\"
|
CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir)/,,$<)\"
|
||||||
CPPFLAGS_DEFAULT += -I$(builddir)
|
CPPFLAGS_DEFAULT += -I$(builddir)
|
||||||
CPPFLAGS_DEFAULT += -I$(srcdir)
|
CPPFLAGS_DEFAULT += -I$(srcdir)
|
||||||
CPPFLAGS_DEFAULT += -I$(top_builddir)
|
CPPFLAGS_DEFAULT += -I$(top_builddir)
|
||||||
|
@ -115,6 +115,7 @@ pkglib_SCRIPTS =
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS =
|
||||||
grubconf_SCRIPTS =
|
grubconf_SCRIPTS =
|
||||||
noinst_LIBRARIES =
|
noinst_LIBRARIES =
|
||||||
|
dist_noinst_DATA =
|
||||||
|
|
||||||
TESTS =
|
TESTS =
|
||||||
EXTRA_DIST =
|
EXTRA_DIST =
|
||||||
|
|
|
@ -5,6 +5,11 @@ EXTRA_DIST += gentpl.py
|
||||||
EXTRA_DIST += Makefile.tpl
|
EXTRA_DIST += Makefile.tpl
|
||||||
EXTRA_DIST += Makefile.util.def
|
EXTRA_DIST += Makefile.util.def
|
||||||
|
|
||||||
|
EXTRA_DIST += unicode
|
||||||
|
|
||||||
|
EXTRA_DIST += util/import_gcry.py
|
||||||
|
EXTRA_DIST += util/import_unicode.py
|
||||||
|
|
||||||
EXTRA_DIST += docs/man
|
EXTRA_DIST += docs/man
|
||||||
EXTRA_DIST += docs/grub.cfg
|
EXTRA_DIST += docs/grub.cfg
|
||||||
|
|
||||||
|
@ -26,8 +31,8 @@ EXTRA_DIST += grub-core/genterminallist.sh
|
||||||
EXTRA_DIST += grub-core/genparttoollist.sh
|
EXTRA_DIST += grub-core/genparttoollist.sh
|
||||||
EXTRA_DIST += grub-core/genemuinitheader.sh
|
EXTRA_DIST += grub-core/genemuinitheader.sh
|
||||||
|
|
||||||
|
EXTRA_DIST += grub-core/lib/libgcrypt/cipher
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h')
|
EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h')
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h')
|
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h')
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h')
|
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h')
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/posix_wrap -name '*.h')
|
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h')
|
||||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/libgcrypt_wrap -name '*.h')
|
|
||||||
|
|
32
configure.ac
32
configure.ac
|
@ -586,6 +586,12 @@ AC_ARG_ENABLE([efiemu],
|
||||||
if test x"$enable_efiemu" = xno ; then
|
if test x"$enable_efiemu" = xno ; then
|
||||||
efiemu_excuse="explicitly disabled"
|
efiemu_excuse="explicitly disabled"
|
||||||
fi
|
fi
|
||||||
|
if test x"$target_cpu" != xi386 ; then
|
||||||
|
efiemu_excuse="only available on i386"
|
||||||
|
fi
|
||||||
|
if test x"$platform" = xefi ; then
|
||||||
|
efiemu_excuse="not available on efi"
|
||||||
|
fi
|
||||||
if test x"$efiemu_excuse" = x ; then
|
if test x"$efiemu_excuse" = x ; then
|
||||||
AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
|
AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
|
||||||
CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
|
CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
|
||||||
|
@ -816,12 +822,23 @@ fi
|
||||||
|
|
||||||
if test x"$device_mapper_excuse" = x ; then
|
if test x"$device_mapper_excuse" = x ; then
|
||||||
# Check for device-mapper library.
|
# Check for device-mapper library.
|
||||||
AC_CHECK_LIB([devmapper], [dm_task_create],
|
AC_CHECK_LIB([devmapper], [dm_task_create], [],
|
||||||
[LIBDEVMAPPER="-ldevmapper"
|
|
||||||
AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
|
|
||||||
[Define to 1 if you have the devmapper library.])],
|
|
||||||
[device_mapper_excuse="need devmapper library"])
|
[device_mapper_excuse="need devmapper library"])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x"$device_mapper_excuse" = x ; then
|
||||||
|
# Check for device-mapper library.
|
||||||
|
AC_CHECK_LIB([devmapper], [dm_log_with_errno_init],
|
||||||
|
[],
|
||||||
|
[device_mapper_excuse="need devmapper library"])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$device_mapper_excuse" = x ; then
|
||||||
|
LIBDEVMAPPER="-ldevmapper";
|
||||||
|
AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
|
||||||
|
[Define to 1 if you have the devmapper library.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST([LIBDEVMAPPER])
|
AC_SUBST([LIBDEVMAPPER])
|
||||||
|
|
||||||
AC_CHECK_LIB([zfs], [libzfs_init],
|
AC_CHECK_LIB([zfs], [libzfs_init],
|
||||||
|
@ -836,6 +853,8 @@ AC_CHECK_LIB([nvpair], [nvlist_print],
|
||||||
[Define to 1 if you have the NVPAIR library.])],)
|
[Define to 1 if you have the NVPAIR library.])],)
|
||||||
AC_SUBST([LIBNVPAIR])
|
AC_SUBST([LIBNVPAIR])
|
||||||
|
|
||||||
|
LIBS=""
|
||||||
|
|
||||||
pkglibrootdir='$(libdir)'/`echo $PACKAGE | sed "$program_transform_name"`
|
pkglibrootdir='$(libdir)'/`echo $PACKAGE | sed "$program_transform_name"`
|
||||||
AC_SUBST(pkglibrootdir)
|
AC_SUBST(pkglibrootdir)
|
||||||
|
|
||||||
|
@ -936,6 +955,11 @@ else
|
||||||
echo PCI support for grub-emu: No "($grub_emu_pci_excuse)"
|
echo PCI support for grub-emu: No "($grub_emu_pci_excuse)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if test x"$device_mapper_excuse" = x ; then
|
||||||
|
echo With devmapper support: Yes
|
||||||
|
else
|
||||||
|
echo With devmapper support: No "($device_mapper_excuse)"
|
||||||
|
fi
|
||||||
if [ x"$enable_mm_debug" = xyes ]; then
|
if [ x"$enable_mm_debug" = xyes ]; then
|
||||||
echo With memory debugging: Yes
|
echo With memory debugging: Yes
|
||||||
else
|
else
|
||||||
|
|
143
docs/grub.texi
143
docs/grub.texi
|
@ -46,6 +46,7 @@ Invariant Sections.
|
||||||
@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
|
@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
|
||||||
@author Gordon Matzigkeit
|
@author Gordon Matzigkeit
|
||||||
@author Yoshinori K. Okuji
|
@author Yoshinori K. Okuji
|
||||||
|
@author Colin Watson
|
||||||
@c The following two commands start the copyright page.
|
@c The following two commands start the copyright page.
|
||||||
@page
|
@page
|
||||||
@vskip 0pt plus 1filll
|
@vskip 0pt plus 1filll
|
||||||
|
@ -85,6 +86,7 @@ This edition documents version @value{VERSION}.
|
||||||
* Interface:: The menu and the command-line
|
* Interface:: The menu and the command-line
|
||||||
* Commands:: The list of available builtin commands
|
* Commands:: The list of available builtin commands
|
||||||
* Security:: Authentication and authorisation
|
* Security:: Authentication and authorisation
|
||||||
|
* Supported kernels:: The list of supported kernels
|
||||||
* Troubleshooting:: Error messages produced by GRUB
|
* Troubleshooting:: Error messages produced by GRUB
|
||||||
* Invoking grub-install:: How to use the GRUB installer
|
* Invoking grub-install:: How to use the GRUB installer
|
||||||
* Invoking grub-mkconfig:: Generate a GRUB configuration file
|
* Invoking grub-mkconfig:: Generate a GRUB configuration file
|
||||||
|
@ -1435,7 +1437,7 @@ The boot file name provided by DHCP. Read-only.
|
||||||
The name of the DHCP server responsible for these boot parameters.
|
The name of the DHCP server responsible for these boot parameters.
|
||||||
Read-only.
|
Read-only.
|
||||||
|
|
||||||
@item net_pxe_blksize
|
@item pxe_blksize
|
||||||
The PXE transfer block size. Read-write, defaults to 512.
|
The PXE transfer block size. Read-write, defaults to 512.
|
||||||
|
|
||||||
@item pxe_default_server
|
@item pxe_default_server
|
||||||
|
@ -2862,6 +2864,145 @@ adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2}
|
||||||
commands.
|
commands.
|
||||||
|
|
||||||
|
|
||||||
|
@node Supported kernels
|
||||||
|
@chapter Supported boot targets
|
||||||
|
|
||||||
|
X86 support is summarised in following table. ``Yes'' means that kernel works on the given platform, ``crashes'' means an early kernel crash which we hove will be fixed by concerned kernel developpers. ``no'' means GRUB doesn't load given kernel on a given platform. ``headless'' means that the kernel works but lacks console drivers (you can still use serial or network console). In case of ``no'' and ``crashes'' the reason is given in footnote.
|
||||||
|
@multitable @columnfractions .50 .22 .22
|
||||||
|
@item @tab BIOS @tab Coreboot
|
||||||
|
@item BIOS chainloading @tab yes @tab no (1)
|
||||||
|
@item NTLDR @tab yes @tab no (1)
|
||||||
|
@item FreeBSD bootloader @tab yes @tab crashes (1)
|
||||||
|
@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
|
||||||
|
@item 64-bit kFreeBSD @tab yes @tab crashes (2,6)
|
||||||
|
@item 32-bit kNetBSD @tab yes @tab crashes (1)
|
||||||
|
@item 64-bit kNetBSD @tab yes @tab crashes (2)
|
||||||
|
@item 32-bit kOpenBSD @tab yes @tab yes
|
||||||
|
@item 64-bit kOpenBSD @tab yes @tab yes
|
||||||
|
@item Multiboot @tab yes @tab yes
|
||||||
|
@item Multiboot2 @tab yes @tab yes
|
||||||
|
@item 32-bit Linux (legacy protocol) @tab yes @tab no (1)
|
||||||
|
@item 64-bit Linux (legacy protocol) @tab yes @tab no (1)
|
||||||
|
@item 32-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 64-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 32-bit XNU @tab yes @tab ?
|
||||||
|
@item 64-bit XNU @tab yes @tab ?
|
||||||
|
@item 32-bit EFI chainloader @tab no (3) @tab no (3)
|
||||||
|
@item 64-bit EFI chainloader @tab no (3) @tab no (3)
|
||||||
|
@item Appleloader @tab no (3) @tab no (3)
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
@multitable @columnfractions .50 .22 .22
|
||||||
|
@item @tab Multiboot @tab Qemu
|
||||||
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
|
@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
||||||
|
@item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
||||||
|
@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1)
|
||||||
|
@item 64-bit kNetBSD @tab yes @tab yes
|
||||||
|
@item 32-bit kOpenBSD @tab yes @tab yes
|
||||||
|
@item 64-bit kOpenBSD @tab yes @tab yes
|
||||||
|
@item Multiboot @tab yes @tab yes
|
||||||
|
@item Multiboot2 @tab yes @tab yes
|
||||||
|
@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1)
|
||||||
|
@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1)
|
||||||
|
@item 32-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 64-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 32-bit XNU @tab ? @tab ?
|
||||||
|
@item 64-bit XNU @tab ? @tab ?
|
||||||
|
@item 32-bit EFI chainloader @tab no (3) @tab no (3)
|
||||||
|
@item 64-bit EFI chainloader @tab no (3) @tab no (3)
|
||||||
|
@item Appleloader @tab no (3) @tab no (3)
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
@multitable @columnfractions .50 .22 .22
|
||||||
|
@item @tab 32-bit EFI @tab 64-bit EFI
|
||||||
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
|
@item 32-bit kFreeBSD @tab headless @tab headless
|
||||||
|
@item 64-bit kFreeBSD @tab headless @tab headless
|
||||||
|
@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1)
|
||||||
|
@item 64-bit kNetBSD @tab yes @tab yes
|
||||||
|
@item 32-bit kOpenBSD @tab headless @tab headless
|
||||||
|
@item 64-bit kOpenBSD @tab headless @tab headless
|
||||||
|
@item Multiboot @tab yes @tab yes
|
||||||
|
@item Multiboot2 @tab yes @tab yes
|
||||||
|
@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1)
|
||||||
|
@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1)
|
||||||
|
@item 32-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 64-bit Linux (modern protocol) @tab yes @tab yes
|
||||||
|
@item 32-bit XNU @tab yes @tab yes
|
||||||
|
@item 64-bit XNU @tab yes (5) @tab yes
|
||||||
|
@item 32-bit EFI chainloader @tab yes @tab no (4)
|
||||||
|
@item 64-bit EFI chainloader @tab no (4) @tab yes
|
||||||
|
@item Appleloader @tab yes @tab yes
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
@multitable @columnfractions .50 .22 .22
|
||||||
|
@item @tab IEEE1275
|
||||||
|
@item BIOS chainloading @tab no (1)
|
||||||
|
@item NTLDR @tab no (1)
|
||||||
|
@item FreeBSD bootloader @tab crashes (1)
|
||||||
|
@item 32-bit kFreeBSD @tab crashes (6)
|
||||||
|
@item 64-bit kFreeBSD @tab crashes (6)
|
||||||
|
@item 32-bit kNetBSD @tab crashes (1)
|
||||||
|
@item 64-bit kNetBSD @tab ?
|
||||||
|
@item 32-bit kOpenBSD @tab ?
|
||||||
|
@item 64-bit kOpenBSD @tab ?
|
||||||
|
@item Multiboot @tab ?
|
||||||
|
@item Multiboot2 @tab ?
|
||||||
|
@item 32-bit Linux (legacy protocol) @tab no (1)
|
||||||
|
@item 64-bit Linux (legacy protocol) @tab no (1)
|
||||||
|
@item 32-bit Linux (modern protocol) @tab ?
|
||||||
|
@item 64-bit Linux (modern protocol) @tab ?
|
||||||
|
@item 32-bit XNU @tab ?
|
||||||
|
@item 64-bit XNU @tab ?
|
||||||
|
@item 32-bit EFI chainloader @tab no (3)
|
||||||
|
@item 64-bit EFI chainloader @tab no (3)
|
||||||
|
@item Appleloader @tab no (3)
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item Requires BIOS
|
||||||
|
@item Crashes because the memory at 0x0-0x1000 isn't available
|
||||||
|
@item EFI only
|
||||||
|
@item 32-bit and 64-bit EFI have different structures and work in different CPU modes so it's not possible to chainload 32-bit bootloader on 64-bit platform and vice-versa
|
||||||
|
@item Some modules may need to be disabled
|
||||||
|
@item Requires ACPI
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
PowerPC and Sparc ports support only Linux. MIPS port supports Linux and multiboot2.
|
||||||
|
|
||||||
|
@chapter Boot tests
|
||||||
|
|
||||||
|
As you have seen in previous chapter the support matrix is pretty big and some of the configurations are only rarely used. To ensure the quality bootchecks are available for all x86 targets except EFI chainloader, Appleloader and XNU. All x86 platforms have bootcheck facility except ieee1275. Multiboot, multiboot2, BIOS chainloader, ntldr and freebsd-bootloader boot targets are tested only with a fake kernel images. Only Linux is tested among the payloads using Linux protocols.
|
||||||
|
|
||||||
|
Following variables must be defined:
|
||||||
|
|
||||||
|
@multitable @columnfractions .30 .65
|
||||||
|
@item GRUB_PAYLOADS_DIR @tab directory containing the required kernels
|
||||||
|
@item GRUB_CBFSTOOL @tab cbfstoll from Coreboot package (for coreboot platform only)
|
||||||
|
@item GRUB_COREBOOT_ROM @tab empty Coreboot ROM
|
||||||
|
@item GRUB_QEMU_OPTS @tab additional options to be supplied to QEMU
|
||||||
|
@end multitable
|
||||||
|
|
||||||
|
Required files are:
|
||||||
|
|
||||||
|
@multitable @columnfractions .40 .55
|
||||||
|
@item kfreebsd_env.i386 @tab 32-bit kFreeBSD device hints
|
||||||
|
@item kfreebsd.i386 @tab 32-bit FreeBSD kernel image
|
||||||
|
@item kfreebsd.x86_64, kfreebsd_env.x86_64 @tab same from 64-bit kFreeBSD
|
||||||
|
@item knetbsd.i386 @tab 32-bit NetBSD kernel image
|
||||||
|
@item knetbsd.miniroot.i386 @tab 32-bit kNetBSD miniroot.kmod.
|
||||||
|
@item knetbsd.x86_64, knetbsd.miniroot.x86_64 @tab same from 64-bit kNetBSD
|
||||||
|
@item kopenbsd.i386 @tab 32-bit OpenBSD kernel bsd.rd image
|
||||||
|
@item kopenbsd.x86_64 @tab same from 64-bit kOpenBSD
|
||||||
|
@item linux.i386 @tab 32-bit Linux
|
||||||
|
@item linux.x86_64 @tab 64-bit Linux
|
||||||
|
@end multitable
|
||||||
|
|
||||||
@node Troubleshooting
|
@node Troubleshooting
|
||||||
@chapter Error messages produced by GRUB
|
@chapter Error messages produced by GRUB
|
||||||
|
|
||||||
|
|
52
gentpl.py
52
gentpl.py
|
@ -10,46 +10,38 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
|
||||||
"powerpc_ieee1275" ]
|
"powerpc_ieee1275" ]
|
||||||
|
|
||||||
GROUPS = {}
|
GROUPS = {}
|
||||||
|
|
||||||
|
GROUPS["common"] = GRUB_PLATFORMS[:]
|
||||||
|
|
||||||
|
# Groups based on CPU
|
||||||
GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ]
|
GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ]
|
||||||
GROUPS["x86_64"] = [ "x86_64_efi" ]
|
GROUPS["x86_64"] = [ "x86_64_efi" ]
|
||||||
GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
|
GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
|
||||||
GROUPS["x86_efi"] = [ "i386_efi", "x86_64_efi" ]
|
|
||||||
|
|
||||||
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
|
|
||||||
GROUPS["x86_efi_pc"] = GROUPS["x86_efi"] + ["i386_pc"]
|
|
||||||
|
|
||||||
GROUPS["x86_noefi"] = GROUPS["x86"][:]; GROUPS["x86_noefi"].remove("i386_efi"); GROUPS["x86_noefi"].remove("x86_64_efi")
|
|
||||||
GROUPS["i386_noefi"] = GROUPS["i386"][:]; GROUPS["i386_noefi"].remove("i386_efi")
|
|
||||||
|
|
||||||
GROUPS["x86_noieee1275"] = GROUPS["x86"][:]; GROUPS["x86_noieee1275"].remove("i386_ieee1275")
|
|
||||||
GROUPS["i386_noieee1275"] = GROUPS["i386"][:]; GROUPS["i386_noieee1275"].remove("i386_ieee1275")
|
|
||||||
|
|
||||||
GROUPS["i386_noefi_noieee1275"] = GROUPS["i386_noefi"][:]; GROUPS["i386_noefi_noieee1275"].remove("i386_ieee1275")
|
|
||||||
|
|
||||||
GROUPS["i386_pc_qemu_coreboot"] = ["i386_pc", "i386_qemu", "i386_coreboot"]
|
|
||||||
GROUPS["i386_coreboot_multiboot"] = ["i386_coreboot", "i386_multiboot"]
|
|
||||||
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
|
|
||||||
GROUPS["i386_pc_coreboot_multiboot_qemu"] = ["i386_pc", "i386_coreboot", "i386_multiboot", "i386_qemu"]
|
|
||||||
|
|
||||||
GROUPS["mips"] = [ "mips_yeeloong" ]
|
GROUPS["mips"] = [ "mips_yeeloong" ]
|
||||||
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
||||||
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
||||||
|
|
||||||
GROUPS["nosparc64"] = GRUB_PLATFORMS[:]; GROUPS["nosparc64"].remove("sparc64_ieee1275")
|
# Groups based on firmware
|
||||||
GROUPS["x86_noefi_mips"] = GROUPS["x86_noefi"] + GROUPS["mips"]
|
GROUPS["x86_efi"] = [ "i386_efi", "x86_64_efi" ]
|
||||||
|
|
||||||
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
|
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
|
||||||
GROUPS["noieee1275"] = GRUB_PLATFORMS[:]
|
|
||||||
for i in GROUPS["ieee1275"]: GROUPS["noieee1275"].remove(i)
|
|
||||||
GROUPS["ieee1275_mips"] = GROUPS["ieee1275"] + GROUPS["mips"]
|
|
||||||
|
|
||||||
GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"]
|
|
||||||
|
|
||||||
|
# emu is a special case so many core functionality isn't needed on this platform
|
||||||
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
|
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
|
||||||
GROUPS["noemu_noieee1275"] = GRUB_PLATFORMS[:]
|
|
||||||
for i in ["emu"] + GROUPS["ieee1275"]: GROUPS["noemu_noieee1275"].remove(i)
|
|
||||||
|
|
||||||
GROUPS["common"] = GRUB_PLATFORMS[:]
|
# Groups based on hardware features
|
||||||
|
GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi")
|
||||||
|
GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"]
|
||||||
|
GROUPS["usb"] = GROUPS["pci"]
|
||||||
|
|
||||||
|
# If gfxterm is main output console integrate it into kernel
|
||||||
|
GROUPS["videoinkernel"] = ["mips_yeeloong"]
|
||||||
|
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
|
||||||
|
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
|
||||||
|
|
||||||
|
# Miscelaneous groups schedulded to disappear in future
|
||||||
|
GROUPS["nosparc64"] = GRUB_PLATFORMS[:]; GROUPS["nosparc64"].remove("sparc64_ieee1275")
|
||||||
|
GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
|
||||||
|
GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Create platform => groups reverse map, where groups covering that
|
# Create platform => groups reverse map, where groups covering that
|
||||||
|
@ -486,7 +478,7 @@ chmod a+x [+ name +]
|
||||||
""")
|
""")
|
||||||
|
|
||||||
r += gvar_add("CLEANFILES", "[+ name +]")
|
r += gvar_add("CLEANFILES", "[+ name +]")
|
||||||
r += gvar_add("EXTRA_DIST", platform_sources(platform))
|
r += gvar_add("dist_noinst_DATA", platform_sources(platform))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def module_rules():
|
def module_rules():
|
||||||
|
|
|
@ -58,8 +58,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/elf.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/elfload.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h
|
||||||
|
@ -70,35 +68,23 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/reader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/symbol.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/types.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
||||||
|
|
||||||
if COND_i386_pc
|
if COND_i386_pc
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/biosdisk.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/vga.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/vbe.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_i386_efi
|
if COND_i386_efi
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||||
|
@ -106,63 +92,36 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_i386_coreboot
|
if COND_i386_coreboot
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_i386_multiboot
|
if COND_i386_multiboot
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_i386_qemu
|
if COND_i386_qemu
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_i386_ieee1275
|
if COND_i386_ieee1275
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_x86_64_efi
|
if COND_x86_64_efi
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/time.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_mips_yeeloong
|
if COND_mips_yeeloong
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h
|
||||||
|
@ -180,28 +139,17 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_powerpc_ieee1275
|
if COND_powerpc_ieee1275
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_sparc64_ieee1275
|
if COND_sparc64_ieee1275
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_emu
|
if COND_emu
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/time.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/types.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gzio.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/menu.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
|
||||||
if COND_GRUB_EMU_SDL
|
if COND_GRUB_EMU_SDL
|
||||||
|
@ -312,7 +260,6 @@ moddep.lst: kernel_syms.lst genmoddep.awk $(DEF_FILES) $(UND_FILES)
|
||||||
| $(AWK) -f $(srcdir)/genmoddep.awk $(UND_FILES) > $@ \
|
| $(AWK) -f $(srcdir)/genmoddep.awk $(UND_FILES) > $@ \
|
||||||
|| (rm -f $@; exit 1)
|
|| (rm -f $@; exit 1)
|
||||||
|
|
||||||
if COND_i386_pc
|
|
||||||
if COND_ENABLE_EFIEMU
|
if COND_ENABLE_EFIEMU
|
||||||
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
|
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
|
||||||
-rm -f $@; \
|
-rm -f $@; \
|
||||||
|
@ -355,5 +302,3 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
|
||||||
platform_DATA += efiemu32.o efiemu64.o
|
platform_DATA += efiemu32.o efiemu64.o
|
||||||
CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
|
CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ kernel = {
|
||||||
x86_64_efi_startup = kern/x86_64/efi/startup.S;
|
x86_64_efi_startup = kern/x86_64/efi/startup.S;
|
||||||
i386_qemu_startup = kern/i386/qemu/startup.S;
|
i386_qemu_startup = kern/i386/qemu/startup.S;
|
||||||
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
|
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
|
||||||
i386_coreboot_multiboot_startup = kern/i386/coreboot/startup.S;
|
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
||||||
|
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
||||||
mips_yeeloong_startup = kern/mips/startup.S;
|
mips_yeeloong_startup = kern/mips/startup.S;
|
||||||
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
|
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
|
||||||
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
|
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
|
||||||
|
@ -65,7 +66,12 @@ kernel = {
|
||||||
|
|
||||||
noemu_nodist = symlist.c;
|
noemu_nodist = symlist.c;
|
||||||
|
|
||||||
noemu_noieee1275 = kern/generic/rtc_get_time_ms.c;
|
i386_pc = kern/generic/rtc_get_time_ms.c;
|
||||||
|
x86_efi = kern/generic/rtc_get_time_ms.c;
|
||||||
|
i386_qemu = kern/generic/rtc_get_time_ms.c;
|
||||||
|
i386_coreboot = kern/generic/rtc_get_time_ms.c;
|
||||||
|
i386_multiboot = kern/generic/rtc_get_time_ms.c;
|
||||||
|
mips_yeeloong = kern/generic/rtc_get_time_ms.c;
|
||||||
|
|
||||||
ieee1275 = disk/ieee1275/ofdisk.c;
|
ieee1275 = disk/ieee1275/ofdisk.c;
|
||||||
ieee1275 = kern/ieee1275/cmain.c;
|
ieee1275 = kern/ieee1275/cmain.c;
|
||||||
|
@ -74,20 +80,20 @@ kernel = {
|
||||||
ieee1275 = kern/ieee1275/openfw.c;
|
ieee1275 = kern/ieee1275/openfw.c;
|
||||||
ieee1275 = term/ieee1275/ofconsole.c;
|
ieee1275 = term/ieee1275/ofconsole.c;
|
||||||
|
|
||||||
ieee1275_mips = term/terminfo.c;
|
ieee1275 = term/terminfo.c;
|
||||||
ieee1275_mips = term/tparm.c;
|
ieee1275 = term/tparm.c;
|
||||||
|
mips = term/terminfo.c;
|
||||||
|
mips = term/tparm.c;
|
||||||
|
|
||||||
i386 = kern/i386/dl.c;
|
i386 = kern/i386/dl.c;
|
||||||
|
|
||||||
i386_coreboot_multiboot_qemu = kern/i386/coreboot/init.c;
|
i386_coreboot_multiboot_qemu = kern/i386/coreboot/init.c;
|
||||||
i386_coreboot_multiboot_qemu = kern/i386/halt.c;
|
|
||||||
i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c;
|
i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c;
|
||||||
|
|
||||||
i386_pc_coreboot_multiboot_qemu = term/i386/vga_common.c;
|
i386_coreboot_multiboot_qemu = term/i386/vga_common.c;
|
||||||
|
i386_pc = term/i386/vga_common.c;
|
||||||
|
|
||||||
i386_noefi = kern/i386/misc.S;
|
x86 = kern/i386/pit.c;
|
||||||
|
|
||||||
x86_noieee1275 = kern/i386/pit.c;
|
|
||||||
|
|
||||||
x86_efi = disk/efi/efidisk.c;
|
x86_efi = disk/efi/efidisk.c;
|
||||||
x86_efi = kern/efi/efi.c;
|
x86_efi = kern/efi/efi.c;
|
||||||
|
@ -118,33 +124,20 @@ kernel = {
|
||||||
i386_multiboot = kern/i386/multiboot_mmap.c;
|
i386_multiboot = kern/i386/multiboot_mmap.c;
|
||||||
i386_multiboot = kern/i386/tsc.c;
|
i386_multiboot = kern/i386/tsc.c;
|
||||||
|
|
||||||
i386_ieee1275 = kern/i386/ieee1275/init.c;
|
|
||||||
i386_ieee1275 = kern/ieee1275/init.c;
|
i386_ieee1275 = kern/ieee1275/init.c;
|
||||||
|
|
||||||
mips_yeeloong = term/ns8250.c;
|
mips_yeeloong = term/ns8250.c;
|
||||||
mips_yeeloong = bus/bonito.c;
|
mips_yeeloong = bus/bonito.c;
|
||||||
mips_yeeloong = bus/cs5536.c;
|
mips_yeeloong = bus/cs5536.c;
|
||||||
mips_yeeloong = bus/pci.c;
|
mips_yeeloong = bus/pci.c;
|
||||||
mips_yeeloong = commands/extcmd.c;
|
|
||||||
mips_yeeloong = font/font.c;
|
|
||||||
mips_yeeloong = font/font_cmd.c;
|
|
||||||
mips_yeeloong = io/bufio.c;
|
|
||||||
mips_yeeloong = kern/mips/cache.S;
|
mips_yeeloong = kern/mips/cache.S;
|
||||||
mips_yeeloong = kern/mips/dl.c;
|
mips_yeeloong = kern/mips/dl.c;
|
||||||
mips_yeeloong = kern/mips/init.c;
|
mips_yeeloong = kern/mips/init.c;
|
||||||
mips_yeeloong = kern/mips/yeeloong/init.c;
|
mips_yeeloong = kern/mips/yeeloong/init.c;
|
||||||
mips_yeeloong = lib/arg.c;
|
|
||||||
mips_yeeloong = term/at_keyboard.c;
|
mips_yeeloong = term/at_keyboard.c;
|
||||||
mips_yeeloong = term/gfxterm.c;
|
|
||||||
mips_yeeloong = term/serial.c;
|
mips_yeeloong = term/serial.c;
|
||||||
mips_yeeloong = video/bitmap.c;
|
|
||||||
mips_yeeloong = video/bitmap_scale.c;
|
|
||||||
mips_yeeloong = video/fb/fbblit.c;
|
|
||||||
mips_yeeloong = video/fb/fbfill.c;
|
|
||||||
mips_yeeloong = video/fb/fbutil.c;
|
|
||||||
mips_yeeloong = video/fb/video_fb.c;
|
|
||||||
mips_yeeloong = video/sm712.c;
|
mips_yeeloong = video/sm712.c;
|
||||||
mips_yeeloong = video/video.c;
|
extra_dist = video/sm712_init.c;
|
||||||
|
|
||||||
powerpc_ieee1275 = kern/ieee1275/init.c;
|
powerpc_ieee1275 = kern/ieee1275/init.c;
|
||||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||||
|
@ -166,9 +159,23 @@ kernel = {
|
||||||
emu = kern/emu/mm.c;
|
emu = kern/emu/mm.c;
|
||||||
emu = kern/emu/time.c;
|
emu = kern/emu/time.c;
|
||||||
|
|
||||||
extra_dist = kern/i386/loader.S;
|
videoinkernel = lib/arg.c;
|
||||||
|
videoinkernel = term/gfxterm.c;
|
||||||
|
videoinkernel = commands/extcmd.c;
|
||||||
|
videoinkernel = font/font.c;
|
||||||
|
videoinkernel = font/font_cmd.c;
|
||||||
|
videoinkernel = io/bufio.c;
|
||||||
|
videoinkernel = video/bitmap.c;
|
||||||
|
videoinkernel = video/bitmap_scale.c;
|
||||||
|
videoinkernel = video/fb/fbblit.c;
|
||||||
|
videoinkernel = video/fb/fbfill.c;
|
||||||
|
videoinkernel = video/fb/fbutil.c;
|
||||||
|
videoinkernel = video/fb/video_fb.c;
|
||||||
|
videoinkernel = video/video.c;
|
||||||
|
|
||||||
extra_dist = kern/i386/realmode.S;
|
extra_dist = kern/i386/realmode.S;
|
||||||
extra_dist = kern/i386/pc/lzma_decode.S;
|
extra_dist = kern/i386/pc/lzma_decode.S;
|
||||||
|
extra_dist = kern/mips/cache_flush.S;
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -305,8 +312,7 @@ module = {
|
||||||
noemu = bus/usb/usbtrans.c;
|
noemu = bus/usb/usbtrans.c;
|
||||||
noemu = bus/usb/usbhub.c;
|
noemu = bus/usb/usbhub.c;
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,8 +320,7 @@ module = {
|
||||||
name = usbserial_common;
|
name = usbserial_common;
|
||||||
common = bus/usb/serial/common.c;
|
common = bus/usb/serial/common.c;
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -323,8 +328,7 @@ module = {
|
||||||
name = usbserial_pl2303;
|
name = usbserial_pl2303;
|
||||||
common = bus/usb/serial/pl2303.c;
|
common = bus/usb/serial/pl2303.c;
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -332,22 +336,20 @@ module = {
|
||||||
name = usbserial_ftdi;
|
name = usbserial_ftdi;
|
||||||
common = bus/usb/serial/ftdi.c;
|
common = bus/usb/serial/ftdi.c;
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = uhci;
|
name = uhci;
|
||||||
common = bus/usb/uhci.c;
|
common = bus/usb/uhci.c;
|
||||||
enable = i386_pc;
|
enable = x86;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = ohci;
|
name = ohci;
|
||||||
common = bus/usb/ohci.c;
|
common = bus/usb/ohci.c;
|
||||||
enable = i386_pc;
|
enable = pci;
|
||||||
enable = mips_yeeloong;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -361,6 +363,7 @@ module = {
|
||||||
enable = x86_efi;
|
enable = x86_efi;
|
||||||
enable = i386_ieee1275;
|
enable = i386_ieee1275;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
|
enable = i386_multiboot;
|
||||||
emu_condition = COND_GRUB_EMU_PCI;
|
emu_condition = COND_GRUB_EMU_PCI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -379,9 +382,8 @@ library = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = cmostest;
|
name = cmostest;
|
||||||
i386 = commands/i386/cmostest.c;
|
common = commands/i386/cmostest.c;
|
||||||
enable = i386_pc;
|
enable = cmos;
|
||||||
enable = i386_coreboot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -401,12 +403,16 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = acpi;
|
name = acpi;
|
||||||
|
|
||||||
i386 = commands/acpi.c;
|
x86 = commands/acpi.c;
|
||||||
x86_efi = commands/efi/acpi.c;
|
x86_efi = commands/efi/acpi.c;
|
||||||
i386_pc = commands/i386/pc/acpi.c;
|
i386_pc = commands/i386/pc/acpi.c;
|
||||||
|
i386_coreboot = commands/i386/pc/acpi.c;
|
||||||
|
i386_multiboot = commands/i386/pc/acpi.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = x86_efi;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
|
enable = i386_coreboot;
|
||||||
|
enable = i386_multiboot;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -486,6 +492,12 @@ module = {
|
||||||
name = halt;
|
name = halt;
|
||||||
nopc = commands/halt.c;
|
nopc = commands/halt.c;
|
||||||
i386_pc = commands/i386/pc/halt.c;
|
i386_pc = commands/i386/pc/halt.c;
|
||||||
|
i386_multiboot = lib/i386/halt.c;
|
||||||
|
i386_coreboot = lib/i386/halt.c;
|
||||||
|
i386_qemu = lib/i386/halt.c;
|
||||||
|
x86_efi = lib/efi/halt.c;
|
||||||
|
ieee1275 = lib/ieee1275/halt.c;
|
||||||
|
emu = lib/emu/halt.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -497,7 +509,7 @@ module = {
|
||||||
name = hdparm;
|
name = hdparm;
|
||||||
common = commands/hdparm.c;
|
common = commands/hdparm.c;
|
||||||
common = lib/hexdump.c;
|
common = lib/hexdump.c;
|
||||||
enable = i386_pc;
|
enable = pci;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -542,8 +554,7 @@ module = {
|
||||||
name = lspci;
|
name = lspci;
|
||||||
common = commands/lspci.c;
|
common = commands/lspci.c;
|
||||||
|
|
||||||
enable = x86;
|
enable = pci;
|
||||||
enable = mips;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -655,8 +666,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = usbtest;
|
name = usbtest;
|
||||||
common = commands/usbtest.c;
|
common = commands/usbtest.c;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
enable = emu;
|
enable = emu;
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
@ -731,15 +741,13 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = ata;
|
name = ata;
|
||||||
common = disk/ata.c;
|
common = disk/ata.c;
|
||||||
enable = x86;
|
enable = pci;
|
||||||
enable = mips;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = ata_pthru;
|
name = ata_pthru;
|
||||||
common = disk/ata_pthru.c;
|
common = disk/ata_pthru.c;
|
||||||
enable = x86;
|
enable = pci;
|
||||||
enable = mips_yeeloong;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -751,8 +759,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = usbms;
|
name = usbms;
|
||||||
common = disk/usbms.c;
|
common = disk/usbms.c;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
enable = emu;
|
enable = emu;
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
@ -765,19 +772,23 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = efiemu;
|
name = efiemu;
|
||||||
i386_pc = efiemu/main.c;
|
common = efiemu/main.c;
|
||||||
i386_pc = efiemu/i386/loadcore32.c;
|
common = efiemu/i386/loadcore32.c;
|
||||||
i386_pc = efiemu/i386/loadcore64.c;
|
common = efiemu/i386/loadcore64.c;
|
||||||
i386_pc = efiemu/i386/pc/cfgtables.c;
|
i386_pc = efiemu/i386/pc/cfgtables.c;
|
||||||
i386_pc = efiemu/mm.c;
|
i386_coreboot = efiemu/i386/pc/cfgtables.c;
|
||||||
i386_pc = efiemu/loadcore_common.c;
|
i386_multiboot = efiemu/i386/pc/cfgtables.c;
|
||||||
i386_pc = efiemu/symbols.c;
|
i386_ieee1275 = efiemu/i386/nocfgtables.c;
|
||||||
i386_pc = efiemu/loadcore32.c;
|
i386_qemu = efiemu/i386/nocfgtables.c;
|
||||||
i386_pc = efiemu/loadcore64.c;
|
common = efiemu/mm.c;
|
||||||
i386_pc = efiemu/prepare32.c;
|
common = efiemu/loadcore_common.c;
|
||||||
i386_pc = efiemu/prepare64.c;
|
common = efiemu/symbols.c;
|
||||||
i386_pc = efiemu/pnvram.c;
|
common = efiemu/loadcore32.c;
|
||||||
i386_pc = efiemu/i386/coredetect.c;
|
common = efiemu/loadcore64.c;
|
||||||
|
common = efiemu/prepare32.c;
|
||||||
|
common = efiemu/prepare64.c;
|
||||||
|
common = efiemu/pnvram.c;
|
||||||
|
common = efiemu/i386/coredetect.c;
|
||||||
|
|
||||||
extra_dist = efiemu/prepare.c;
|
extra_dist = efiemu/prepare.c;
|
||||||
extra_dist = efiemu/loadcore.c;
|
extra_dist = efiemu/loadcore.c;
|
||||||
|
@ -785,16 +796,17 @@ module = {
|
||||||
extra_dist = efiemu/runtime/efiemu.c;
|
extra_dist = efiemu/runtime/efiemu.c;
|
||||||
|
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
|
enable = i386_coreboot;
|
||||||
|
enable = i386_ieee1275;
|
||||||
|
enable = i386_multiboot;
|
||||||
|
enable = i386_qemu;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = font;
|
name = font;
|
||||||
common = font/font.c;
|
common = font/font.c;
|
||||||
common = font/font_cmd.c;
|
common = font/font_cmd.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -962,10 +974,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = bufio;
|
name = bufio;
|
||||||
common = io/bufio.c;
|
common = io/bufio.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -987,26 +996,35 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = relocator;
|
name = relocator;
|
||||||
mips = lib/mips/relocator.c;
|
common = lib/relocator.c;
|
||||||
mips = lib/mips/relocator_asm.S;
|
x86 = lib/i386/relocator16.S;
|
||||||
|
x86 = lib/i386/relocator32.S;
|
||||||
|
x86 = lib/i386/relocator64.S;
|
||||||
|
i386 = lib/i386/relocator_asm.S;
|
||||||
|
x86_64 = lib/x86_64/relocator_asm.S;
|
||||||
x86 = lib/i386/relocator.c;
|
x86 = lib/i386/relocator.c;
|
||||||
x86 = lib/i386/relocator_asm.S;
|
ieee1275 = lib/ieee1275/relocator.c;
|
||||||
x86 = lib/i386/relocator_backward.S;
|
x86_efi = lib/efi/relocator.c;
|
||||||
extra_dist = lib/relocator.c;
|
mips = lib/mips/relocator_asm.S;
|
||||||
|
mips = lib/mips/relocator.c;
|
||||||
|
powerpc = lib/powerpc/relocator_asm.S;
|
||||||
|
powerpc = lib/powerpc/relocator.c;
|
||||||
|
|
||||||
|
extra_dist = lib/i386/relocator_common.S;
|
||||||
|
extra_dist = kern/powerpc/cache_flush.S;
|
||||||
|
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
enable = powerpc;
|
||||||
enable = x86;
|
enable = x86;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = datetime;
|
name = datetime;
|
||||||
x86_noefi_mips = lib/cmos_datetime.c;
|
cmos = lib/cmos_datetime.c;
|
||||||
x86_efi = lib/efi/datetime.c;
|
x86_efi = lib/efi/datetime.c;
|
||||||
sparc64_ieee1275 = lib/ieee1275/datetime.c;
|
sparc64_ieee1275 = lib/ieee1275/datetime.c;
|
||||||
powerpc_ieee1275 = lib/ieee1275/datetime.c;
|
powerpc_ieee1275 = lib/ieee1275/datetime.c;
|
||||||
enable = x86;
|
enable = noemu;
|
||||||
enable = mips;
|
|
||||||
enable = sparc64_ieee1275;
|
|
||||||
enable = powerpc_ieee1275;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1022,28 +1040,19 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = aout;
|
name = aout;
|
||||||
common = loader/aout.c;
|
common = loader/aout.c;
|
||||||
enable = i386_pc;
|
enable = x86;
|
||||||
enable = i386_qemu;
|
|
||||||
enable = i386_coreboot;
|
|
||||||
enable = i386_multiboot;
|
|
||||||
enable = i386_ieee1275;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = bsd;
|
name = bsd;
|
||||||
i386 = loader/i386/bsd.c;
|
x86 = loader/i386/bsd.c;
|
||||||
i386 = loader/i386/bsd32.c;
|
x86 = loader/i386/bsd32.c;
|
||||||
i386 = loader/i386/bsd64.c;
|
x86 = loader/i386/bsd64.c;
|
||||||
i386 = loader/i386/bsd_helper.S;
|
|
||||||
i386 = loader/i386/bsd_trampoline.S;
|
|
||||||
|
|
||||||
extra_dist = loader/i386/bsdXX.c;
|
extra_dist = loader/i386/bsdXX.c;
|
||||||
extra_dist = loader/i386/bsd_pagetable.c;
|
extra_dist = loader/i386/bsd_pagetable.c;
|
||||||
|
|
||||||
enable = i386_pc;
|
enable = x86;
|
||||||
enable = i386_qemu;
|
|
||||||
enable = i386_coreboot;
|
|
||||||
enable = i386_multiboot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1052,6 +1061,12 @@ module = {
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = ntldr;
|
||||||
|
i386_pc = loader/i386/pc/ntldr.c;
|
||||||
|
enable = i386_pc;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = multiboot2;
|
name = multiboot2;
|
||||||
cppflags = "-DGRUB_USE_MULTIBOOT2";
|
cppflags = "-DGRUB_USE_MULTIBOOT2";
|
||||||
|
@ -1072,11 +1087,7 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = linux;
|
name = linux;
|
||||||
i386_noefi_noieee1275 = loader/i386/linux.c;
|
x86 = loader/i386/linux.c;
|
||||||
|
|
||||||
x86_efi = loader/i386/efi/linux.c;
|
|
||||||
x86_64_efi = loader/i386/linux_trampoline.S;
|
|
||||||
i386_ieee1275 = loader/i386/ieee1275/linux.c;
|
|
||||||
mips = loader/mips/linux.c;
|
mips = loader/mips/linux.c;
|
||||||
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
||||||
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
||||||
|
@ -1085,16 +1096,15 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = xnu;
|
name = xnu;
|
||||||
x86_efi_pc = loader/xnu_resume.c;
|
x86 = loader/xnu_resume.c;
|
||||||
x86_efi_pc = loader/i386/xnu.c;
|
x86 = loader/i386/xnu.c;
|
||||||
x86_efi_pc = loader/macho32.c;
|
x86 = loader/macho32.c;
|
||||||
x86_efi_pc = loader/macho64.c;
|
x86 = loader/macho64.c;
|
||||||
x86_efi_pc = loader/macho.c;
|
x86 = loader/macho.c;
|
||||||
x86_efi_pc = loader/xnu.c;
|
x86 = loader/xnu.c;
|
||||||
|
|
||||||
extra_dist = loader/machoXX.c;
|
extra_dist = loader/machoXX.c;
|
||||||
enable = i386_pc;
|
enable = x86;
|
||||||
enable = x86_efi;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1113,34 +1123,15 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = mmap;
|
name = mmap;
|
||||||
i386_pc = mmap/mmap.c;
|
common = mmap/mmap.c;
|
||||||
i386_pc = mmap/i386/uppermem.c;
|
x86 = mmap/i386/uppermem.c;
|
||||||
i386_pc = mmap/i386/mmap.c;
|
x86 = mmap/i386/mmap.c;
|
||||||
|
|
||||||
i386_pc = mmap/i386/pc/mmap.c;
|
i386_pc = mmap/i386/pc/mmap.c;
|
||||||
i386_pc = mmap/i386/pc/mmap_helper.S;
|
i386_pc = mmap/i386/pc/mmap_helper.S;
|
||||||
|
|
||||||
x86_efi = mmap/mmap.c;
|
|
||||||
x86_efi = mmap/i386/uppermem.c;
|
|
||||||
x86_efi = mmap/i386/mmap.c;
|
|
||||||
x86_efi = mmap/efi/mmap.c;
|
x86_efi = mmap/efi/mmap.c;
|
||||||
|
|
||||||
i386_coreboot = mmap/mmap.c;
|
|
||||||
i386_coreboot = mmap/i386/uppermem.c;
|
|
||||||
i386_coreboot = mmap/i386/mmap.c;
|
|
||||||
|
|
||||||
i386_multiboot = mmap/mmap.c;
|
|
||||||
i386_multiboot = mmap/i386/uppermem.c;
|
|
||||||
i386_multiboot = mmap/i386/mmap.c;
|
|
||||||
|
|
||||||
i386_qemu = mmap/mmap.c;
|
|
||||||
i386_qemu = mmap/i386/uppermem.c;
|
|
||||||
i386_qemu = mmap/i386/mmap.c;
|
|
||||||
|
|
||||||
i386_ieee1275 = mmap/mmap.c;
|
|
||||||
i386_ieee1275 = mmap/i386/uppermem.c;
|
|
||||||
i386_ieee1275 = mmap/i386/mmap.c;
|
|
||||||
|
|
||||||
mips_yeeloong = mmap/mmap.c;
|
|
||||||
mips_yeeloong = mmap/mips/yeeloong/uppermem.c;
|
mips_yeeloong = mmap/mips/yeeloong/uppermem.c;
|
||||||
|
|
||||||
enable = x86;
|
enable = x86;
|
||||||
|
@ -1240,10 +1231,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = gfxterm;
|
name = gfxterm;
|
||||||
common = term/gfxterm.c;
|
common = term/gfxterm.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1272,8 +1260,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = usb_keyboard;
|
name = usb_keyboard;
|
||||||
common = term/usb_keyboard.c;
|
common = term/usb_keyboard.c;
|
||||||
enable = i386_pc;
|
enable = usb;
|
||||||
enable = mips_yeeloong;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1284,9 +1271,11 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = vga_text;
|
name = vga_text;
|
||||||
x86 = term/i386/pc/vga_text.c;
|
common = term/i386/pc/vga_text.c;
|
||||||
x86 = term/i386/vga_common.c;
|
common = term/i386/vga_common.c;
|
||||||
enable = x86;
|
enable = i386_pc;
|
||||||
|
enable = i386_coreboot;
|
||||||
|
enable = i386_multiboot;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1316,19 +1305,13 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = bitmap;
|
name = bitmap;
|
||||||
common = video/bitmap.c;
|
common = video/bitmap.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = bitmap_scale;
|
name = bitmap_scale;
|
||||||
common = video/bitmap_scale.c;
|
common = video/bitmap_scale.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1370,19 +1353,13 @@ module = {
|
||||||
common = video/fb/fbblit.c;
|
common = video/fb/fbblit.c;
|
||||||
common = video/fb/fbfill.c;
|
common = video/fb/fbfill.c;
|
||||||
common = video/fb/fbutil.c;
|
common = video/fb/fbutil.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = video;
|
name = video;
|
||||||
common = video/video.c;
|
common = video/video.c;
|
||||||
enable = emu;
|
enable = videomodules;
|
||||||
enable = x86;
|
|
||||||
enable = sparc64;
|
|
||||||
enable = powerpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
|
|
@ -153,10 +153,6 @@ real_start:
|
||||||
/* set %si to the disk address packet */
|
/* set %si to the disk address packet */
|
||||||
movw $disk_address_packet, %si
|
movw $disk_address_packet, %si
|
||||||
|
|
||||||
/* do not probe LBA if the drive is a floppy */
|
|
||||||
testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
|
|
||||||
jz LOCAL(chs_mode)
|
|
||||||
|
|
||||||
/* check if LBA is supported */
|
/* check if LBA is supported */
|
||||||
movb $0x41, %ah
|
movb $0x41, %ah
|
||||||
movw $0x55aa, %bx
|
movw $0x55aa, %bx
|
||||||
|
|
|
@ -185,7 +185,7 @@ real_code_2:
|
||||||
call LOCAL(move_memory)
|
call LOCAL(move_memory)
|
||||||
|
|
||||||
/* Check for multiboot signature. */
|
/* Check for multiboot signature. */
|
||||||
cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END)
|
cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE)
|
||||||
jz 1f
|
jz 1f
|
||||||
|
|
||||||
movl (ramdisk_image - start), %esi
|
movl (ramdisk_image - start), %esi
|
||||||
|
|
|
@ -55,12 +55,12 @@ struct grub_ohci_td
|
||||||
grub_uint32_t next_td; /* LittleEndian physical address */
|
grub_uint32_t next_td; /* LittleEndian physical address */
|
||||||
grub_uint32_t buffer_end; /* LittleEndian physical address */
|
grub_uint32_t buffer_end; /* LittleEndian physical address */
|
||||||
/* next values are not for OHCI HW */
|
/* next values are not for OHCI HW */
|
||||||
|
volatile struct grub_ohci_td *link_td; /* pointer to next free/chained TD
|
||||||
|
* pointer as uint32 */
|
||||||
grub_uint32_t prev_td_phys; /* we need it to find previous TD
|
grub_uint32_t prev_td_phys; /* we need it to find previous TD
|
||||||
* physical address in CPU endian */
|
* physical address in CPU endian */
|
||||||
grub_uint32_t link_td; /* pointer to next free/chained TD
|
|
||||||
* pointer as uint32 */
|
|
||||||
grub_uint32_t tr_index; /* index of TD in transfer */
|
grub_uint32_t tr_index; /* index of TD in transfer */
|
||||||
grub_uint8_t pad[4]; /* padding to 32 bytes */
|
grub_uint8_t pad[8 - sizeof (volatile struct grub_ohci_td *)]; /* padding to 32 bytes */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/* OHCI Endpoint Descriptor. */
|
/* OHCI Endpoint Descriptor. */
|
||||||
|
@ -334,7 +334,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
||||||
/* Preset free TDs chain in TDs */
|
/* Preset free TDs chain in TDs */
|
||||||
grub_memset ((void*)o->td, 0, sizeof(struct grub_ohci_td) * GRUB_OHCI_TDS);
|
grub_memset ((void*)o->td, 0, sizeof(struct grub_ohci_td) * GRUB_OHCI_TDS);
|
||||||
for (j=0; j < (GRUB_OHCI_TDS-1); j++)
|
for (j=0; j < (GRUB_OHCI_TDS-1); j++)
|
||||||
o->td[j].link_td = (grub_uint32_t)&o->td[j+1];
|
o->td[j].link_td = &o->td[j+1];
|
||||||
|
|
||||||
grub_dprintf ("ohci", "TDs: chunk=%p, virt=%p, phys=0x%02x\n",
|
grub_dprintf ("ohci", "TDs: chunk=%p, virt=%p, phys=0x%02x\n",
|
||||||
o->td_chunk, o->td, o->td_addr);
|
o->td_chunk, o->td, o->td_addr);
|
||||||
|
@ -561,7 +561,7 @@ static void
|
||||||
grub_ohci_free_td (struct grub_ohci *o, grub_ohci_td_t td)
|
grub_ohci_free_td (struct grub_ohci *o, grub_ohci_td_t td)
|
||||||
{
|
{
|
||||||
grub_memset ( (void*)td, 0, sizeof(struct grub_ohci_td) );
|
grub_memset ( (void*)td, 0, sizeof(struct grub_ohci_td) );
|
||||||
td->link_td = (grub_uint32_t) o->td_free; /* Cahin new free TD & rest */
|
td->link_td = o->td_free; /* Cahin new free TD & rest */
|
||||||
o->td_free = td; /* Change address of first free TD */
|
o->td_free = td; /* Change address of first free TD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,8 +604,8 @@ grub_ohci_transaction (grub_ohci_td_t td,
|
||||||
grub_uint32_t buffer;
|
grub_uint32_t buffer;
|
||||||
grub_uint32_t buffer_end;
|
grub_uint32_t buffer_end;
|
||||||
|
|
||||||
grub_dprintf ("ohci", "OHCI transaction td=%p type=%d, toggle=%d, size=%d\n",
|
grub_dprintf ("ohci", "OHCI transaction td=%p type=%d, toggle=%d, size=%lu\n",
|
||||||
td, type, toggle, size);
|
td, type, toggle, (unsigned long) size);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -781,7 +781,7 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chain TDs */
|
/* Chain TDs */
|
||||||
td_current_virt->link_td = (grub_uint32_t) td_next_virt;
|
td_current_virt->link_td = td_next_virt;
|
||||||
td_current_virt->next_td = grub_cpu_to_le32 (
|
td_current_virt->next_td = grub_cpu_to_le32 (
|
||||||
grub_ohci_td_virt2phys (o,
|
grub_ohci_td_virt2phys (o,
|
||||||
td_next_virt) );
|
td_next_virt) );
|
||||||
|
@ -1406,6 +1406,8 @@ static struct grub_usb_controller_dev usb_controller =
|
||||||
|
|
||||||
GRUB_MOD_INIT(ohci)
|
GRUB_MOD_INIT(ohci)
|
||||||
{
|
{
|
||||||
|
COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_td) == 32);
|
||||||
|
COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_ed) == 16);
|
||||||
grub_ohci_inithw ();
|
grub_ohci_inithw ();
|
||||||
grub_usb_controller_dev_register (&usb_controller);
|
grub_usb_controller_dev_register (&usb_controller);
|
||||||
grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw,
|
grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw,
|
||||||
|
|
|
@ -228,7 +228,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
|
||||||
/* Link all Transfer Descriptors in a list of available Transfer
|
/* Link all Transfer Descriptors in a list of available Transfer
|
||||||
Descriptors. */
|
Descriptors. */
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1];
|
u->td[i].linkptr = (grub_uint32_t) (grub_addr_t) &u->td[i + 1];
|
||||||
u->td[255 - 1].linkptr = 0;
|
u->td[255 - 1].linkptr = 0;
|
||||||
u->tdfree = u->td;
|
u->tdfree = u->td;
|
||||||
|
|
||||||
|
@ -238,20 +238,20 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
|
||||||
/* Setup the frame list pointers. Since no isochronous transfers
|
/* Setup the frame list pointers. Since no isochronous transfers
|
||||||
are and will be supported, they all point to the (same!) queue
|
are and will be supported, they all point to the (same!) queue
|
||||||
head. */
|
head. */
|
||||||
fp = (grub_uint32_t) u->qh & (~15);
|
fp = (grub_uint32_t) (grub_addr_t) u->qh & (~15);
|
||||||
/* Mark this as a queue head. */
|
/* Mark this as a queue head. */
|
||||||
fp |= 2;
|
fp |= 2;
|
||||||
for (i = 0; i < 1024; i++)
|
for (i = 0; i < 1024; i++)
|
||||||
u->framelist[i] = fp;
|
u->framelist[i] = fp;
|
||||||
/* Program the framelist address into the UHCI controller. */
|
/* Program the framelist address into the UHCI controller. */
|
||||||
grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
|
grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
|
||||||
(grub_uint32_t) u->framelist);
|
(grub_uint32_t) (grub_addr_t) u->framelist);
|
||||||
|
|
||||||
/* Make the Queue Heads point to each other. */
|
/* Make the Queue Heads point to each other. */
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
/* Point to the next QH. */
|
/* Point to the next QH. */
|
||||||
u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15);
|
u->qh[i].linkptr = (grub_uint32_t) (grub_addr_t) (&u->qh[i + 1]) & (~15);
|
||||||
|
|
||||||
/* This is a QH. */
|
/* This is a QH. */
|
||||||
u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
|
u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
|
||||||
|
@ -319,7 +319,7 @@ grub_alloc_td (struct grub_uhci *u)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret = u->tdfree;
|
ret = u->tdfree;
|
||||||
u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr;
|
u->tdfree = (grub_uhci_td_t) (grub_addr_t) u->tdfree->linkptr;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ grub_alloc_td (struct grub_uhci *u)
|
||||||
static void
|
static void
|
||||||
grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
|
grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
|
||||||
{
|
{
|
||||||
td->linkptr = (grub_uint32_t) u->tdfree;
|
td->linkptr = (grub_uint32_t) (grub_addr_t) u->tdfree;
|
||||||
u->tdfree = td;
|
u->tdfree = td;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td,
|
||||||
|
|
||||||
/* Unlink the queue. */
|
/* Unlink the queue. */
|
||||||
tdprev = td;
|
tdprev = td;
|
||||||
td = (grub_uhci_td_t) td->linkptr2;
|
td = (grub_uhci_td_t) (grub_addr_t) td->linkptr2;
|
||||||
|
|
||||||
/* Free the TD. */
|
/* Free the TD. */
|
||||||
grub_free_td (u, tdprev);
|
grub_free_td (u, tdprev);
|
||||||
|
@ -413,8 +413,8 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_dprintf ("uhci",
|
grub_dprintf ("uhci",
|
||||||
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n",
|
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%lu data=0x%x td=%p\n",
|
||||||
endp, type, addr, toggle, size, data, td);
|
endp, type, addr, toggle, (unsigned long) size, data, td);
|
||||||
|
|
||||||
/* Don't point to any TD, just terminate. */
|
/* Don't point to any TD, just terminate. */
|
||||||
td->linkptr = 1;
|
td->linkptr = 1;
|
||||||
|
@ -484,8 +484,8 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
||||||
td_first = td;
|
td_first = td;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
td_prev->linkptr2 = (grub_uint32_t) td;
|
td_prev->linkptr2 = (grub_uint32_t) (grub_addr_t) td;
|
||||||
td_prev->linkptr = (grub_uint32_t) td;
|
td_prev->linkptr = (grub_uint32_t) (grub_addr_t) td;
|
||||||
td_prev->linkptr |= 4;
|
td_prev->linkptr |= 4;
|
||||||
}
|
}
|
||||||
td_prev = td;
|
td_prev = td;
|
||||||
|
@ -497,7 +497,7 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
||||||
|
|
||||||
/* Link it into the queue and terminate. Now the transaction can
|
/* Link it into the queue and terminate. Now the transaction can
|
||||||
take place. */
|
take place. */
|
||||||
qh->elinkptr = (grub_uint32_t) td_first;
|
qh->elinkptr = (grub_uint32_t) (grub_addr_t) td_first;
|
||||||
|
|
||||||
grub_dprintf ("uhci", "initiate transaction\n");
|
grub_dprintf ("uhci", "initiate transaction\n");
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
||||||
{
|
{
|
||||||
grub_uhci_td_t errtd;
|
grub_uhci_td_t errtd;
|
||||||
|
|
||||||
errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f);
|
errtd = (grub_uhci_td_t) (grub_addr_t) (qh->elinkptr & ~0x0f);
|
||||||
|
|
||||||
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
||||||
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
||||||
|
|
|
@ -54,8 +54,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
||||||
grub_memcpy ((char *) data, data_in, size);
|
grub_memcpy ((char *) data, data_in, size);
|
||||||
|
|
||||||
grub_dprintf ("usb",
|
grub_dprintf ("usb",
|
||||||
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
|
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n",
|
||||||
reqtype, request, value, index, size);
|
reqtype, request, value, index, (unsigned long)size);
|
||||||
|
|
||||||
/* Create a transfer. */
|
/* Create a transfer. */
|
||||||
transfer = grub_malloc (sizeof (*transfer));
|
transfer = grub_malloc (sizeof (*transfer));
|
||||||
|
@ -179,7 +179,8 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
||||||
struct grub_pci_dma_chunk *data_chunk;
|
struct grub_pci_dma_chunk *data_chunk;
|
||||||
grub_size_t size = size0;
|
grub_size_t size = size0;
|
||||||
|
|
||||||
grub_dprintf ("usb", "bulk: size=0x%02x type=%d\n", size, type);
|
grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size,
|
||||||
|
type);
|
||||||
|
|
||||||
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
||||||
data_chunk = grub_memalign_dma32 (128, size);
|
data_chunk = grub_memalign_dma32 (128, size);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
|
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
|
@ -28,6 +29,69 @@ static const struct grub_arg_option options[] =
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void __attribute__ ((noreturn))
|
||||||
|
stop (void)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
asm volatile ("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Halt the system, using APM if possible. If NO_APM is true, don't use
|
||||||
|
* APM even if it is available.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
grub_halt (int no_apm)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
if (no_apm)
|
||||||
|
stop ();
|
||||||
|
|
||||||
|
/* detect APM */
|
||||||
|
regs.eax = 0x5300;
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
|
||||||
|
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||||
|
stop ();
|
||||||
|
|
||||||
|
/* disconnect APM first */
|
||||||
|
regs.eax = 0x5304;
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
|
||||||
|
/* connect APM */
|
||||||
|
regs.eax = 0x5301;
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||||
|
stop ();
|
||||||
|
|
||||||
|
/* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
|
||||||
|
regs.eax = 0x530E;
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.ecx = 0x0101;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||||
|
stop ();
|
||||||
|
|
||||||
|
/* set the power state to off */
|
||||||
|
regs.eax = 0x5307;
|
||||||
|
regs.ebx = 1;
|
||||||
|
regs.ecx = 3;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
|
||||||
|
/* shouldn't reach here */
|
||||||
|
stop ();
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_halt (grub_extcmd_context_t ctxt,
|
grub_cmd_halt (grub_extcmd_context_t ctxt,
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <grub/machine/biosdisk.h>
|
#include <grub/machine/biosdisk.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
@ -28,6 +29,219 @@
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
|
|
||||||
static int cd_drive = 0;
|
static int cd_drive = 0;
|
||||||
|
static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap);
|
||||||
|
|
||||||
|
static int grub_biosdisk_get_num_floppies (void)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
/* reset the disk system first */
|
||||||
|
regs.eax = 0;
|
||||||
|
regs.edx = 0;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
|
||||||
|
for (drive = 0; drive < 2; drive++)
|
||||||
|
{
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT | GRUB_CPU_INT_FLAGS_CARRY;
|
||||||
|
regs.edx = drive;
|
||||||
|
|
||||||
|
/* call GET DISK TYPE */
|
||||||
|
regs.eax = 0x1500;
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* check if this drive exists */
|
||||||
|
if (!(regs.eax & 0x300))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
|
||||||
|
* is passed for disk address packet. If an error occurs, return
|
||||||
|
* non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
regs.eax = ah << 8;
|
||||||
|
/* compute the address of disk_address_packet */
|
||||||
|
regs.ds = (((grub_addr_t) dap) & 0xffff0000) >> 4;
|
||||||
|
regs.esi = (((grub_addr_t) dap) & 0xffff);
|
||||||
|
regs.edx = drive;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
return (regs.eax >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
|
||||||
|
* NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
|
||||||
|
* return non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
|
||||||
|
int soff, int nsec, int segment)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
/* Try 3 times. */
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
/* set up CHS information */
|
||||||
|
/* set %ch to low eight bits of cylinder */
|
||||||
|
regs.ecx = (coff << 8) & 0xff00;
|
||||||
|
/* set bits 6-7 of %cl to high two bits of cylinder */
|
||||||
|
regs.ecx |= (coff >> 2) & 0xc0;
|
||||||
|
/* set bits 0-5 of %cl to sector */
|
||||||
|
regs.ecx |= soff & 0x3f;
|
||||||
|
|
||||||
|
/* set %dh to head and %dl to drive */
|
||||||
|
regs.edx = (drive & 0xff) | ((hoff << 8) & 0xff00);
|
||||||
|
/* set %ah to AH */
|
||||||
|
regs.eax = (ah << 8) & 0xff00;
|
||||||
|
/* set %al to NSEC */
|
||||||
|
regs.eax |= nsec & 0xff;
|
||||||
|
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.es = segment;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
/* check if successful */
|
||||||
|
if (!(regs.flags & GRUB_CPU_INT_FLAGS_CARRY))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* save return value */
|
||||||
|
ret = regs.eax >> 8;
|
||||||
|
|
||||||
|
/* if fail, reset the disk system */
|
||||||
|
regs.eax = 0;
|
||||||
|
regs.edx = (drive & 0xff);
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if LBA is supported for DRIVE. If it is supported, then return
|
||||||
|
* the major version of extensions, otherwise zero.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_biosdisk_check_int13_extensions (int drive)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.edx = drive & 0xff;
|
||||||
|
regs.eax = 0x4100;
|
||||||
|
regs.ebx = 0x55aa;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
|
||||||
|
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((regs.ebx & 0xffff) != 0xaa55)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check if AH=0x42 is supported */
|
||||||
|
if (!(regs.ecx & 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (regs.eax >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
|
||||||
|
* error occurs, then return non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_biosdisk_get_diskinfo_standard (int drive,
|
||||||
|
unsigned long *cylinders,
|
||||||
|
unsigned long *heads,
|
||||||
|
unsigned long *sectors)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.eax = 0x0800;
|
||||||
|
regs.edx = drive & 0xff;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
|
||||||
|
/* Check if unsuccessful. Ignore return value if carry isn't set to
|
||||||
|
workaround some buggy BIOSes. */
|
||||||
|
if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0))
|
||||||
|
return (regs.eax & 0xff00) >> 8;
|
||||||
|
|
||||||
|
/* bogus BIOSes may not return an error number */
|
||||||
|
/* 0 sectors means no disk */
|
||||||
|
if (!(regs.ecx & 0x3f))
|
||||||
|
/* XXX 0x60 is one of the unused error numbers */
|
||||||
|
return 0x60;
|
||||||
|
|
||||||
|
/* the number of heads is counted from zero */
|
||||||
|
*heads = ((regs.edx >> 8) & 0xff) + 1;
|
||||||
|
*cylinders = (((regs.ecx >> 8) & 0xff) | ((regs.ecx << 2) & 0x0300)) + 1;
|
||||||
|
*sectors = regs.ecx & 0x3f;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_biosdisk_get_diskinfo_real (int drive, void *drp, grub_uint16_t ax)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.eax = ax;
|
||||||
|
|
||||||
|
/* compute the address of drive parameters */
|
||||||
|
regs.esi = ((grub_addr_t) drp) & 0xf;
|
||||||
|
regs.ds = ((grub_addr_t) drp) >> 4;
|
||||||
|
regs.edx = drive & 0xff;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x13, ®s);
|
||||||
|
|
||||||
|
/* Check if unsuccessful. Ignore return value if carry isn't set to
|
||||||
|
workaround some buggy BIOSes. */
|
||||||
|
if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0))
|
||||||
|
return (regs.eax & 0xff00) >> 8;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the cdrom information of DRIVE in CDRP. If an error occurs,
|
||||||
|
* then return non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
|
||||||
|
{
|
||||||
|
return grub_biosdisk_get_diskinfo_real (drive, cdrp, 0x4b01);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the geometry of DRIVE in a drive parameters, DRP. If an error
|
||||||
|
* occurs, then return non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
|
||||||
|
{
|
||||||
|
return grub_biosdisk_get_diskinfo_real (drive, drp, 0x4800);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_biosdisk_get_drive (const char *name)
|
grub_biosdisk_get_drive (const char *name)
|
||||||
|
@ -107,7 +321,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
if (drive < 0)
|
if (drive < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
|
disk->has_partitions = 1;
|
||||||
disk->id = drive;
|
disk->id = drive;
|
||||||
|
|
||||||
data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
|
data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
|
||||||
|
@ -123,7 +337,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
/* TODO: get the correct size. */
|
/* TODO: get the correct size. */
|
||||||
total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||||
}
|
}
|
||||||
else if (drive & 0x80)
|
else
|
||||||
{
|
{
|
||||||
/* HDD */
|
/* HDD */
|
||||||
int version;
|
int version;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/efiemu/efiemu.h>
|
#include <grub/efiemu/efiemu.h>
|
||||||
#include <grub/machine/efiemu.h>
|
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
|
|
||||||
#define cpuid(num,a,b,c,d) \
|
#define cpuid(num,a,b,c,d) \
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* Register SMBIOS and ACPI tables. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
@ -16,12 +17,14 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GRUB_LOADER_MACHINE_HEADER
|
#include <grub/err.h>
|
||||||
#define GRUB_LOADER_MACHINE_HEADER 1
|
#include <grub/efiemu/efiemu.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/acpi.h>
|
||||||
|
|
||||||
/* The symbol shared between the normal mode and rescue mode
|
grub_err_t
|
||||||
loader. */
|
grub_machine_efiemu_init_tables (void)
|
||||||
void grub_rescue_cmd_linux (int argc, char *argv[]);
|
{
|
||||||
void grub_rescue_cmd_initrd (int argc, char *argv[]);
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
#endif /* ! GRUB_LOADER_MACHINE_HEADER */
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/efiemu/efiemu.h>
|
#include <grub/efiemu/efiemu.h>
|
||||||
#include <grub/machine/efiemu.h>
|
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/acpi.h>
|
#include <grub/acpi.h>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/efiemu/efiemu.h>
|
#include <grub/efiemu/efiemu.h>
|
||||||
#include <grub/cpu/efiemu.h>
|
#include <grub/cpu/efiemu.h>
|
||||||
#include <grub/machine/efiemu.h>
|
|
||||||
#include <grub/elf.h>
|
#include <grub/elf.h>
|
||||||
|
|
||||||
/* ELF symbols and their values */
|
/* ELF symbols and their values */
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/efiemu/efiemu.h>
|
#include <grub/efiemu/efiemu.h>
|
||||||
#include <grub/machine/efiemu.h>
|
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
@ -183,22 +182,6 @@ grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
|
|
||||||
__attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
/* Nothing to do here yet */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
grub_efiemu_finish_boot_services (void)
|
|
||||||
{
|
|
||||||
/* Nothing to do here yet */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the runtime from the file FILENAME. */
|
/* Load the runtime from the file FILENAME. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_efiemu_load_file (const char *filename)
|
grub_efiemu_load_file (const char *filename)
|
||||||
|
|
|
@ -323,6 +323,25 @@ grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_efiemu_finish_boot_services (grub_efi_uintn_t *memory_map_size,
|
||||||
|
grub_efi_memory_descriptor_t *memory_map,
|
||||||
|
grub_efi_uintn_t *map_key,
|
||||||
|
grub_efi_uintn_t *descriptor_size,
|
||||||
|
grub_efi_uint32_t *descriptor_version)
|
||||||
|
{
|
||||||
|
int val = grub_efiemu_get_memory_map (memory_map_size,
|
||||||
|
memory_map, map_key,
|
||||||
|
descriptor_size,
|
||||||
|
descriptor_version);
|
||||||
|
if (val == 1)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
if (val == -1)
|
||||||
|
return grub_errno;
|
||||||
|
return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Free everything */
|
/* Free everything */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_efiemu_mm_unload (void)
|
grub_efiemu_mm_unload (void)
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
gcc -c -m32 -DELF32 -o efiemu32.o ./efiemu.c -Wall -Werror -nostdlib -O2 -I. -I../../include
|
|
||||||
gcc -c -m64 -DELF64 -o efiemu64_c.o ./efiemu.c -Wall -Werror -mcmodel=large -O2 -I. -I../../include
|
|
||||||
gcc -c -m64 -DELF64 -o efiemu64_s.o ./efiemu.S -Wall -Werror -mcmodel=large -O2 -I. -I../../include
|
|
||||||
ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
|
||||||
#include <grub/machine/pxe.h>
|
#include <grub/machine/pxe.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
|
|
||||||
#define SEGMENT(x) ((x) >> 4)
|
#define SEGMENT(x) ((x) >> 4)
|
||||||
|
@ -40,7 +41,7 @@ struct grub_pxe_disk_data
|
||||||
grub_uint32_t gateway_ip;
|
grub_uint32_t gateway_ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_pxenv *grub_pxe_pxenv;
|
struct grub_pxe_bangpxe *grub_pxe_pxenv;
|
||||||
static grub_uint32_t grub_pxe_your_ip;
|
static grub_uint32_t grub_pxe_your_ip;
|
||||||
static grub_uint32_t grub_pxe_default_server_ip;
|
static grub_uint32_t grub_pxe_default_server_ip;
|
||||||
static grub_uint32_t grub_pxe_default_gateway_ip;
|
static grub_uint32_t grub_pxe_default_gateway_ip;
|
||||||
|
@ -55,6 +56,51 @@ struct grub_pxe_data
|
||||||
char filename[0];
|
char filename[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static grub_uint32_t pxe_rm_entry = 0;
|
||||||
|
|
||||||
|
static struct grub_pxe_bangpxe *
|
||||||
|
grub_pxe_scan (void)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
struct grub_pxenv *pxenv;
|
||||||
|
struct grub_pxe_bangpxe *bangpxe;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
|
||||||
|
regs.ebx = 0;
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.eax = 0x5650;
|
||||||
|
regs.es = 0;
|
||||||
|
|
||||||
|
grub_bios_interrupt (0x1a, ®s);
|
||||||
|
|
||||||
|
if ((regs.eax & 0xffff) != 0x564e)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff));
|
||||||
|
if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE,
|
||||||
|
sizeof (pxenv->signature))
|
||||||
|
!= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pxenv->version < 0x201)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4)
|
||||||
|
+ (pxenv->pxe_ptr & 0xffff));
|
||||||
|
|
||||||
|
if (!bangpxe)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE,
|
||||||
|
sizeof (bangpxe->signature)) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pxe_rm_entry = bangpxe->rm_entry;
|
||||||
|
|
||||||
|
return bangpxe;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_pxe_iterate (int (*hook) (const char *name))
|
grub_pxe_iterate (int (*hook) (const char *name))
|
||||||
{
|
{
|
||||||
|
@ -202,14 +248,14 @@ grub_pxefs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
if (curr_file != 0)
|
if (curr_file != 0)
|
||||||
{
|
{
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
|
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2, pxe_rm_entry);
|
||||||
curr_file = 0;
|
curr_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.c1.server_ip = disk_data->server_ip;
|
c.c1.server_ip = disk_data->server_ip;
|
||||||
c.c1.gateway_ip = disk_data->gateway_ip;
|
c.c1.gateway_ip = disk_data->gateway_ip;
|
||||||
grub_strcpy ((char *)&c.c1.filename[0], name);
|
grub_strcpy ((char *)&c.c1.filename[0], name);
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
|
grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry);
|
||||||
if (c.c1.status)
|
if (c.c1.status)
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
|
||||||
|
|
||||||
|
@ -217,7 +263,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
||||||
c.c2.packet_size = grub_pxe_blksize;
|
c.c2.packet_size = grub_pxe_blksize;
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
|
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2, pxe_rm_entry);
|
||||||
if (c.c2.status)
|
if (c.c2.status)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "open fails");
|
return grub_error (GRUB_ERR_BAD_FS, "open fails");
|
||||||
|
|
||||||
|
@ -275,14 +321,14 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
struct grub_pxenv_tftp_open o;
|
struct grub_pxenv_tftp_open o;
|
||||||
|
|
||||||
if (curr_file != 0)
|
if (curr_file != 0)
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
|
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry);
|
||||||
|
|
||||||
o.server_ip = disk_data->server_ip;
|
o.server_ip = disk_data->server_ip;
|
||||||
o.gateway_ip = disk_data->gateway_ip;
|
o.gateway_ip = disk_data->gateway_ip;
|
||||||
grub_strcpy ((char *)&o.filename[0], data->filename);
|
grub_strcpy ((char *)&o.filename[0], data->filename);
|
||||||
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
||||||
o.packet_size = grub_pxe_blksize;
|
o.packet_size = data->block_size;
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
|
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry);
|
||||||
if (o.status)
|
if (o.status)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "open fails");
|
grub_error (GRUB_ERR_BAD_FS, "open fails");
|
||||||
|
@ -297,7 +343,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
while (pn >= data->packet_number)
|
while (pn >= data->packet_number)
|
||||||
{
|
{
|
||||||
c.buffer_size = data->block_size;
|
c.buffer_size = data->block_size;
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
|
grub_pxe_call (GRUB_PXENV_TFTP_READ, &c, pxe_rm_entry);
|
||||||
if (c.status)
|
if (c.status)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "read fails");
|
grub_error (GRUB_ERR_BAD_FS, "read fails");
|
||||||
|
@ -318,7 +364,7 @@ grub_pxefs_close (grub_file_t file)
|
||||||
|
|
||||||
if (curr_file == file)
|
if (curr_file == file)
|
||||||
{
|
{
|
||||||
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
|
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c, pxe_rm_entry);
|
||||||
curr_file = 0;
|
curr_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +489,7 @@ parse_dhcp_vendor (void *vend, int limit)
|
||||||
static void
|
static void
|
||||||
grub_pxe_detect (void)
|
grub_pxe_detect (void)
|
||||||
{
|
{
|
||||||
struct grub_pxenv *pxenv;
|
struct grub_pxe_bangpxe *pxenv;
|
||||||
struct grub_pxenv_get_cached_info ci;
|
struct grub_pxenv_get_cached_info ci;
|
||||||
struct grub_pxenv_boot_player *bp;
|
struct grub_pxenv_boot_player *bp;
|
||||||
|
|
||||||
|
@ -454,7 +500,7 @@ grub_pxe_detect (void)
|
||||||
ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
|
ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
|
||||||
ci.buffer = 0;
|
ci.buffer = 0;
|
||||||
ci.buffer_size = 0;
|
ci.buffer_size = 0;
|
||||||
grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
|
grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
|
||||||
if (ci.status)
|
if (ci.status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -718,10 +718,13 @@ grub_nilfs2_load_sb (struct grub_nilfs2_data *data)
|
||||||
grub_uint64_t partition_size;
|
grub_uint64_t partition_size;
|
||||||
int valid[2];
|
int valid[2];
|
||||||
int swp = 0;
|
int swp = 0;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
/* Read first super block. */
|
/* Read first super block. */
|
||||||
grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0,
|
err = grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0,
|
||||||
sizeof (struct grub_nilfs2_super_block), &data->sblock);
|
sizeof (struct grub_nilfs2_super_block), &data->sblock);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
/* Make sure if 1st super block is valid. */
|
/* Make sure if 1st super block is valid. */
|
||||||
valid[0] = grub_nilfs2_valid_sb (&data->sblock);
|
valid[0] = grub_nilfs2_valid_sb (&data->sblock);
|
||||||
|
|
||||||
|
@ -729,17 +732,21 @@ grub_nilfs2_load_sb (struct grub_nilfs2_data *data)
|
||||||
if (partition_size != GRUB_DISK_SIZE_UNKNOWN)
|
if (partition_size != GRUB_DISK_SIZE_UNKNOWN)
|
||||||
{
|
{
|
||||||
/* Read second super block. */
|
/* Read second super block. */
|
||||||
grub_disk_read (disk, NILFS_2ND_SUPER_BLOCK (partition_size), 0,
|
err = grub_disk_read (disk, NILFS_2ND_SUPER_BLOCK (partition_size), 0,
|
||||||
sizeof (struct grub_nilfs2_super_block), &sb2);
|
sizeof (struct grub_nilfs2_super_block), &sb2);
|
||||||
/* Make sure if 2nd super block is valid. */
|
if (err)
|
||||||
valid[1] = grub_nilfs2_valid_sb (&sb2);
|
{
|
||||||
|
valid[1] = 0;
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Make sure if 2nd super block is valid. */
|
||||||
|
valid[1] = grub_nilfs2_valid_sb (&sb2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* 2nd super block may not exist, so it's invalid. */
|
/* 2nd super block may not exist, so it's invalid. */
|
||||||
valid[1] = 0;
|
valid[1] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!valid[0] && !valid[1])
|
if (!valid[0] && !valid[1])
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
|
return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
|
||||||
|
|
||||||
|
@ -752,8 +759,7 @@ grub_nilfs2_load_sb (struct grub_nilfs2_data *data)
|
||||||
grub_memcpy (&data->sblock, &sb2,
|
grub_memcpy (&data->sblock, &sb2,
|
||||||
sizeof (struct grub_nilfs2_super_block));
|
sizeof (struct grub_nilfs2_super_block));
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
return grub_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_nilfs2_data *
|
static struct grub_nilfs2_data *
|
||||||
|
|
|
@ -682,20 +682,3 @@ grub_dl_unload_unneeded (void)
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unload all modules. */
|
|
||||||
void
|
|
||||||
grub_dl_unload_all (void)
|
|
||||||
{
|
|
||||||
while (grub_dl_head)
|
|
||||||
{
|
|
||||||
grub_dl_t p;
|
|
||||||
|
|
||||||
grub_dl_unload_unneeded ();
|
|
||||||
|
|
||||||
/* Force to decrement the ref count. This will purge pre-loaded
|
|
||||||
modules and manually inserted modules. */
|
|
||||||
for (p = grub_dl_head; p; p = p->next)
|
|
||||||
p->ref_count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -174,26 +174,6 @@ grub_reboot (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
|
||||||
grub_halt (void)
|
|
||||||
{
|
|
||||||
grub_efi_fini ();
|
|
||||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
|
||||||
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
|
||||||
for (;;) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
|
|
||||||
{
|
|
||||||
grub_efi_boot_services_t *b;
|
|
||||||
grub_efi_status_t status;
|
|
||||||
|
|
||||||
b = grub_efi_system_table->boot_services;
|
|
||||||
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
|
|
||||||
return status == GRUB_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
|
grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
|
||||||
grub_efi_uintn_t descriptor_size,
|
grub_efi_uintn_t descriptor_size,
|
||||||
|
@ -760,26 +740,3 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||||
dp = (grub_efi_device_path_t *) ((char *) dp + len);
|
dp = (grub_efi_device_path_t *) ((char *) dp + len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
grub_efi_finish_boot_services (void)
|
|
||||||
{
|
|
||||||
grub_efi_uintn_t mmap_size = 0;
|
|
||||||
grub_efi_uintn_t map_key;
|
|
||||||
grub_efi_uintn_t desc_size;
|
|
||||||
grub_efi_uint32_t desc_version;
|
|
||||||
void *mmap_buf = 0;
|
|
||||||
|
|
||||||
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
|
|
||||||
&desc_size, &desc_version) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
mmap_buf = grub_malloc (mmap_size);
|
|
||||||
|
|
||||||
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
|
|
||||||
&desc_size, &desc_version) <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return grub_efi_exit_boot_services (map_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,12 @@ static struct allocated_page *allocated_pages = 0;
|
||||||
#define MIN_HEAP_SIZE 0x100000
|
#define MIN_HEAP_SIZE 0x100000
|
||||||
#define MAX_HEAP_SIZE (1600 * 0x100000)
|
#define MAX_HEAP_SIZE (1600 * 0x100000)
|
||||||
|
|
||||||
|
static void *finish_mmap_buf = 0;
|
||||||
|
static grub_efi_uintn_t finish_mmap_size = 0;
|
||||||
|
static grub_efi_uintn_t finish_key = 0;
|
||||||
|
static grub_efi_uintn_t finish_desc_size;
|
||||||
|
static grub_efi_uint32_t finish_desc_version;
|
||||||
|
int grub_efi_is_finished = 0;
|
||||||
|
|
||||||
/* Allocate pages. Return the pointer to the first of allocated pages. */
|
/* Allocate pages. Return the pointer to the first of allocated pages. */
|
||||||
void *
|
void *
|
||||||
|
@ -140,6 +146,51 @@ grub_efi_free_pages (grub_efi_physical_address_t address,
|
||||||
efi_call_2 (b->free_pages, address, pages);
|
efi_call_2 (b->free_pages, address, pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
|
||||||
|
grub_efi_uintn_t *map_key,
|
||||||
|
grub_efi_uintn_t *efi_desc_size,
|
||||||
|
grub_efi_uint32_t *efi_desc_version)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
|
||||||
|
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
|
||||||
|
&finish_desc_size, &finish_desc_version) < 0)
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||||
|
|
||||||
|
if (outbuf && *outbuf_size < finish_mmap_size)
|
||||||
|
return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
|
||||||
|
|
||||||
|
finish_mmap_buf = grub_malloc (finish_mmap_size);
|
||||||
|
if (!finish_mmap_buf)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
|
||||||
|
&finish_desc_size, &finish_desc_version) <= 0)
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
|
||||||
|
finish_key);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
|
||||||
|
|
||||||
|
grub_efi_is_finished = 1;
|
||||||
|
if (outbuf_size)
|
||||||
|
*outbuf_size = finish_mmap_size;
|
||||||
|
if (outbuf)
|
||||||
|
grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
|
||||||
|
if (map_key)
|
||||||
|
*map_key = finish_key;
|
||||||
|
if (efi_desc_size)
|
||||||
|
*efi_desc_size = finish_desc_size;
|
||||||
|
if (efi_desc_version)
|
||||||
|
*efi_desc_version = finish_desc_version;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
|
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
|
||||||
return 0 if partial, or return -1 if an error occurs. */
|
return 0 if partial, or return -1 if an error occurs. */
|
||||||
int
|
int
|
||||||
|
@ -154,6 +205,29 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
|
||||||
grub_efi_uintn_t key;
|
grub_efi_uintn_t key;
|
||||||
grub_efi_uint32_t version;
|
grub_efi_uint32_t version;
|
||||||
|
|
||||||
|
if (grub_efi_is_finished)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
if (*memory_map_size < finish_mmap_size)
|
||||||
|
{
|
||||||
|
grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
*memory_map_size = finish_mmap_size;
|
||||||
|
if (map_key)
|
||||||
|
*map_key = finish_key;
|
||||||
|
if (descriptor_size)
|
||||||
|
*descriptor_size = finish_desc_size;
|
||||||
|
if (descriptor_version)
|
||||||
|
*descriptor_version = finish_desc_version;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow some parameters to be missing. */
|
/* Allow some parameters to be missing. */
|
||||||
if (! map_key)
|
if (! map_key)
|
||||||
map_key = &key;
|
map_key = &key;
|
||||||
|
|
|
@ -140,7 +140,7 @@ grub_elf32_load_phdrs (grub_elf_t elf)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
grub_elf32_phdr_iterate (grub_elf_t elf,
|
grub_elf32_phdr_iterate (grub_elf_t elf,
|
||||||
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
|
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
|
||||||
void *hook_arg)
|
void *hook_arg)
|
||||||
|
@ -326,7 +326,7 @@ grub_elf64_load_phdrs (grub_elf_t elf)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
grub_elf64_phdr_iterate (grub_elf_t elf,
|
grub_elf64_phdr_iterate (grub_elf_t elf,
|
||||||
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
|
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
|
||||||
void *hook_arg)
|
void *hook_arg)
|
||||||
|
|
|
@ -66,16 +66,6 @@ grub_reboot (void)
|
||||||
longjmp (main_env, 1);
|
longjmp (main_env, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
grub_halt (
|
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
|
||||||
int no_apm __attribute__ ((unused))
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
grub_reboot ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_init (void)
|
grub_machine_init (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <grub/kernel.h>
|
#include <grub/kernel.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/machine/time.h>
|
#include <grub/machine/time.h>
|
||||||
#include <grub/machine/init.h>
|
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/console.h>
|
#include <grub/machine/console.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
|
@ -32,33 +31,21 @@
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/cpu/io.h>
|
#include <grub/cpu/io.h>
|
||||||
|
#include <grub/cpu/floppy.h>
|
||||||
#include <grub/cpu/tsc.h>
|
#include <grub/cpu/tsc.h>
|
||||||
#ifdef GRUB_MACHINE_QEMU
|
#ifdef GRUB_MACHINE_QEMU
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2
|
|
||||||
|
|
||||||
extern char _start[];
|
extern char _start[];
|
||||||
extern char _end[];
|
extern char _end[];
|
||||||
|
|
||||||
grub_addr_t grub_os_area_addr;
|
|
||||||
grub_size_t grub_os_area_size;
|
|
||||||
|
|
||||||
grub_uint32_t
|
grub_uint32_t
|
||||||
grub_get_rtc (void)
|
grub_get_rtc (void)
|
||||||
{
|
{
|
||||||
grub_fatal ("grub_get_rtc() is not implemented.\n");
|
grub_fatal ("grub_get_rtc() is not implemented.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the floppy drive from spinning, so that other software is
|
|
||||||
jumped to with a known state. */
|
|
||||||
void
|
|
||||||
grub_stop_floppy (void)
|
|
||||||
{
|
|
||||||
grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_exit (void)
|
grub_exit (void)
|
||||||
{
|
{
|
||||||
|
@ -103,20 +90,7 @@ grub_machine_init (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr == GRUB_MEMORY_MACHINE_UPPER_START
|
grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
|
||||||
|| (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
|
|
||||||
&& addr <= GRUB_MEMORY_MACHINE_UPPER_START
|
|
||||||
&& (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
|
|
||||||
{
|
|
||||||
grub_size_t quarter = size >> 2;
|
|
||||||
|
|
||||||
grub_os_area_addr = addr;
|
|
||||||
grub_os_area_size = size - quarter;
|
|
||||||
grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
|
|
||||||
quarter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_DATA_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
|
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
|
||||||
|
@ -85,7 +85,3 @@ codestart:
|
||||||
*/
|
*/
|
||||||
#include "../realmode.S"
|
#include "../realmode.S"
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines needed by Linux and Multiboot loaders.
|
|
||||||
*/
|
|
||||||
#include "../loader.S"
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_DATA_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
|
|
||||||
codestart:
|
codestart:
|
||||||
movl %eax, EXT_C(grub_ieee1275_entry_fn)
|
movl %eax, EXT_C(grub_ieee1275_entry_fn)
|
||||||
|
@ -63,7 +63,3 @@ codestart:
|
||||||
*/
|
*/
|
||||||
#include "../realmode.S"
|
#include "../realmode.S"
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines needed by Linux and Multiboot loaders.
|
|
||||||
*/
|
|
||||||
#include "../loader.S"
|
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: These functions defined in this file may be called from C.
|
|
||||||
* Be careful of that you must not modify some registers. Quote
|
|
||||||
* from gcc-2.95.2/gcc/config/i386/i386.h:
|
|
||||||
|
|
||||||
1 for registers not available across function calls.
|
|
||||||
These must include the FIXED_REGISTERS and also any
|
|
||||||
registers that can be used without being saved.
|
|
||||||
The latter must include the registers where values are returned
|
|
||||||
and the register where structure-value addresses are passed.
|
|
||||||
Aside from that, you can include as many other registers as you like.
|
|
||||||
|
|
||||||
ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
|
|
||||||
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: GRUB is compiled with the options -mrtd and -mregparm=3.
|
|
||||||
* So the first three arguments are passed in %eax, %edx, and %ecx,
|
|
||||||
* respectively, and if a function has a fixed number of arguments
|
|
||||||
* and the number if greater than three, the function must return
|
|
||||||
* with "ret $N" where N is ((the number of arguments) - 3) * 4.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the area for all of the special variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.p2align 2 /* force 4-byte alignment */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void grub_linux_boot_zimage (void)
|
|
||||||
*/
|
|
||||||
VARIABLE(grub_linux_prot_size)
|
|
||||||
.long 0
|
|
||||||
VARIABLE(grub_linux_tmp_addr)
|
|
||||||
.long 0
|
|
||||||
VARIABLE(grub_linux_real_addr)
|
|
||||||
.long 0
|
|
||||||
VARIABLE(grub_linux_is_bzimage)
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
FUNCTION(grub_linux16_real_boot)
|
|
||||||
/* Must be done before zImage copy. */
|
|
||||||
call EXT_C(grub_dl_unload_all)
|
|
||||||
|
|
||||||
movl EXT_C(grub_linux_is_bzimage), %ebx
|
|
||||||
test %ebx, %ebx
|
|
||||||
jne bzimage
|
|
||||||
|
|
||||||
/* copy the kernel */
|
|
||||||
movl EXT_C(grub_linux_prot_size), %ecx
|
|
||||||
addl $3, %ecx
|
|
||||||
shrl $2, %ecx
|
|
||||||
movl $GRUB_LINUX_BZIMAGE_ADDR, %esi
|
|
||||||
movl $GRUB_LINUX_ZIMAGE_ADDR, %edi
|
|
||||||
cld
|
|
||||||
rep
|
|
||||||
movsl
|
|
||||||
|
|
||||||
bzimage:
|
|
||||||
movl EXT_C(grub_linux_real_addr), %ebx
|
|
||||||
|
|
||||||
/* copy the real mode code */
|
|
||||||
movl EXT_C(grub_linux_tmp_addr), %esi
|
|
||||||
movl %ebx, %edi
|
|
||||||
movl $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
|
|
||||||
cld
|
|
||||||
rep
|
|
||||||
movsb
|
|
||||||
|
|
||||||
/* change %ebx to the segment address */
|
|
||||||
shrl $4, %ebx
|
|
||||||
movl %ebx, %eax
|
|
||||||
addl $0x20, %eax
|
|
||||||
movw %ax, linux_setup_seg
|
|
||||||
|
|
||||||
/* XXX new stack pointer in safe area for calling functions */
|
|
||||||
movl $0x4000, %esp
|
|
||||||
call EXT_C(grub_stop_floppy)
|
|
||||||
|
|
||||||
/* final setup for linux boot */
|
|
||||||
call prot_to_real
|
|
||||||
.code16
|
|
||||||
|
|
||||||
cli
|
|
||||||
movw %bx, %ss
|
|
||||||
movw $GRUB_LINUX_SETUP_STACK, %sp
|
|
||||||
|
|
||||||
movw %bx, %ds
|
|
||||||
movw %bx, %es
|
|
||||||
movw %bx, %fs
|
|
||||||
movw %bx, %gs
|
|
||||||
|
|
||||||
/* ljmp */
|
|
||||||
.byte 0xea
|
|
||||||
.word 0
|
|
||||||
linux_setup_seg:
|
|
||||||
.word 0
|
|
||||||
.code32
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 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/symbol.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
/*
|
|
||||||
* This call is special... it never returns... in fact it should simply
|
|
||||||
* hang at this point!
|
|
||||||
*/
|
|
||||||
FUNCTION(grub_stop)
|
|
||||||
cli
|
|
||||||
1: hlt
|
|
||||||
jmp 1b
|
|
|
@ -16,7 +16,6 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/machine/init.h>
|
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/multiboot.h>
|
#include <grub/multiboot.h>
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/console.h>
|
#include <grub/machine/console.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
@ -44,9 +45,6 @@ struct mem_region
|
||||||
static struct mem_region mem_regions[MAX_REGIONS];
|
static struct mem_region mem_regions[MAX_REGIONS];
|
||||||
static int num_regions;
|
static int num_regions;
|
||||||
|
|
||||||
grub_addr_t grub_os_area_addr;
|
|
||||||
grub_size_t grub_os_area_size;
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
make_install_device (void)
|
make_install_device (void)
|
||||||
{
|
{
|
||||||
|
@ -142,6 +140,22 @@ compact_mem_regions (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
|
||||||
|
* BIOS call "INT 12H" to get conventional memory size
|
||||||
|
* The return value in AX.
|
||||||
|
*/
|
||||||
|
static inline grub_uint16_t
|
||||||
|
grub_get_conv_memsize (void)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x12, ®s);
|
||||||
|
return regs.eax & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_init (void)
|
grub_machine_init (void)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +165,7 @@ grub_machine_init (void)
|
||||||
/* Initialize the console as early as possible. */
|
/* Initialize the console as early as possible. */
|
||||||
grub_console_init ();
|
grub_console_init ();
|
||||||
|
|
||||||
grub_lower_mem = grub_get_memsize (0) << 10;
|
grub_lower_mem = grub_get_conv_memsize () << 10;
|
||||||
|
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
|
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
|
||||||
|
@ -203,25 +217,9 @@ grub_machine_init (void)
|
||||||
|
|
||||||
compact_mem_regions ();
|
compact_mem_regions ();
|
||||||
|
|
||||||
/* Add the memory regions to free memory, except for the region starting
|
|
||||||
from 1MB. This region is partially used for loading OS images.
|
|
||||||
For now, 1/4 of this is added to free memory. */
|
|
||||||
for (i = 0; i < num_regions; i++)
|
for (i = 0; i < num_regions; i++)
|
||||||
if (mem_regions[i].addr == 0x100000)
|
|
||||||
{
|
|
||||||
grub_size_t quarter = mem_regions[i].size >> 2;
|
|
||||||
|
|
||||||
grub_os_area_addr = mem_regions[i].addr;
|
|
||||||
grub_os_area_size = mem_regions[i].size - quarter;
|
|
||||||
grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
|
|
||||||
quarter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
|
grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
|
||||||
|
|
||||||
if (! grub_os_area_addr)
|
|
||||||
grub_fatal ("no upper memory");
|
|
||||||
|
|
||||||
grub_tsc_init ();
|
grub_tsc_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,98 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/machine/init.h>
|
#include <grub/machine/init.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* grub_get_ext_memsize() : return the extended memory size in KB.
|
||||||
|
* BIOS call "INT 15H, AH=88H" to get extended memory size
|
||||||
|
* The return value in AX.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static inline grub_uint16_t
|
||||||
|
grub_get_ext_memsize (void)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.eax = 0x8800;
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
return regs.eax & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB
|
||||||
|
in 1KB parts, and upper 16 bits are above 16MB in 64KB parts. If error, return zero.
|
||||||
|
BIOS call "INT 15H, AH=E801H" to get EISA memory map,
|
||||||
|
AX = memory between 1M and 16M in 1K parts.
|
||||||
|
BX = memory above 16M in 64K parts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline grub_uint32_t
|
||||||
|
grub_get_eisa_mmap (void)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
regs.eax = 0xe801;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
|
||||||
|
if ((regs.eax & 0xff00) == 0x8600)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (regs.eax & 0xffff) | (regs.ebx << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
|
||||||
|
* start), for the Query System Address Map BIOS call.
|
||||||
|
*
|
||||||
|
* Sets the first 4-byte int value of "addr" to the size returned by
|
||||||
|
* the call. If the call fails, sets it to zero.
|
||||||
|
*
|
||||||
|
* Returns: new (non-zero) continuation value, 0 if done.
|
||||||
|
*/
|
||||||
|
/* Get a memory map entry. Return next continuation value. Zero means
|
||||||
|
the end. */
|
||||||
|
static grub_uint32_t
|
||||||
|
grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
|
||||||
|
grub_uint32_t cont)
|
||||||
|
{
|
||||||
|
struct grub_bios_int_registers regs;
|
||||||
|
|
||||||
|
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||||
|
|
||||||
|
/* place address (+4) in ES:DI */
|
||||||
|
regs.es = ((grub_addr_t) &entry->addr) >> 4;
|
||||||
|
regs.edi = ((grub_addr_t) &entry->addr) & 0xf;
|
||||||
|
|
||||||
|
/* set continuation value */
|
||||||
|
regs.ebx = cont;
|
||||||
|
|
||||||
|
/* set default maximum buffer size */
|
||||||
|
regs.ecx = sizeof (*entry) - sizeof (entry->size);
|
||||||
|
|
||||||
|
/* set EDX to 'SMAP' */
|
||||||
|
regs.edx = 0x534d4150;
|
||||||
|
|
||||||
|
regs.eax = 0xe820;
|
||||||
|
grub_bios_interrupt (0x15, ®s);
|
||||||
|
|
||||||
|
/* write length of buffer (zero if error) into ADDR */
|
||||||
|
if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) || regs.eax != 0x534d4150
|
||||||
|
|| regs.ecx < 0x14 || regs.ecx > 0x400)
|
||||||
|
entry->size = 0;
|
||||||
|
else
|
||||||
|
entry->size = regs.ecx;
|
||||||
|
|
||||||
|
/* return the continuation value */
|
||||||
|
return regs.ebx;
|
||||||
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
|
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
|
||||||
{
|
{
|
||||||
|
@ -61,7 +148,7 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
|
||||||
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
|
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
|
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,6 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/machine/init.h>
|
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
|
@ -68,6 +67,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
|
||||||
GRUB_MACHINE_MEMORY_AVAILABLE))
|
GRUB_MACHINE_MEMORY_AVAILABLE))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (hook ((grub_addr_t) _end,
|
||||||
|
0xa0000 - (grub_addr_t) _end,
|
||||||
|
GRUB_MACHINE_MEMORY_AVAILABLE))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (hook (GRUB_MEMORY_MACHINE_UPPER,
|
if (hook (GRUB_MEMORY_MACHINE_UPPER,
|
||||||
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
|
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
|
||||||
GRUB_MACHINE_MEMORY_RESERVED))
|
GRUB_MACHINE_MEMORY_RESERVED))
|
||||||
|
|
|
@ -39,7 +39,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_DATA_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
|
|
||||||
codestart:
|
codestart:
|
||||||
/* Relocate to low memory. First we figure out our location.
|
/* Relocate to low memory. First we figure out our location.
|
||||||
|
@ -94,6 +94,9 @@ codestart:
|
||||||
call EXT_C(grub_main)
|
call EXT_C(grub_main)
|
||||||
|
|
||||||
/* This should never happen. */
|
/* This should never happen. */
|
||||||
jmp EXT_C(grub_stop)
|
cli
|
||||||
|
1:
|
||||||
|
hlt
|
||||||
|
jmp 1b
|
||||||
|
|
||||||
#include "../realmode.S"
|
#include "../realmode.S"
|
||||||
|
|
|
@ -423,14 +423,3 @@ grub_reboot (void)
|
||||||
for (;;) ;
|
for (;;) ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
|
||||||
grub_halt (void)
|
|
||||||
{
|
|
||||||
/* Not standardized. We try three known commands. */
|
|
||||||
|
|
||||||
grub_ieee1275_interpret ("shut-down", 0);
|
|
||||||
grub_ieee1275_interpret ("power-off", 0);
|
|
||||||
grub_ieee1275_interpret ("poweroff", 0);
|
|
||||||
for (;;) ;
|
|
||||||
}
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_DATA_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
||||||
VARIABLE (grub_arch_busclock)
|
VARIABLE (grub_arch_busclock)
|
||||||
.long 0
|
.long 0
|
||||||
|
|
|
@ -184,6 +184,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
|
||||||
va_start (args, fmt);
|
va_start (args, fmt);
|
||||||
grub_vprintf (fmt, args);
|
grub_vprintf (fmt, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
grub_refresh ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,7 +990,7 @@ grub_abort (void)
|
||||||
grub_exit ();
|
grub_exit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef APPLE_CC
|
#if ! defined (APPLE_CC) && !defined (GRUB_UTIL)
|
||||||
/* GCC emits references to abort(). */
|
/* GCC emits references to abort(). */
|
||||||
void abort (void) __attribute__ ((alias ("grub_abort")));
|
void abort (void) __attribute__ ((alias ("grub_abort")));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/mm_private.h>
|
||||||
|
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
# undef grub_malloc
|
# undef grub_malloc
|
||||||
|
@ -74,45 +75,9 @@
|
||||||
# undef grub_memalign
|
# undef grub_memalign
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Magic words. */
|
|
||||||
#define GRUB_MM_FREE_MAGIC 0x2d3c2808
|
|
||||||
#define GRUB_MM_ALLOC_MAGIC 0x6db08fa4
|
|
||||||
|
|
||||||
typedef struct grub_mm_header
|
|
||||||
{
|
|
||||||
struct grub_mm_header *next;
|
|
||||||
grub_size_t size;
|
|
||||||
grub_size_t magic;
|
|
||||||
#if GRUB_CPU_SIZEOF_VOID_P == 4
|
|
||||||
char padding[4];
|
|
||||||
#elif GRUB_CPU_SIZEOF_VOID_P == 8
|
|
||||||
char padding[8];
|
|
||||||
#else
|
|
||||||
# error "unknown word size"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
*grub_mm_header_t;
|
|
||||||
|
|
||||||
#if GRUB_CPU_SIZEOF_VOID_P == 4
|
|
||||||
# define GRUB_MM_ALIGN_LOG2 4
|
|
||||||
#elif GRUB_CPU_SIZEOF_VOID_P == 8
|
|
||||||
# define GRUB_MM_ALIGN_LOG2 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GRUB_MM_ALIGN (1 << GRUB_MM_ALIGN_LOG2)
|
|
||||||
|
|
||||||
typedef struct grub_mm_region
|
|
||||||
{
|
|
||||||
struct grub_mm_header *first;
|
|
||||||
struct grub_mm_region *next;
|
|
||||||
grub_addr_t addr;
|
|
||||||
grub_size_t size;
|
|
||||||
}
|
|
||||||
*grub_mm_region_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static grub_mm_region_t base;
|
grub_mm_region_t grub_mm_base;
|
||||||
|
|
||||||
/* Get a header from the pointer PTR, and set *P and *R to a pointer
|
/* Get a header from the pointer PTR, and set *P and *R to a pointer
|
||||||
to the header and a pointer to its region, respectively. PTR must
|
to the header and a pointer to its region, respectively. PTR must
|
||||||
|
@ -123,9 +88,9 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
|
||||||
if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
|
if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
|
||||||
grub_fatal ("unaligned pointer %p", ptr);
|
grub_fatal ("unaligned pointer %p", ptr);
|
||||||
|
|
||||||
for (*r = base; *r; *r = (*r)->next)
|
for (*r = grub_mm_base; *r; *r = (*r)->next)
|
||||||
if ((grub_addr_t) ptr > (*r)->addr
|
if ((grub_addr_t) ptr > (grub_addr_t) ((*r) + 1)
|
||||||
&& (grub_addr_t) ptr <= (*r)->addr + (*r)->size)
|
&& (grub_addr_t) ptr <= (grub_addr_t) ((*r) + 1) + (*r)->size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (! *r)
|
if (! *r)
|
||||||
|
@ -156,18 +121,18 @@ grub_mm_init_region (void *addr, grub_size_t size)
|
||||||
if (size < GRUB_MM_ALIGN)
|
if (size < GRUB_MM_ALIGN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN);
|
h = (grub_mm_header_t) (r + 1);
|
||||||
h->next = h;
|
h->next = h;
|
||||||
h->magic = GRUB_MM_FREE_MAGIC;
|
h->magic = GRUB_MM_FREE_MAGIC;
|
||||||
h->size = (size >> GRUB_MM_ALIGN_LOG2);
|
h->size = (size >> GRUB_MM_ALIGN_LOG2);
|
||||||
|
|
||||||
r->first = h;
|
r->first = h;
|
||||||
r->addr = (grub_addr_t) h;
|
r->pre_size = (grub_addr_t) r - (grub_addr_t) addr;
|
||||||
r->size = (h->size << GRUB_MM_ALIGN_LOG2);
|
r->size = (h->size << GRUB_MM_ALIGN_LOG2);
|
||||||
|
|
||||||
/* Find where to insert this region. Put a smaller one before bigger ones,
|
/* Find where to insert this region. Put a smaller one before bigger ones,
|
||||||
to prevent fragmentation. */
|
to prevent fragmentation. */
|
||||||
for (p = &base, q = *p; q; p = &(q->next), q = *p)
|
for (p = &grub_mm_base, q = *p; q; p = &(q->next), q = *p)
|
||||||
if (q->size > r->size)
|
if (q->size > r->size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -206,6 +171,7 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
||||||
|
|
||||||
if (p->size >= n + extra)
|
if (p->size >= n + extra)
|
||||||
{
|
{
|
||||||
|
extra += (p->size - extra - n) & (~(align - 1));
|
||||||
if (extra == 0 && p->size == n)
|
if (extra == 0 && p->size == n)
|
||||||
{
|
{
|
||||||
/* There is no special alignment requirement and memory block
|
/* There is no special alignment requirement and memory block
|
||||||
|
@ -284,10 +250,10 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
|
||||||
r = p + extra + n;
|
r = p + extra + n;
|
||||||
r->magic = GRUB_MM_FREE_MAGIC;
|
r->magic = GRUB_MM_FREE_MAGIC;
|
||||||
r->size = p->size - extra - n;
|
r->size = p->size - extra - n;
|
||||||
r->next = p->next;
|
r->next = p;
|
||||||
|
|
||||||
p->size = extra;
|
p->size = extra;
|
||||||
p->next = r;
|
q->next = r;
|
||||||
p += extra;
|
p += extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,13 +284,16 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||||
grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
|
grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
if (!grub_mm_base)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
align = (align >> GRUB_MM_ALIGN_LOG2);
|
align = (align >> GRUB_MM_ALIGN_LOG2);
|
||||||
if (align == 0)
|
if (align == 0)
|
||||||
align = 1;
|
align = 1;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
|
||||||
for (r = base; r; r = r->next)
|
for (r = grub_mm_base; r; r = r->next)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
@ -352,6 +321,7 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -485,7 +455,7 @@ grub_mm_dump_free (void)
|
||||||
{
|
{
|
||||||
grub_mm_region_t r;
|
grub_mm_region_t r;
|
||||||
|
|
||||||
for (r = base; r; r = r->next)
|
for (r = grub_mm_base; r; r = r->next)
|
||||||
{
|
{
|
||||||
grub_mm_header_t p;
|
grub_mm_header_t p;
|
||||||
|
|
||||||
|
@ -512,13 +482,13 @@ grub_mm_dump (unsigned lineno)
|
||||||
grub_mm_region_t r;
|
grub_mm_region_t r;
|
||||||
|
|
||||||
grub_printf ("called at line %u\n", lineno);
|
grub_printf ("called at line %u\n", lineno);
|
||||||
for (r = base; r; r = r->next)
|
for (r = grub_mm_base; r; r = r->next)
|
||||||
{
|
{
|
||||||
grub_mm_header_t p;
|
grub_mm_header_t p;
|
||||||
|
|
||||||
for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1)
|
for (p = (grub_mm_header_t) ALIGN_UP ((grub_addr_t) (r + 1),
|
||||||
& (~(GRUB_MM_ALIGN - 1)));
|
GRUB_MM_ALIGN);
|
||||||
(grub_addr_t) p < r->addr + r->size;
|
(grub_addr_t) p < (grub_addr_t) (r+1) + r->size;
|
||||||
p++)
|
p++)
|
||||||
{
|
{
|
||||||
switch (p->magic)
|
switch (p->magic)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* cache.S - Flush the processor cache for a specific region. */
|
/* cache.S - Flush the processor cache for a specific region. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2004,2007 Free Software Foundation, Inc.
|
* Copyright (C) 2004,2007,2010 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,32 +17,10 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CACHE_LINE_BYTES 32
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
.globl grub_arch_sync_caches
|
.globl grub_arch_sync_caches
|
||||||
grub_arch_sync_caches:
|
grub_arch_sync_caches:
|
||||||
/* `address' may not be CACHE_LINE_BYTES-aligned. */
|
#include "cache_flush.S"
|
||||||
andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment. */
|
|
||||||
add 4, 4, 6 /* Adjust `size' to compensate. */
|
|
||||||
|
|
||||||
/* Force the dcache lines to memory. */
|
|
||||||
li 5, 0
|
|
||||||
1: dcbst 5, 3
|
|
||||||
addi 5, 5, CACHE_LINE_BYTES
|
|
||||||
cmpw 5, 4
|
|
||||||
blt 1b
|
|
||||||
sync /* Force all dcbsts to complete. */
|
|
||||||
|
|
||||||
/* Invalidate the icache lines. */
|
|
||||||
li 5, 0
|
|
||||||
1: icbi 5, 3
|
|
||||||
addi 5, 5, CACHE_LINE_BYTES
|
|
||||||
cmpw 5, 4
|
|
||||||
blt 1b
|
|
||||||
sync /* Force all icbis to complete. */
|
|
||||||
isync /* Discard partially executed instructions that were
|
|
||||||
loaded from the invalid icache. */
|
|
||||||
blr
|
blr
|
||||||
|
|
43
grub-core/kern/powerpc/cache_flush.S
Normal file
43
grub-core/kern/powerpc/cache_flush.S
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* cache.S - Flush the processor cache for a specific region. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2004,2007,2010 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef CACHE_LINE_BYTES
|
||||||
|
#define CACHE_LINE_BYTES 32
|
||||||
|
|
||||||
|
/* `address' may not be CACHE_LINE_BYTES-aligned. */
|
||||||
|
andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment. */
|
||||||
|
add 4, 4, 6 /* Adjust `size' to compensate. */
|
||||||
|
|
||||||
|
/* Force the dcache lines to memory. */
|
||||||
|
li 5, 0
|
||||||
|
1: dcbst 5, 3
|
||||||
|
addi 5, 5, CACHE_LINE_BYTES
|
||||||
|
cmpw 5, 4
|
||||||
|
blt 1b
|
||||||
|
sync /* Force all dcbsts to complete. */
|
||||||
|
|
||||||
|
/* Invalidate the icache lines. */
|
||||||
|
li 5, 0
|
||||||
|
1: icbi 5, 3
|
||||||
|
addi 5, 5, CACHE_LINE_BYTES
|
||||||
|
cmpw 5, 4
|
||||||
|
blt 1b
|
||||||
|
sync /* Force all icbis to complete. */
|
||||||
|
isync /* Discard partially executed instructions that were
|
||||||
|
loaded from the invalid icache. */
|
|
@ -39,7 +39,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_DATA_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
|
|
||||||
codestart:
|
codestart:
|
||||||
li 2, 0
|
li 2, 0
|
||||||
|
|
|
@ -42,7 +42,7 @@ VARIABLE(grub_prefix)
|
||||||
* Leave some breathing room for the prefix.
|
* Leave some breathing room for the prefix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END
|
. = EXT_C(_start) + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
|
|
||||||
codestart:
|
codestart:
|
||||||
/* Copy the modules past the end of the kernel image.
|
/* Copy the modules past the end of the kernel image.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
/* efi.c - generic EFI support */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2002,2003,2004,2006,2007 Free Software Foundation, Inc.
|
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,7 +17,18 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GRUB_LOADER_MACHINE_HEADER
|
#include <grub/efi/api.h>
|
||||||
#define GRUB_LOADER_MACHINE_HEADER 1
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
|
||||||
#endif /* ! GRUB_LOADER_MACHINE_HEADER */
|
void
|
||||||
|
grub_halt (void)
|
||||||
|
{
|
||||||
|
grub_machine_fini ();
|
||||||
|
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||||
|
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
104
grub-core/lib/efi/relocator.c
Normal file
104
grub-core/lib/efi/relocator.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2010 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/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
#include <grub/memory.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
|
||||||
|
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
|
||||||
|
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
grub_relocator_firmware_get_max_events (void)
|
||||||
|
{
|
||||||
|
grub_efi_uintn_t mmapsize = 0, descriptor_size = 0;
|
||||||
|
grub_efi_uint32_t descriptor_version = 0;
|
||||||
|
grub_efi_uintn_t key;
|
||||||
|
grub_efi_get_memory_map (&mmapsize, NULL, &key, &descriptor_size,
|
||||||
|
&descriptor_version);
|
||||||
|
/* Since grub_relocator_firmware_fill_events uses malloc
|
||||||
|
we need some reserve. Hence +10. */
|
||||||
|
return 2 * (mmapsize / descriptor_size + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
|
||||||
|
{
|
||||||
|
grub_efi_uintn_t mmapsize = 0, desc_size = 0;
|
||||||
|
grub_efi_uint32_t descriptor_version = 0;
|
||||||
|
grub_efi_memory_descriptor_t *descs = NULL;
|
||||||
|
grub_efi_uintn_t key;
|
||||||
|
int counter = 0;
|
||||||
|
grub_efi_memory_descriptor_t *desc;
|
||||||
|
|
||||||
|
grub_efi_get_memory_map (&mmapsize, NULL, &key, &desc_size,
|
||||||
|
&descriptor_version);
|
||||||
|
descs = grub_malloc (mmapsize);
|
||||||
|
if (!descs)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
grub_efi_get_memory_map (&mmapsize, descs, &key, &desc_size,
|
||||||
|
&descriptor_version);
|
||||||
|
|
||||||
|
for (desc = descs;
|
||||||
|
(char *) desc < ((char *) descs + mmapsize);
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
{
|
||||||
|
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
|
||||||
|
continue;
|
||||||
|
events[counter].type = REG_FIRMWARE_START;
|
||||||
|
events[counter].pos = desc->physical_start;
|
||||||
|
counter++;
|
||||||
|
events[counter].type = REG_FIRMWARE_END;
|
||||||
|
events[counter].pos = desc->physical_start + (desc->num_pages << 12);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_physical_address_t address = start;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
|
||||||
|
if (grub_efi_is_finished)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
|
||||||
|
GRUB_EFI_LOADER_DATA, size >> 12, &address);
|
||||||
|
return (status == GRUB_EFI_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_relocator_firmware_free_region (grub_addr_t start, grub_size_t size)
|
||||||
|
{
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
|
||||||
|
if (grub_efi_is_finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
efi_call_2 (b->free_pages, start, size >> 12);
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,9 +16,10 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GRUB_MACHINE_EFI_EMU_HEADER
|
#include <grub/misc.h>
|
||||||
#define GRUB_MACHINE_EFI_EMU_HEADER 1
|
|
||||||
|
|
||||||
grub_err_t grub_machine_efiemu_init_tables (void);
|
void
|
||||||
|
grub_halt (void)
|
||||||
#endif
|
{
|
||||||
|
grub_reboot ();
|
||||||
|
}
|
|
@ -17,11 +17,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/cpu/io.h>
|
#include <grub/cpu/io.h>
|
||||||
#include <grub/machine/init.h>
|
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
|
||||||
const char bochs_shutdown[] = "Shutdown";
|
const char bochs_shutdown[] = "Shutdown";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This call is special... it never returns... in fact it should simply
|
||||||
|
* hang at this point!
|
||||||
|
*/
|
||||||
|
static inline void __attribute__ ((noreturn))
|
||||||
|
stop (void)
|
||||||
|
{
|
||||||
|
asm volatile ("cli");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
asm volatile ("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_halt (void)
|
grub_halt (void)
|
||||||
{
|
{
|
||||||
|
@ -38,5 +51,5 @@ grub_halt (void)
|
||||||
|
|
||||||
/* In order to return we'd have to check what the previous status of IF
|
/* In order to return we'd have to check what the previous status of IF
|
||||||
flag was. But user most likely doesn't want to return anyway ... */
|
flag was. But user most likely doesn't want to return anyway ... */
|
||||||
grub_stop ();
|
stop ();
|
||||||
}
|
}
|
|
@ -19,84 +19,252 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
|
||||||
#include <grub/i386/relocator.h>
|
#include <grub/i386/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
|
||||||
extern grub_uint8_t grub_relocator32_forward_start;
|
extern grub_uint8_t grub_relocator_forward_start;
|
||||||
extern grub_uint8_t grub_relocator32_forward_end;
|
extern grub_uint8_t grub_relocator_forward_end;
|
||||||
extern grub_uint8_t grub_relocator32_backward_start;
|
extern grub_uint8_t grub_relocator_backward_start;
|
||||||
extern grub_uint8_t grub_relocator32_backward_end;
|
extern grub_uint8_t grub_relocator_backward_end;
|
||||||
|
|
||||||
extern grub_uint32_t grub_relocator32_backward_dest;
|
extern void *grub_relocator_backward_dest;
|
||||||
extern grub_uint32_t grub_relocator32_backward_size;
|
extern void *grub_relocator_backward_src;
|
||||||
extern grub_addr_t grub_relocator32_backward_src;
|
extern grub_size_t grub_relocator_backward_chunk_size;
|
||||||
|
|
||||||
extern grub_uint32_t grub_relocator32_forward_dest;
|
extern void *grub_relocator_forward_dest;
|
||||||
extern grub_uint32_t grub_relocator32_forward_size;
|
extern void *grub_relocator_forward_src;
|
||||||
extern grub_addr_t grub_relocator32_forward_src;
|
extern grub_size_t grub_relocator_forward_chunk_size;
|
||||||
|
|
||||||
extern grub_uint32_t grub_relocator32_forward_eax;
|
extern grub_uint8_t grub_relocator16_start;
|
||||||
extern grub_uint32_t grub_relocator32_forward_ebx;
|
extern grub_uint8_t grub_relocator16_end;
|
||||||
extern grub_uint32_t grub_relocator32_forward_ecx;
|
extern grub_uint16_t grub_relocator16_cs;
|
||||||
extern grub_uint32_t grub_relocator32_forward_edx;
|
extern grub_uint16_t grub_relocator16_ip;
|
||||||
extern grub_uint32_t grub_relocator32_forward_eip;
|
extern grub_uint16_t grub_relocator16_ds;
|
||||||
extern grub_uint32_t grub_relocator32_forward_esp;
|
extern grub_uint16_t grub_relocator16_es;
|
||||||
|
extern grub_uint16_t grub_relocator16_fs;
|
||||||
|
extern grub_uint16_t grub_relocator16_gs;
|
||||||
|
extern grub_uint16_t grub_relocator16_ss;
|
||||||
|
extern grub_uint16_t grub_relocator16_sp;
|
||||||
|
extern grub_uint32_t grub_relocator16_edx;
|
||||||
|
|
||||||
extern grub_uint32_t grub_relocator32_backward_eax;
|
extern grub_uint8_t grub_relocator32_start;
|
||||||
extern grub_uint32_t grub_relocator32_backward_ebx;
|
extern grub_uint8_t grub_relocator32_end;
|
||||||
extern grub_uint32_t grub_relocator32_backward_ecx;
|
extern grub_uint32_t grub_relocator32_eax;
|
||||||
extern grub_uint32_t grub_relocator32_backward_edx;
|
extern grub_uint32_t grub_relocator32_ebx;
|
||||||
extern grub_uint32_t grub_relocator32_backward_eip;
|
extern grub_uint32_t grub_relocator32_ecx;
|
||||||
extern grub_uint32_t grub_relocator32_backward_esp;
|
extern grub_uint32_t grub_relocator32_edx;
|
||||||
|
extern grub_uint32_t grub_relocator32_eip;
|
||||||
|
extern grub_uint32_t grub_relocator32_esp;
|
||||||
|
extern grub_uint32_t grub_relocator32_ebp;
|
||||||
|
extern grub_uint32_t grub_relocator32_esi;
|
||||||
|
extern grub_uint32_t grub_relocator32_edi;
|
||||||
|
|
||||||
#define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start)
|
extern grub_uint8_t grub_relocator64_start;
|
||||||
#define RELOCATOR_ALIGN 16
|
extern grub_uint8_t grub_relocator64_end;
|
||||||
#define PREFIX(x) grub_relocator32_ ## x
|
extern grub_uint64_t grub_relocator64_rax;
|
||||||
|
extern grub_uint64_t grub_relocator64_rbx;
|
||||||
|
extern grub_uint64_t grub_relocator64_rcx;
|
||||||
|
extern grub_uint64_t grub_relocator64_rdx;
|
||||||
|
extern grub_uint64_t grub_relocator64_rip;
|
||||||
|
extern grub_uint64_t grub_relocator64_rip_addr;
|
||||||
|
extern grub_uint64_t grub_relocator64_rsp;
|
||||||
|
extern grub_uint64_t grub_relocator64_rsi;
|
||||||
|
extern grub_addr_t grub_relocator64_cr3;
|
||||||
|
|
||||||
static void
|
#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start)
|
||||||
write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest,
|
|
||||||
grub_size_t size, struct grub_relocator32_state state)
|
grub_size_t grub_relocator_align = 1;
|
||||||
|
grub_size_t grub_relocator_forward_size;
|
||||||
|
grub_size_t grub_relocator_backward_size;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
grub_size_t grub_relocator_jumper_size = 12;
|
||||||
|
#else
|
||||||
|
grub_size_t grub_relocator_jumper_size = 7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_init (void)
|
||||||
{
|
{
|
||||||
grub_relocator32_backward_dest = dest;
|
grub_relocator_forward_size = RELOCATOR_SIZEOF(_forward);
|
||||||
grub_relocator32_backward_src = PTR_TO_UINT64 (src);
|
grub_relocator_backward_size = RELOCATOR_SIZEOF(_backward);
|
||||||
grub_relocator32_backward_size = size;
|
|
||||||
|
|
||||||
grub_relocator32_backward_eax = state.eax;
|
|
||||||
grub_relocator32_backward_ebx = state.ebx;
|
|
||||||
grub_relocator32_backward_ecx = state.ecx;
|
|
||||||
grub_relocator32_backward_edx = state.edx;
|
|
||||||
grub_relocator32_backward_eip = state.eip;
|
|
||||||
grub_relocator32_backward_esp = state.esp;
|
|
||||||
|
|
||||||
grub_memmove (ptr,
|
|
||||||
&grub_relocator32_backward_start,
|
|
||||||
RELOCATOR_SIZEOF (backward));
|
|
||||||
((void (*) (void)) ptr) ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest,
|
grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
|
||||||
grub_size_t size, struct grub_relocator32_state state)
|
|
||||||
{
|
{
|
||||||
|
grub_uint8_t *ptr;
|
||||||
grub_relocator32_forward_dest = dest;
|
ptr = rels;
|
||||||
grub_relocator32_forward_src = PTR_TO_UINT64 (src);
|
#ifdef __x86_64__
|
||||||
grub_relocator32_forward_size = size;
|
/* movq imm64, %rax (for relocator) */
|
||||||
|
*(grub_uint8_t *) ptr = 0x48;
|
||||||
grub_relocator32_forward_eax = state.eax;
|
ptr++;
|
||||||
grub_relocator32_forward_ebx = state.ebx;
|
*(grub_uint8_t *) ptr = 0xb8;
|
||||||
grub_relocator32_forward_ecx = state.ecx;
|
ptr++;
|
||||||
grub_relocator32_forward_edx = state.edx;
|
*(grub_uint64_t *) ptr = addr;
|
||||||
grub_relocator32_forward_eip = state.eip;
|
ptr += sizeof (grub_uint64_t);
|
||||||
grub_relocator32_forward_esp = state.esp;
|
#else
|
||||||
|
/* movl imm32, %eax (for relocator) */
|
||||||
grub_memmove (ptr,
|
*(grub_uint8_t *) ptr = 0xb8;
|
||||||
&grub_relocator32_forward_start,
|
ptr++;
|
||||||
RELOCATOR_SIZEOF (forward));
|
*(grub_uint32_t *) ptr = addr;
|
||||||
((void (*) (void)) ptr) ();
|
ptr += sizeof (grub_uint32_t);
|
||||||
|
#endif
|
||||||
|
/* jmp $eax/$rax */
|
||||||
|
*(grub_uint8_t *) ptr = 0xff;
|
||||||
|
ptr++;
|
||||||
|
*(grub_uint8_t *) ptr = 0xe0;
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../relocator.c"
|
void
|
||||||
|
grub_cpu_relocator_backward (void *ptr, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
grub_relocator_backward_dest = dest;
|
||||||
|
grub_relocator_backward_src = src;
|
||||||
|
grub_relocator_backward_chunk_size = size;
|
||||||
|
|
||||||
|
grub_memmove (ptr,
|
||||||
|
&grub_relocator_backward_start,
|
||||||
|
RELOCATOR_SIZEOF (_backward));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_forward (void *ptr, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
grub_relocator_forward_dest = dest;
|
||||||
|
grub_relocator_forward_src = src;
|
||||||
|
grub_relocator_forward_chunk_size = size;
|
||||||
|
|
||||||
|
grub_memmove (ptr,
|
||||||
|
&grub_relocator_forward_start,
|
||||||
|
RELOCATOR_SIZEOF (_forward));
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator32_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator32_state state)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
|
(0xffffffff - RELOCATOR_SIZEOF (32))
|
||||||
|
+ 1, RELOCATOR_SIZEOF (32), 16,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_relocator32_eax = state.eax;
|
||||||
|
grub_relocator32_ebx = state.ebx;
|
||||||
|
grub_relocator32_ecx = state.ecx;
|
||||||
|
grub_relocator32_edx = state.edx;
|
||||||
|
grub_relocator32_eip = state.eip;
|
||||||
|
grub_relocator32_esp = state.esp;
|
||||||
|
grub_relocator32_ebp = state.ebp;
|
||||||
|
grub_relocator32_esi = state.esi;
|
||||||
|
grub_relocator32_edi = state.edi;
|
||||||
|
|
||||||
|
grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start,
|
||||||
|
RELOCATOR_SIZEOF (32));
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||||
|
&relst, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
asm volatile ("cli");
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator16_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator16_state state)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
|
0xa0000 - RELOCATOR_SIZEOF (16),
|
||||||
|
RELOCATOR_SIZEOF (16), 16,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_relocator16_cs = state.cs;
|
||||||
|
grub_relocator16_ip = state.ip;
|
||||||
|
|
||||||
|
grub_relocator16_ds = state.ds;
|
||||||
|
grub_relocator16_es = state.es;
|
||||||
|
grub_relocator16_fs = state.fs;
|
||||||
|
grub_relocator16_gs = state.gs;
|
||||||
|
|
||||||
|
grub_relocator16_ss = state.ss;
|
||||||
|
grub_relocator16_sp = state.sp;
|
||||||
|
|
||||||
|
grub_relocator16_edx = state.edx;
|
||||||
|
|
||||||
|
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
||||||
|
RELOCATOR_SIZEOF (16));
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||||
|
&relst, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
asm volatile ("cli");
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator64_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator64_state state,
|
||||||
|
grub_addr_t min_addr, grub_addr_t max_addr)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
|
||||||
|
max_addr - RELOCATOR_SIZEOF (64),
|
||||||
|
RELOCATOR_SIZEOF (64), 16,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_relocator64_rax = state.rax;
|
||||||
|
grub_relocator64_rbx = state.rbx;
|
||||||
|
grub_relocator64_rcx = state.rcx;
|
||||||
|
grub_relocator64_rdx = state.rdx;
|
||||||
|
grub_relocator64_rip = state.rip;
|
||||||
|
grub_relocator64_rsp = state.rsp;
|
||||||
|
grub_relocator64_rsi = state.rsi;
|
||||||
|
grub_relocator64_cr3 = state.cr3;
|
||||||
|
|
||||||
|
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_start,
|
||||||
|
RELOCATOR_SIZEOF (64));
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||||
|
&relst, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
asm volatile ("cli");
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
193
grub-core/lib/i386/relocator16.S
Normal file
193
grub-core/lib/i386/relocator16.S
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The code segment of the protected mode. */
|
||||||
|
#define CODE_SEGMENT 0x08
|
||||||
|
|
||||||
|
/* The data segment of the protected mode. */
|
||||||
|
#define DATA_SEGMENT 0x10
|
||||||
|
|
||||||
|
#define PSEUDO_REAL_CSEG 0x18
|
||||||
|
|
||||||
|
#define PSEUDO_REAL_DSEG 0x20
|
||||||
|
|
||||||
|
#include "relocator_common.S"
|
||||||
|
|
||||||
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator16_start)
|
||||||
|
PREAMBLE
|
||||||
|
|
||||||
|
movl %esi, %eax
|
||||||
|
movw %ax, (LOCAL (cs_base_bytes12) - LOCAL (base)) (RSI, 1)
|
||||||
|
shrl $16, %eax
|
||||||
|
movb %al, (LOCAL (cs_base_byte3) - LOCAL (base)) (RSI, 1)
|
||||||
|
|
||||||
|
RELOAD_GDT
|
||||||
|
.code32
|
||||||
|
/* Update other registers. */
|
||||||
|
movl $DATA_SEGMENT, %eax
|
||||||
|
movl %eax, %ds
|
||||||
|
movl %eax, %es
|
||||||
|
movl %eax, %fs
|
||||||
|
movl %eax, %gs
|
||||||
|
movl %eax, %ss
|
||||||
|
|
||||||
|
DISABLE_PAGING
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* Disable amd64. */
|
||||||
|
movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax
|
||||||
|
wrmsr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn off PAE. */
|
||||||
|
movl %cr4, %eax
|
||||||
|
andl $(~GRUB_MEMORY_CPU_CR4_PAE_ON), %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
/* Update other registers. */
|
||||||
|
movl $PSEUDO_REAL_DSEG, %eax
|
||||||
|
movl %eax, %ds
|
||||||
|
movl %eax, %es
|
||||||
|
movl %eax, %fs
|
||||||
|
movl %eax, %gs
|
||||||
|
movl %eax, %ss
|
||||||
|
|
||||||
|
movl %esi, %eax
|
||||||
|
shrl $4, %eax
|
||||||
|
movw %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1)
|
||||||
|
|
||||||
|
/* jump to a 16 bit segment */
|
||||||
|
ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base))
|
||||||
|
LOCAL(cont2):
|
||||||
|
.code16
|
||||||
|
|
||||||
|
/* clear the PE bit of CR0 */
|
||||||
|
movl %cr0, %eax
|
||||||
|
andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
/* flush prefetch queue, reload %cs */
|
||||||
|
/* ljmp */
|
||||||
|
.byte 0xea
|
||||||
|
.word LOCAL(cont3)-LOCAL(base)
|
||||||
|
LOCAL(segment):
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
LOCAL(cont3):
|
||||||
|
/* we are in real mode now
|
||||||
|
* set up the real mode segment registers : DS, SS, ES
|
||||||
|
*/
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_ds)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %ds
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_es)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %es
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_fs)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %fs
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_gs)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_ss)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %ss
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_sp)
|
||||||
|
.word 0
|
||||||
|
movw %ax, %ss
|
||||||
|
|
||||||
|
/* movw imm32, %edx. */
|
||||||
|
.byte 0x66, 0xba
|
||||||
|
VARIABLE(grub_relocator16_edx)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Cleared direction flag is of no problem with any current
|
||||||
|
payload and makes this implementation easier. */
|
||||||
|
cld
|
||||||
|
|
||||||
|
/* ljmp */
|
||||||
|
.byte 0xea
|
||||||
|
VARIABLE(grub_relocator16_ip)
|
||||||
|
.word 0
|
||||||
|
VARIABLE(grub_relocator16_cs)
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
.code32
|
||||||
|
|
||||||
|
/* GDT. Copied from loader/i386/linux.c. */
|
||||||
|
.p2align 4
|
||||||
|
LOCAL(gdt):
|
||||||
|
.word 0, 0
|
||||||
|
.byte 0, 0, 0, 0
|
||||||
|
|
||||||
|
/* -- code segment --
|
||||||
|
* base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
|
||||||
|
* type = 32bit code execute/read, DPL = 0
|
||||||
|
*/
|
||||||
|
.word 0xFFFF, 0
|
||||||
|
.byte 0, 0x9A, 0xCF, 0
|
||||||
|
|
||||||
|
/* -- data segment --
|
||||||
|
* base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
|
||||||
|
* type = 32 bit data read/write, DPL = 0
|
||||||
|
*/
|
||||||
|
.word 0xFFFF, 0
|
||||||
|
.byte 0, 0x92, 0xCF, 0
|
||||||
|
|
||||||
|
/* -- 16 bit real mode CS --
|
||||||
|
* base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
|
||||||
|
* type = 16 bit code execute/read only/conforming, DPL = 0
|
||||||
|
*/
|
||||||
|
.word 0xFFFF
|
||||||
|
LOCAL(cs_base_bytes12):
|
||||||
|
.word 0
|
||||||
|
LOCAL(cs_base_byte3):
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
.byte 0x9E, 0, 0
|
||||||
|
|
||||||
|
/* -- 16 bit real mode DS --
|
||||||
|
* base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
|
||||||
|
* type = 16 bit data read/write, DPL = 0
|
||||||
|
*/
|
||||||
|
.word 0xFFFF, 0
|
||||||
|
.byte 0, 0x92, 0, 0
|
||||||
|
LOCAL(gdt_end):
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator16_end)
|
134
grub-core/lib/i386/relocator32.S
Normal file
134
grub-core/lib/i386/relocator32.S
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The code segment of the protected mode. */
|
||||||
|
#define CODE_SEGMENT 0x10
|
||||||
|
|
||||||
|
/* The data segment of the protected mode. */
|
||||||
|
#define DATA_SEGMENT 0x18
|
||||||
|
|
||||||
|
#include "relocator_common.S"
|
||||||
|
|
||||||
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator32_start)
|
||||||
|
PREAMBLE
|
||||||
|
|
||||||
|
RELOAD_GDT
|
||||||
|
.code32
|
||||||
|
/* Update other registers. */
|
||||||
|
movl $DATA_SEGMENT, %eax
|
||||||
|
movl %eax, %ds
|
||||||
|
movl %eax, %es
|
||||||
|
movl %eax, %fs
|
||||||
|
movl %eax, %gs
|
||||||
|
movl %eax, %ss
|
||||||
|
|
||||||
|
DISABLE_PAGING
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* Disable amd64. */
|
||||||
|
movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax
|
||||||
|
wrmsr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn off PAE. */
|
||||||
|
movl %cr4, %eax
|
||||||
|
andl $(~GRUB_MEMORY_CPU_CR4_PAE_ON), %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
jmp LOCAL(cont2)
|
||||||
|
LOCAL(cont2):
|
||||||
|
.code32
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator32_esp)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
movl %eax, %esp
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator32_ebp)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
movl %eax, %ebp
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator32_esi)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
movl %eax, %esi
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator32_edi)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
movl %eax, %edi
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator32_eax)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* mov imm32, %ebx */
|
||||||
|
.byte 0xbb
|
||||||
|
VARIABLE(grub_relocator32_ebx)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* mov imm32, %ecx */
|
||||||
|
.byte 0xb9
|
||||||
|
VARIABLE(grub_relocator32_ecx)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* mov imm32, %edx */
|
||||||
|
.byte 0xba
|
||||||
|
VARIABLE(grub_relocator32_edx)
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Cleared direction flag is of no problem with any current
|
||||||
|
payload and makes this implementation easier. */
|
||||||
|
cld
|
||||||
|
|
||||||
|
.byte 0xea
|
||||||
|
VARIABLE(grub_relocator32_eip)
|
||||||
|
.long 0
|
||||||
|
.word CODE_SEGMENT
|
||||||
|
|
||||||
|
/* GDT. Copied from loader/i386/linux.c. */
|
||||||
|
.p2align 4
|
||||||
|
LOCAL(gdt):
|
||||||
|
/* NULL. */
|
||||||
|
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
/* Reserved. */
|
||||||
|
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
/* Code segment. */
|
||||||
|
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
|
||||||
|
|
||||||
|
/* Data segment. */
|
||||||
|
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
|
||||||
|
LOCAL(gdt_end):
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator32_end)
|
160
grub-core/lib/i386/relocator64.S
Normal file
160
grub-core/lib/i386/relocator64.S
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CODE32_SEGMENT 0x18
|
||||||
|
#define CODE_SEGMENT 0x08
|
||||||
|
|
||||||
|
/* The data segment of the protected mode. */
|
||||||
|
#define DATA_SEGMENT 0x10
|
||||||
|
|
||||||
|
#include "relocator_common.S"
|
||||||
|
|
||||||
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator64_start)
|
||||||
|
PREAMBLE
|
||||||
|
#ifndef __x86_64__
|
||||||
|
DISABLE_PAGING
|
||||||
|
|
||||||
|
/* Turn on PAE. */
|
||||||
|
movl %cr4, %eax
|
||||||
|
orl $(GRUB_MEMORY_CPU_CR4_PAE_ON | GRUB_MEMORY_CPU_CR4_PSE_ON), %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
/* mov imm32, %eax */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator64_cr3)
|
||||||
|
.long 0
|
||||||
|
movl %eax, %cr3
|
||||||
|
|
||||||
|
/* Turn on amd64. */
|
||||||
|
movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $GRUB_MEMORY_CPU_AMD64_MSR_ON, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Enable paging. */
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $GRUB_MEMORY_CPU_CR0_PAGING_ON, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
RELOAD_GDT
|
||||||
|
#else
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator64_cr3)
|
||||||
|
.quad 0
|
||||||
|
movq %rax, %cr3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.code64
|
||||||
|
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator64_rsp)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
movq %rax, %rsp
|
||||||
|
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator64_rsi)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
movq %rax, %rsi
|
||||||
|
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator64_rax)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
/* mov imm64, %rbx */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xbb
|
||||||
|
VARIABLE(grub_relocator64_rbx)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
/* mov imm64, %rcx */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb9
|
||||||
|
VARIABLE(grub_relocator64_rcx)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
/* mov imm64, %rdx */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xba
|
||||||
|
VARIABLE(grub_relocator64_rdx)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
/* Cleared direction flag is of no problem with any current
|
||||||
|
payload and makes this implementation easier. */
|
||||||
|
cld
|
||||||
|
|
||||||
|
jmp *LOCAL(jump_addr) (%rip)
|
||||||
|
|
||||||
|
LOCAL(jump_addr):
|
||||||
|
VARIABLE(grub_relocator64_rip)
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
|
.p2align 4
|
||||||
|
LOCAL(gdt):
|
||||||
|
/* NULL. */
|
||||||
|
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
/* 64-bit segment. */
|
||||||
|
.word 0xffff /* Limit xffff. */
|
||||||
|
.word 0x0000 /* Base xxxx0000. */
|
||||||
|
.byte 0x00 /* Base xx00xxxx. */
|
||||||
|
.byte (0x8 /* Type 8. */ | (1 << 4) /* Code. */ \
|
||||||
|
| (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */)
|
||||||
|
.byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \
|
||||||
|
| (1 << 5) /* 64-bit. */ | (0 << 6) \
|
||||||
|
| (1 << 7) /* 4K granular. */)
|
||||||
|
.byte 0x00 /* Base 00xxxxxx. */
|
||||||
|
|
||||||
|
/* Data segment*/
|
||||||
|
.word 0xffff /* Limit xffff. */
|
||||||
|
.word 0x0000 /* Base xxxx0000. */
|
||||||
|
.byte 0x00 /* Base xx00xxxx. */
|
||||||
|
.byte (0x0 /* Type 0. */ | (0 << 4) /* Data. */ \
|
||||||
|
| (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */)
|
||||||
|
.byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \
|
||||||
|
| (0 << 5) /* Data. */ | (0 << 6) \
|
||||||
|
| (1 << 7) /* 4K granular. */)
|
||||||
|
.byte 0x00 /* Base 00xxxxxx. */
|
||||||
|
|
||||||
|
/* Compatibility segment. */
|
||||||
|
.word 0xffff /* Limit xffff. */
|
||||||
|
.word 0x0000 /* Base xxxx0000. */
|
||||||
|
.byte 0x00 /* Base xx00xxxx. */
|
||||||
|
.byte (0x8 /* Type 8. */ | (1 << 4) /* Code. */ \
|
||||||
|
| (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */)
|
||||||
|
.byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \
|
||||||
|
| (0 << 5) /* 32-bit. */ | (1 << 6) /* 32-bit. */ \
|
||||||
|
| (1 << 7) /* 4K granular. */)
|
||||||
|
.byte 0x00 /* Base 00xxxxxx. */
|
||||||
|
|
||||||
|
LOCAL(gdt_end):
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator64_end)
|
|
@ -19,232 +19,62 @@
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/i386/memory.h>
|
#include <grub/i386/memory.h>
|
||||||
|
|
||||||
#ifdef BACKWARD
|
.p2align 2
|
||||||
#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x)
|
|
||||||
#else
|
|
||||||
#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x)
|
|
||||||
#endif
|
|
||||||
#ifdef __x86_64__
|
|
||||||
#define RAX %rax
|
|
||||||
#define RCX %rcx
|
|
||||||
#define RDI %rdi
|
|
||||||
#define RSI %rdi
|
|
||||||
#else
|
|
||||||
#define RAX %eax
|
|
||||||
#define RCX %ecx
|
|
||||||
#define RDI %edi
|
|
||||||
#define RSI %esi
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The code segment of the protected mode. */
|
VARIABLE(grub_relocator_backward_start)
|
||||||
#define CODE_SEGMENT 0x10
|
|
||||||
|
|
||||||
/* The data segment of the protected mode. */
|
|
||||||
#define DATA_SEGMENT 0x18
|
|
||||||
|
|
||||||
.p2align 4 /* force 16-byte alignment */
|
|
||||||
|
|
||||||
RELOCATOR_VARIABLE(start)
|
|
||||||
#ifdef BACKWARD
|
|
||||||
LOCAL(base):
|
|
||||||
#endif
|
|
||||||
cli
|
|
||||||
|
|
||||||
#ifndef __x86_64__
|
|
||||||
/* mov imm32, %eax */
|
/* mov imm32, %eax */
|
||||||
.byte 0xb8
|
.byte 0xb8
|
||||||
RELOCATOR_VARIABLE(dest)
|
VARIABLE(grub_relocator_backward_dest)
|
||||||
.long 0
|
.long 0
|
||||||
movl %eax, %edi
|
movl %eax, %edi
|
||||||
|
|
||||||
/* mov imm32, %eax */
|
/* mov imm32, %eax */
|
||||||
.byte 0xb8
|
.byte 0xb8
|
||||||
RELOCATOR_VARIABLE(src)
|
VARIABLE(grub_relocator_backward_src)
|
||||||
.long 0
|
.long 0
|
||||||
movl %eax, %esi
|
movl %eax, %esi
|
||||||
|
|
||||||
/* mov imm32, %ecx */
|
/* mov imm32, %ecx */
|
||||||
.byte 0xb9
|
.byte 0xb9
|
||||||
RELOCATOR_VARIABLE(size)
|
VARIABLE(grub_relocator_backward_chunk_size)
|
||||||
.long 0
|
|
||||||
#else
|
|
||||||
xorq %rax, %rax
|
|
||||||
|
|
||||||
/* mov imm32, %eax */
|
|
||||||
.byte 0xb8
|
|
||||||
RELOCATOR_VARIABLE(dest)
|
|
||||||
.long 0
|
|
||||||
movq %rax, %rdi
|
|
||||||
|
|
||||||
/* mov imm64, %rax */
|
|
||||||
.byte 0x48
|
|
||||||
.byte 0xb8
|
|
||||||
RELOCATOR_VARIABLE(src)
|
|
||||||
.long 0, 0
|
|
||||||
movq %rax, %rsi
|
|
||||||
|
|
||||||
xorq %rcx, %rcx
|
|
||||||
/* mov imm32, %ecx */
|
|
||||||
.byte 0xb9
|
|
||||||
RELOCATOR_VARIABLE(size)
|
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
#endif
|
add %ecx, %esi
|
||||||
|
add %ecx, %edi
|
||||||
mov RDI, RAX
|
|
||||||
|
|
||||||
#ifdef BACKWARD
|
|
||||||
add RCX, RSI
|
|
||||||
add RCX, RDI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BACKWARD
|
|
||||||
add RCX, RAX
|
|
||||||
#endif
|
|
||||||
add $0x3, RCX
|
|
||||||
shr $2, RCX
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef BACKWARD
|
/* Backward movsb is implicitly off-by-one. compensate that. */
|
||||||
/* Backward movsl is implicitly off-by-four. compensate that. */
|
sub $1, %esi
|
||||||
sub $4, RSI
|
sub $1, %edi
|
||||||
sub $4, RDI
|
|
||||||
|
|
||||||
/* Backward copy. */
|
/* Backward copy. */
|
||||||
std
|
std
|
||||||
|
|
||||||
rep
|
rep
|
||||||
movsl
|
movsb
|
||||||
|
VARIABLE(grub_relocator_backward_end)
|
||||||
|
|
||||||
#else
|
|
||||||
/* Forward copy. */
|
|
||||||
cld
|
|
||||||
rep
|
|
||||||
movsl
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* %rax contains now our new 'base'. */
|
|
||||||
mov RAX, RSI
|
|
||||||
add $(LOCAL(cont0) - LOCAL(base)), RAX
|
|
||||||
jmp *RAX
|
|
||||||
LOCAL(cont0):
|
|
||||||
lea (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX
|
|
||||||
movl %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
|
|
||||||
|
|
||||||
lea (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX
|
|
||||||
mov RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1)
|
|
||||||
|
|
||||||
/* Switch to compatibility mode. */
|
|
||||||
|
|
||||||
lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)
|
|
||||||
|
|
||||||
/* Update %cs. */
|
|
||||||
ljmp *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
|
|
||||||
|
|
||||||
LOCAL(cont1):
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/* Update other registers. */
|
|
||||||
movl $DATA_SEGMENT, %eax
|
|
||||||
movl %eax, %ds
|
|
||||||
movl %eax, %es
|
|
||||||
movl %eax, %fs
|
|
||||||
movl %eax, %gs
|
|
||||||
movl %eax, %ss
|
|
||||||
|
|
||||||
/* Disable paging. */
|
|
||||||
movl %cr0, %eax
|
|
||||||
andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
/* Disable amd64. */
|
|
||||||
movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
|
|
||||||
rdmsr
|
|
||||||
andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax
|
|
||||||
wrmsr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Turn off PAE. */
|
|
||||||
movl %cr4, %eax
|
|
||||||
andl $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
jmp LOCAL(cont2)
|
|
||||||
LOCAL(cont2):
|
|
||||||
.code32
|
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator_forward_start)
|
||||||
/* mov imm32, %eax */
|
/* mov imm32, %eax */
|
||||||
.byte 0xb8
|
.byte 0xb8
|
||||||
RELOCATOR_VARIABLE (esp)
|
VARIABLE(grub_relocator_forward_dest)
|
||||||
.long 0
|
.long 0
|
||||||
|
movl %eax, %edi
|
||||||
|
|
||||||
movl %eax, %esp
|
/* mov imm32, %rax */
|
||||||
|
|
||||||
/* mov imm32, %eax */
|
|
||||||
.byte 0xb8
|
.byte 0xb8
|
||||||
RELOCATOR_VARIABLE (eax)
|
VARIABLE(grub_relocator_forward_src)
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* mov imm32, %ebx */
|
|
||||||
.byte 0xbb
|
|
||||||
RELOCATOR_VARIABLE (ebx)
|
|
||||||
.long 0
|
.long 0
|
||||||
|
movl %eax, %esi
|
||||||
|
|
||||||
/* mov imm32, %ecx */
|
/* mov imm32, %ecx */
|
||||||
.byte 0xb9
|
.byte 0xb9
|
||||||
RELOCATOR_VARIABLE (ecx)
|
VARIABLE(grub_relocator_forward_chunk_size)
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
/* mov imm32, %edx */
|
/* Forward copy. */
|
||||||
.byte 0xba
|
|
||||||
RELOCATOR_VARIABLE (edx)
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Cleared direction flag is of no problem with any current
|
|
||||||
payload and makes this implementation easier. */
|
|
||||||
cld
|
cld
|
||||||
|
rep
|
||||||
.byte 0xea
|
movsb
|
||||||
RELOCATOR_VARIABLE (eip)
|
VARIABLE(grub_relocator_forward_end)
|
||||||
.long 0
|
|
||||||
.word CODE_SEGMENT
|
|
||||||
|
|
||||||
/* GDT. Copied from loader/i386/linux.c. */
|
|
||||||
.p2align 4
|
|
||||||
LOCAL(gdt):
|
|
||||||
/* NULL. */
|
|
||||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
/* Reserved. */
|
|
||||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
/* Code segment. */
|
|
||||||
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
|
|
||||||
|
|
||||||
/* Data segment. */
|
|
||||||
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
|
|
||||||
|
|
||||||
.p2align 4
|
|
||||||
LOCAL(gdtdesc):
|
|
||||||
.word 0x27
|
|
||||||
LOCAL(gdt_addr):
|
|
||||||
#ifdef __x86_64__
|
|
||||||
/* Filled by the code. */
|
|
||||||
.quad 0
|
|
||||||
#else
|
|
||||||
/* Filled by the code. */
|
|
||||||
.long 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.p2align 4
|
|
||||||
LOCAL(jump_vector):
|
|
||||||
/* Jump location. Is filled by the code */
|
|
||||||
.long 0
|
|
||||||
.long CODE_SEGMENT
|
|
||||||
|
|
||||||
#ifndef BACKWARD
|
|
||||||
LOCAL(base):
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RELOCATOR_VARIABLE(end)
|
|
||||||
|
|
82
grub-core/lib/i386/relocator_common.S
Normal file
82
grub-core/lib/i386/relocator_common.S
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/symbol.h>
|
||||||
|
#include <grub/i386/memory.h>
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define RAX %rax
|
||||||
|
#define RSI %rsi
|
||||||
|
#else
|
||||||
|
#define RAX %eax
|
||||||
|
#define RSI %esi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.macro DISABLE_PAGING
|
||||||
|
#ifdef GRUB_MACHINE_IEEE1275
|
||||||
|
#endif
|
||||||
|
|
||||||
|
movl %cr0, %eax
|
||||||
|
andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro PREAMBLE
|
||||||
|
LOCAL(base):
|
||||||
|
/* %rax contains now our new 'base'. */
|
||||||
|
mov RAX, RSI
|
||||||
|
|
||||||
|
add $(LOCAL(cont0) - LOCAL(base)), RAX
|
||||||
|
jmp *RAX
|
||||||
|
LOCAL(cont0):
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro RELOAD_GDT
|
||||||
|
lea (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX
|
||||||
|
movl %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
|
||||||
|
|
||||||
|
lea (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX
|
||||||
|
mov RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1)
|
||||||
|
|
||||||
|
/* Switch to compatibility mode. */
|
||||||
|
lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)
|
||||||
|
|
||||||
|
/* Update %cs. */
|
||||||
|
ljmp *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
LOCAL(gdtdesc):
|
||||||
|
.word LOCAL(gdt_end) - LOCAL(gdt)
|
||||||
|
LOCAL(gdt_addr):
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* Filled by the code. */
|
||||||
|
.quad 0
|
||||||
|
#else
|
||||||
|
/* Filled by the code. */
|
||||||
|
.long 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
LOCAL(jump_vector):
|
||||||
|
/* Jump location. Is filled by the code */
|
||||||
|
.long 0
|
||||||
|
.long CODE_SEGMENT
|
||||||
|
|
||||||
|
LOCAL(cont1):
|
||||||
|
.endm
|
|
@ -1,7 +1,7 @@
|
||||||
/* init.c -- Initialize GRUB on Open Firmware. */
|
/* openfw.c -- Open firmware support functions. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
|
* Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,12 +17,17 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/types.h>
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
#include <grub/cache.h>
|
#include <grub/misc.h>
|
||||||
|
|
||||||
void grub_stop_floppy (void);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_stop_floppy (void)
|
grub_halt (void)
|
||||||
{
|
{
|
||||||
|
/* Not standardized. We try three known commands. */
|
||||||
|
|
||||||
|
grub_ieee1275_interpret ("shut-down", 0);
|
||||||
|
grub_ieee1275_interpret ("power-off", 0);
|
||||||
|
grub_ieee1275_interpret ("poweroff", 0);
|
||||||
|
|
||||||
|
while (1);
|
||||||
}
|
}
|
95
grub-core/lib/ieee1275/relocator.c
Normal file
95
grub-core/lib/ieee1275/relocator.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2010 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/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
#include <grub/memory.h>
|
||||||
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
grub_relocator_firmware_get_max_events (void)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
auto int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)),
|
||||||
|
grub_uint64_t len __attribute__ ((unused)),
|
||||||
|
grub_uint32_t type __attribute__ ((unused)));
|
||||||
|
int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)),
|
||||||
|
grub_uint64_t len __attribute__ ((unused)),
|
||||||
|
grub_uint32_t type __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
|
||||||
|
return 0;
|
||||||
|
grub_machine_mmap_iterate (count);
|
||||||
|
return 2 * counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
auto int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
|
||||||
|
grub_uint32_t type);
|
||||||
|
int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
|
||||||
|
grub_uint32_t type)
|
||||||
|
{
|
||||||
|
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
|
||||||
|
{
|
||||||
|
if (addr + len <= 0x180000)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (addr < 0x180000)
|
||||||
|
{
|
||||||
|
len = addr + len - 0x180000;
|
||||||
|
addr = 0x180000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events[counter].type = REG_FIRMWARE_START;
|
||||||
|
events[counter].pos = addr;
|
||||||
|
counter++;
|
||||||
|
events[counter].type = REG_FIRMWARE_END;
|
||||||
|
events[counter].pos = addr + len;
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
|
||||||
|
return 0;
|
||||||
|
grub_machine_mmap_iterate (fill);
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size)
|
||||||
|
{
|
||||||
|
return (grub_claimmap (start, size) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_relocator_firmware_free_region (grub_addr_t start, grub_size_t size)
|
||||||
|
{
|
||||||
|
grub_ieee1275_release (start, size);
|
||||||
|
}
|
|
@ -25,26 +25,33 @@
|
||||||
#include <grub/cache.h>
|
#include <grub/cache.h>
|
||||||
|
|
||||||
#include <grub/mips/relocator.h>
|
#include <grub/mips/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
|
||||||
/* Remark: doesn't work with source outside of 4G.
|
/* Do we need mips64? */
|
||||||
Use relocator64 in this case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern grub_uint8_t grub_relocator32_forward_start;
|
extern grub_uint8_t grub_relocator_forward_start;
|
||||||
extern grub_uint8_t grub_relocator32_forward_end;
|
extern grub_uint8_t grub_relocator_forward_end;
|
||||||
extern grub_uint8_t grub_relocator32_backward_start;
|
extern grub_uint8_t grub_relocator_backward_start;
|
||||||
extern grub_uint8_t grub_relocator32_backward_end;
|
extern grub_uint8_t grub_relocator_backward_end;
|
||||||
|
|
||||||
#define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
|
#define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
|
||||||
#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
|
#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
|
||||||
|
|
||||||
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \
|
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \
|
||||||
- &grub_relocator32_##x##_start)
|
- &grub_relocator_##x##_start)
|
||||||
#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
|
#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
|
||||||
+ REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF)
|
+ REGW_SIZEOF * 3)
|
||||||
#define RELOCATOR_ALIGN 16
|
grub_size_t grub_relocator_align = sizeof (grub_uint32_t);
|
||||||
|
grub_size_t grub_relocator_forward_size;
|
||||||
|
grub_size_t grub_relocator_backward_size;
|
||||||
|
grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF;
|
||||||
|
|
||||||
#define PREFIX(x) grub_relocator32_ ## x
|
void
|
||||||
|
grub_cpu_relocator_init (void)
|
||||||
|
{
|
||||||
|
grub_relocator_forward_size = RELOCATOR_SIZEOF(forward);
|
||||||
|
grub_relocator_backward_size = RELOCATOR_SIZEOF(backward);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_reg (int regn, grub_uint32_t val, void **target)
|
write_reg (int regn, grub_uint32_t val, void **target)
|
||||||
|
@ -69,44 +76,74 @@ write_jump (int regn, void **target)
|
||||||
*target = ((grub_uint32_t *) *target) + 1;
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest,
|
grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
|
||||||
grub_size_t size, struct grub_relocator32_state state)
|
{
|
||||||
|
write_reg (1, addr, &rels);
|
||||||
|
write_jump (1, &rels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_backward (void *ptr0, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = ptr0;
|
void *ptr = ptr0;
|
||||||
int i;
|
|
||||||
write_reg (8, (grub_uint32_t) src, &ptr);
|
write_reg (8, (grub_uint32_t) src, &ptr);
|
||||||
write_reg (9, dest, &ptr);
|
write_reg (9, (grub_uint32_t) dest, &ptr);
|
||||||
write_reg (10, size, &ptr);
|
write_reg (10, (grub_uint32_t) size, &ptr);
|
||||||
grub_memcpy (ptr, &grub_relocator32_backward_start,
|
grub_memcpy (ptr, &grub_relocator_backward_start,
|
||||||
RELOCATOR_SRC_SIZEOF (backward));
|
RELOCATOR_SRC_SIZEOF (backward));
|
||||||
ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward);
|
|
||||||
for (i = 1; i < 32; i++)
|
|
||||||
write_reg (i, state.gpr[i], &ptr);
|
|
||||||
write_jump (state.jumpreg, &ptr);
|
|
||||||
grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0);
|
|
||||||
grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0);
|
|
||||||
((void (*) (void)) ptr0) ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest,
|
grub_cpu_relocator_forward (void *ptr0, void *src, void *dest,
|
||||||
grub_size_t size, struct grub_relocator32_state state)
|
grub_size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = ptr0;
|
void *ptr = ptr0;
|
||||||
int i;
|
|
||||||
write_reg (8, (grub_uint32_t) src, &ptr);
|
write_reg (8, (grub_uint32_t) src, &ptr);
|
||||||
write_reg (9, dest, &ptr);
|
write_reg (9, (grub_uint32_t) dest, &ptr);
|
||||||
write_reg (10, size, &ptr);
|
write_reg (10, (grub_uint32_t) size, &ptr);
|
||||||
grub_memcpy (ptr, &grub_relocator32_forward_start,
|
grub_memcpy (ptr, &grub_relocator_forward_start,
|
||||||
RELOCATOR_SRC_SIZEOF (forward));
|
RELOCATOR_SRC_SIZEOF (forward));
|
||||||
ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward);
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator32_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator32_state state)
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
void *ptr;
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_size_t relsize;
|
||||||
|
grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF;
|
||||||
|
unsigned i;
|
||||||
|
grub_addr_t vtarget;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
|
(0xffffffff - stateset_size)
|
||||||
|
+ 1, stateset_size,
|
||||||
|
sizeof (grub_uint32_t),
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ptr = get_virtual_current_address (ch);
|
||||||
for (i = 1; i < 32; i++)
|
for (i = 1; i < 32; i++)
|
||||||
write_reg (i, state.gpr[i], &ptr);
|
write_reg (i, state.gpr[i], &ptr);
|
||||||
write_jump (state.jumpreg, &ptr);
|
write_jump (state.jumpreg, &ptr);
|
||||||
grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0);
|
|
||||||
grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0);
|
|
||||||
((void (*) (void)) ptr0) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../relocator.c"
|
vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch),
|
||||||
|
stateset_size);
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_arch_sync_caches ((void *) relst, relsize);
|
||||||
|
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
|
@ -20,39 +20,39 @@
|
||||||
|
|
||||||
.p2align 4 /* force 16-byte alignment */
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
VARIABLE (grub_relocator32_forward_start)
|
VARIABLE (grub_relocator_forward_start)
|
||||||
move $a0, $9
|
move $a0, $9
|
||||||
move $a1, $10
|
move $a1, $10
|
||||||
|
|
||||||
copycont1:
|
copycont1:
|
||||||
lb $11,0($8)
|
lb $11,0($8)
|
||||||
sb $11,0($9)
|
sb $11,0($9)
|
||||||
addiu $8, $8, 0x1
|
addiu $8, $8, 1
|
||||||
addiu $9, $9, 0x1
|
addiu $9, $9, 1
|
||||||
addiu $10, $10, 0xffff
|
addiu $10, $10, -1
|
||||||
bne $10, $0, copycont1
|
bne $10, $0, copycont1
|
||||||
|
|
||||||
#include "../../kern/mips/cache_flush.S"
|
#include "../../kern/mips/cache_flush.S"
|
||||||
|
|
||||||
VARIABLE (grub_relocator32_forward_end)
|
VARIABLE (grub_relocator_forward_end)
|
||||||
|
|
||||||
VARIABLE (grub_relocator32_backward_start)
|
VARIABLE (grub_relocator_backward_start)
|
||||||
move $a0, $9
|
move $a0, $9
|
||||||
move $a1, $10
|
move $a1, $10
|
||||||
|
|
||||||
addu $9, $9, $10
|
addu $9, $9, $10
|
||||||
addu $8, $8, $10
|
addu $8, $8, $10
|
||||||
/* Backward movsl is implicitly off-by-one. compensate that. */
|
/* Backward movsl is implicitly off-by-one. compensate that. */
|
||||||
addiu $9, $9, 0xffff
|
addiu $9, $9, -1
|
||||||
addiu $8, $8, 0xffff
|
addiu $8, $8, -1
|
||||||
copycont2:
|
copycont2:
|
||||||
lb $11,0($8)
|
lb $11,0($8)
|
||||||
sb $11,0($9)
|
sb $11,0($9)
|
||||||
addiu $8, $8, 0xffff
|
addiu $8, $8, -1
|
||||||
addiu $9, $9, 0xffff
|
addiu $9, $9, -1
|
||||||
addiu $10, 0xffff
|
addiu $10, $10, -1
|
||||||
bne $10, $0, copycont2
|
bne $10, $0, copycont2
|
||||||
|
|
||||||
#include "../../kern/mips/cache_flush.S"
|
#include "../../kern/mips/cache_flush.S"
|
||||||
|
|
||||||
VARIABLE (grub_relocator32_backward_end)
|
VARIABLE (grub_relocator_backward_end)
|
||||||
|
|
142
grub-core/lib/powerpc/relocator.c
Normal file
142
grub-core/lib/powerpc/relocator.c
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
|
||||||
|
#include <grub/powerpc/relocator.h>
|
||||||
|
#include <grub/relocator_private.h>
|
||||||
|
|
||||||
|
extern grub_uint8_t grub_relocator_forward_start;
|
||||||
|
extern grub_uint8_t grub_relocator_forward_end;
|
||||||
|
extern grub_uint8_t grub_relocator_backward_start;
|
||||||
|
extern grub_uint8_t grub_relocator_backward_end;
|
||||||
|
|
||||||
|
#define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
|
||||||
|
#define JUMP_SIZEOF (sizeof (grub_uint32_t))
|
||||||
|
|
||||||
|
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \
|
||||||
|
- &grub_relocator_##x##_start)
|
||||||
|
#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
|
||||||
|
+ REGW_SIZEOF * 3)
|
||||||
|
grub_size_t grub_relocator_align = sizeof (grub_uint32_t);
|
||||||
|
grub_size_t grub_relocator_forward_size;
|
||||||
|
grub_size_t grub_relocator_backward_size;
|
||||||
|
grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF;
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_init (void)
|
||||||
|
{
|
||||||
|
grub_relocator_forward_size = RELOCATOR_SIZEOF(forward);
|
||||||
|
grub_relocator_backward_size = RELOCATOR_SIZEOF(backward);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_reg (int regn, grub_uint32_t val, void **target)
|
||||||
|
{
|
||||||
|
/* lis r, val >> 16 */
|
||||||
|
*(grub_uint32_t *) *target =
|
||||||
|
((0x3c00 | (regn << 5)) << 16) | (val >> 16);
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
/* ori r, r, val & 0xffff. */
|
||||||
|
*(grub_uint32_t *) *target = (((0x6000 | regn << 5 | regn) << 16)
|
||||||
|
| (val & 0xffff));
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_jump (void **target)
|
||||||
|
{
|
||||||
|
/* blr. */
|
||||||
|
*(grub_uint32_t *) *target = 0x4e800020;
|
||||||
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
|
||||||
|
{
|
||||||
|
write_reg (GRUB_PPC_JUMP_REGISTER, addr, &rels);
|
||||||
|
write_jump (&rels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_backward (void *ptr0, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = ptr0;
|
||||||
|
write_reg (8, (grub_uint32_t) src, &ptr);
|
||||||
|
write_reg (9, (grub_uint32_t) dest, &ptr);
|
||||||
|
write_reg (10, (grub_uint32_t) size, &ptr);
|
||||||
|
grub_memcpy (ptr, &grub_relocator_backward_start,
|
||||||
|
RELOCATOR_SRC_SIZEOF (backward));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cpu_relocator_forward (void *ptr0, void *src, void *dest,
|
||||||
|
grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = ptr0;
|
||||||
|
write_reg (8, (grub_uint32_t) src, &ptr);
|
||||||
|
write_reg (9, (grub_uint32_t) dest, &ptr);
|
||||||
|
write_reg (10, (grub_uint32_t) size, &ptr);
|
||||||
|
grub_memcpy (ptr, &grub_relocator_forward_start,
|
||||||
|
RELOCATOR_SRC_SIZEOF (forward));
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_relocator32_boot (struct grub_relocator *rel,
|
||||||
|
struct grub_relocator32_state state)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
grub_err_t err;
|
||||||
|
void *relst;
|
||||||
|
grub_size_t relsize;
|
||||||
|
grub_size_t stateset_size = 32 * REGW_SIZEOF + JUMP_SIZEOF;
|
||||||
|
unsigned i;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||||
|
(0xffffffff - stateset_size)
|
||||||
|
+ 1, stateset_size,
|
||||||
|
sizeof (grub_uint32_t),
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ptr = get_virtual_current_address (ch);
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
write_reg (i, state.gpr[i], &ptr);
|
||||||
|
write_jump (&ptr);
|
||||||
|
|
||||||
|
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||||
|
&relst, &relsize);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_arch_sync_caches ((void *) relst, relsize);
|
||||||
|
|
||||||
|
((void (*) (void)) relst) ();
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
60
grub-core/lib/powerpc/relocator_asm.S
Normal file
60
grub-core/lib/powerpc/relocator_asm.S
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009,2010 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/symbol.h>
|
||||||
|
|
||||||
|
.p2align 4 /* force 16-byte alignment */
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_forward_start)
|
||||||
|
mr 3, 9
|
||||||
|
mr 4, 10
|
||||||
|
|
||||||
|
copycont1:
|
||||||
|
lbz 11,0(8)
|
||||||
|
stb 11,0(9)
|
||||||
|
addi 8, 8, 0x1
|
||||||
|
addi 9, 9, 0x1
|
||||||
|
addi 10, 10, -1
|
||||||
|
cmpwi 10, 0
|
||||||
|
bne copycont1
|
||||||
|
|
||||||
|
#include "../../kern/powerpc/cache_flush.S"
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_forward_end)
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_backward_start)
|
||||||
|
mr 3, 9
|
||||||
|
mr 4, 10
|
||||||
|
|
||||||
|
add 9, 9, 10
|
||||||
|
add 8, 8, 10
|
||||||
|
/* Backward movsl is implicitly off-by-one. compensate that. */
|
||||||
|
addi 9, 9, -1
|
||||||
|
addi 8, 8, -1
|
||||||
|
copycont2:
|
||||||
|
lbz 11,0(8)
|
||||||
|
stb 11,0(9)
|
||||||
|
addi 8, 8, -1
|
||||||
|
addi 9, 9, -1
|
||||||
|
addi 10, 10, -1
|
||||||
|
cmpwi 10, 0
|
||||||
|
bne copycont2
|
||||||
|
|
||||||
|
#include "../../kern/powerpc/cache_flush.S"
|
||||||
|
|
||||||
|
VARIABLE (grub_relocator_backward_end)
|
File diff suppressed because it is too large
Load diff
85
grub-core/lib/x86_64/relocator_asm.S
Normal file
85
grub-core/lib/x86_64/relocator_asm.S
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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/symbol.h>
|
||||||
|
#include <grub/i386/memory.h>
|
||||||
|
|
||||||
|
.p2align 2
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator_backward_start)
|
||||||
|
/* mov imm32, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator_backward_dest)
|
||||||
|
.long 0, 0
|
||||||
|
movq %rax, %rdi
|
||||||
|
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator_backward_src)
|
||||||
|
.long 0, 0
|
||||||
|
movq %rax, %rsi
|
||||||
|
|
||||||
|
/* mov imm64, %rcx */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb9
|
||||||
|
VARIABLE(grub_relocator_backward_chunk_size)
|
||||||
|
.long 0, 0
|
||||||
|
|
||||||
|
add %rcx, %rsi
|
||||||
|
add %rcx, %rdi
|
||||||
|
|
||||||
|
/* Backward movsb is implicitly off-by-one. compensate that. */
|
||||||
|
sub $1, %rsi
|
||||||
|
sub $1, %rdi
|
||||||
|
|
||||||
|
/* Backward copy. */
|
||||||
|
std
|
||||||
|
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
VARIABLE(grub_relocator_backward_end)
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE(grub_relocator_forward_start)
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator_forward_dest)
|
||||||
|
.long 0, 0
|
||||||
|
movq %rax, %rdi
|
||||||
|
|
||||||
|
/* mov imm64, %rax */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator_forward_src)
|
||||||
|
.long 0, 0
|
||||||
|
movq %rax, %rsi
|
||||||
|
|
||||||
|
/* mov imm64, %rcx */
|
||||||
|
.byte 0x48
|
||||||
|
.byte 0xb9
|
||||||
|
VARIABLE(grub_relocator_forward_chunk_size)
|
||||||
|
.long 0, 0
|
||||||
|
|
||||||
|
/* Forward copy. */
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
VARIABLE(grub_relocator_forward_end)
|
|
@ -39,9 +39,8 @@ grub_aout_get_type (union grub_aout_header *header)
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_aout_load (grub_file_t file, int offset,
|
grub_aout_load (grub_file_t file, int offset,
|
||||||
grub_addr_t load_addr,
|
void *load_addr,
|
||||||
int load_size,
|
int load_size, grub_size_t bss_size)
|
||||||
grub_addr_t bss_end_addr)
|
|
||||||
{
|
{
|
||||||
if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
|
if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -49,14 +48,13 @@ grub_aout_load (grub_file_t file, int offset,
|
||||||
if (!load_size)
|
if (!load_size)
|
||||||
load_size = file->size - offset;
|
load_size = file->size - offset;
|
||||||
|
|
||||||
grub_file_read (file, (void *) load_addr, load_size);
|
grub_file_read (file, load_addr, load_size);
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (bss_end_addr)
|
if (bss_size)
|
||||||
grub_memset ((char *) load_addr + load_size, 0,
|
grub_memset ((char *) load_addr + load_size, 0, bss_size);
|
||||||
bss_end_addr - load_addr - load_size);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,22 +1,18 @@
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/cpu/bsd.h>
|
#include <grub/i386/bsd.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/elf.h>
|
#include <grub/elf.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/i386/loader.h>
|
#include <grub/i386/relocator.h>
|
||||||
|
|
||||||
#define ALIGN_PAGE(a) ALIGN_UP (a, 4096)
|
#define ALIGN_PAGE(a) ALIGN_UP (a, 4096)
|
||||||
|
|
||||||
static inline grub_err_t
|
static inline grub_err_t
|
||||||
load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
|
load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
|
||||||
{
|
{
|
||||||
if (PTR_TO_UINT32 (where) + size > grub_os_area_addr + grub_os_area_size)
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
|
||||||
"not enough memory for the module");
|
|
||||||
if (grub_file_seek (file, off) == (grub_off_t) -1)
|
if (grub_file_seek (file, off) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
if (grub_file_read (file, where, size)
|
if (grub_file_read (file, where, size) != (grub_ssize_t) size)
|
||||||
!= (grub_ssize_t) size)
|
|
||||||
{
|
{
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -75,7 +71,8 @@ read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr)
|
||||||
platforms. So I keep both versions. */
|
platforms. So I keep both versions. */
|
||||||
#if OBJSYM
|
#if OBJSYM
|
||||||
grub_err_t
|
grub_err_t
|
||||||
SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
|
||||||
|
grub_file_t file, int argc,
|
||||||
char *argv[], grub_addr_t *kern_end)
|
char *argv[], grub_addr_t *kern_end)
|
||||||
{
|
{
|
||||||
Elf_Ehdr e;
|
Elf_Ehdr e;
|
||||||
|
@ -83,6 +80,8 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
||||||
char *shdr = 0;
|
char *shdr = 0;
|
||||||
grub_addr_t curload, module;
|
grub_addr_t curload, module;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
grub_size_t chunk_size = 0;
|
||||||
|
void *chunk_src;
|
||||||
|
|
||||||
err = read_headers (file, &e, &shdr);
|
err = read_headers (file, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -90,6 +89,29 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
||||||
|
|
||||||
curload = module = ALIGN_PAGE (*kern_end);
|
curload = module = ALIGN_PAGE (*kern_end);
|
||||||
|
|
||||||
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
{
|
||||||
|
if (s->sh_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (s->sh_addralign)
|
||||||
|
chunk_size = ALIGN_UP (chunk_size + *kern_end, s->sh_addralign)
|
||||||
|
- *kern_end;
|
||||||
|
|
||||||
|
chunk_size += s->sh_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
module, chunk_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
chunk_src = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
@ -109,15 +131,14 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case SHT_PROGBITS:
|
case SHT_PROGBITS:
|
||||||
err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size);
|
err = load (file, (grub_uint8_t *) chunk_src + curload - *kern_end,
|
||||||
|
s->sh_offset, s->sh_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SHT_NOBITS:
|
case SHT_NOBITS:
|
||||||
if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size)
|
grub_memset ((grub_uint8_t *) chunk_src + curload - *kern_end, 0,
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
s->sh_size);
|
||||||
"not enough memory for the module");
|
|
||||||
grub_memset (UINT_TO_PTR (curload), 0, s->sh_size);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
curload += s->sh_size;
|
curload += s->sh_size;
|
||||||
|
@ -129,13 +150,13 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
||||||
argc - 1, argv + 1, module,
|
argc - 1, argv + 1, module,
|
||||||
curload - module);
|
curload - module);
|
||||||
if (! err)
|
if (! err)
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA
|
||||||
| FREEBSD_MODINFOMD_ELFHDR,
|
| FREEBSD_MODINFOMD_ELFHDR,
|
||||||
&e, sizeof (e));
|
&e, sizeof (e));
|
||||||
if (! err)
|
if (! err)
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA
|
||||||
| FREEBSD_MODINFOMD_SHDR,
|
| FREEBSD_MODINFOMD_SHDR,
|
||||||
shdr, e.e_shnum * e.e_shentsize);
|
shdr, e.e_shnum * e.e_shentsize);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +164,8 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
|
||||||
#else
|
#else
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
|
SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||||
|
grub_file_t file, int argc, char *argv[],
|
||||||
grub_addr_t *kern_end)
|
grub_addr_t *kern_end)
|
||||||
{
|
{
|
||||||
Elf_Ehdr e;
|
Elf_Ehdr e;
|
||||||
|
@ -151,6 +173,8 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
|
||||||
char *shdr = 0;
|
char *shdr = 0;
|
||||||
grub_addr_t curload, module;
|
grub_addr_t curload, module;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
grub_size_t chunk_size = 0;
|
||||||
|
void *chunk_src;
|
||||||
|
|
||||||
err = read_headers (file, &e, &shdr);
|
err = read_headers (file, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -158,6 +182,30 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
|
||||||
|
|
||||||
curload = module = ALIGN_PAGE (*kern_end);
|
curload = module = ALIGN_PAGE (*kern_end);
|
||||||
|
|
||||||
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
{
|
||||||
|
if (s->sh_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (! (s->sh_flags & SHF_ALLOC))
|
||||||
|
continue;
|
||||||
|
if (chunk_size < s->sh_addr + s->sh_size)
|
||||||
|
chunk_size = s->sh_addr + s->sh_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
module, chunk_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
chunk_src = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
|
||||||
+ e.e_shnum * e.e_shentsize);
|
+ e.e_shnum * e.e_shentsize);
|
||||||
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
@ -176,17 +224,15 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case SHT_PROGBITS:
|
case SHT_PROGBITS:
|
||||||
err = load (file, UINT_TO_PTR (module + s->sh_addr),
|
err = load (file, (grub_uint8_t *) chunk_src + module
|
||||||
|
+ s->sh_addr - *kern_end,
|
||||||
s->sh_offset, s->sh_size);
|
s->sh_offset, s->sh_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SHT_NOBITS:
|
case SHT_NOBITS:
|
||||||
if (module + s->sh_addr + s->sh_size
|
grub_memset ((grub_uint8_t *) chunk_src + module
|
||||||
> grub_os_area_addr + grub_os_area_size)
|
+ s->sh_addr - *kern_end, 0, s->sh_size);
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
|
||||||
"not enough memory for the module");
|
|
||||||
grub_memset (UINT_TO_PTR (module + s->sh_addr), 0, s->sh_size);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (curload < module + s->sh_addr + s->sh_size)
|
if (curload < module + s->sh_addr + s->sh_size)
|
||||||
|
@ -212,32 +258,36 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
|
||||||
grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
|
grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
|
||||||
argc - 1, argv + 1, module,
|
argc - 1, argv + 1, module,
|
||||||
curload - module);
|
curload - module);
|
||||||
return SUFFIX (grub_freebsd_load_elf_meta) (file, kern_end);
|
return SUFFIX (grub_freebsd_load_elf_meta) (relocator, file, kern_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
|
SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
|
grub_file_t file, grub_addr_t *kern_end)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
Elf_Ehdr e;
|
Elf_Ehdr e;
|
||||||
Elf_Shdr *s;
|
Elf_Shdr *s;
|
||||||
char *shdr = 0;
|
char *shdr = 0;
|
||||||
unsigned symoff, stroff, symsize, strsize;
|
unsigned symoff, stroff, symsize, strsize;
|
||||||
grub_addr_t curload;
|
|
||||||
grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
|
grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
|
void *sym_chunk;
|
||||||
|
grub_uint8_t *curload;
|
||||||
|
grub_freebsd_addr_t symtarget;
|
||||||
const char *str;
|
const char *str;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
grub_size_t chunk_size;
|
||||||
|
|
||||||
err = read_headers (file, &e, &shdr);
|
err = read_headers (file, &e, &shdr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_ELFHDR, &e,
|
FREEBSD_MODINFOMD_ELFHDR, &e,
|
||||||
sizeof (e));
|
sizeof (e));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -256,19 +306,31 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
|
||||||
stroff = s->sh_offset;
|
stroff = s->sh_offset;
|
||||||
strsize = s->sh_size;
|
strsize = s->sh_size;
|
||||||
|
|
||||||
if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize
|
chunk_size = ALIGN_UP (symsize + strsize, sizeof (grub_freebsd_addr_t))
|
||||||
> grub_os_area_addr + grub_os_area_size)
|
+ 2 * sizeof (grub_freebsd_addr_t);
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
|
||||||
"not enough memory for kernel symbols");
|
|
||||||
|
|
||||||
symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
|
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
|
||||||
*((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize;
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
symtarget, chunk_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
sym_chunk = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
symstart = symtarget;
|
||||||
|
symend = symstart + chunk_size;
|
||||||
|
|
||||||
|
curload = sym_chunk;
|
||||||
|
*((grub_freebsd_addr_t *) curload) = symsize;
|
||||||
curload += sizeof (grub_freebsd_addr_t);
|
curload += sizeof (grub_freebsd_addr_t);
|
||||||
|
|
||||||
if (grub_file_seek (file, symoff) == (grub_off_t) -1)
|
if (grub_file_seek (file, symoff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
sym = (Elf_Sym *) UINT_TO_PTR (curload);
|
sym = (Elf_Sym *) curload;
|
||||||
if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
|
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
||||||
(grub_ssize_t) symsize)
|
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
|
@ -276,21 +338,17 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
|
||||||
}
|
}
|
||||||
curload += symsize;
|
curload += symsize;
|
||||||
|
|
||||||
*((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize;
|
*((grub_freebsd_addr_t *) curload) = strsize;
|
||||||
curload += sizeof (grub_freebsd_addr_t);
|
curload += sizeof (grub_freebsd_addr_t);
|
||||||
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
str = (char *) UINT_TO_PTR (curload);
|
str = (char *) curload;
|
||||||
if (grub_file_read (file, UINT_TO_PTR (curload), strsize)
|
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
||||||
!= (grub_ssize_t) strsize)
|
|
||||||
{
|
{
|
||||||
if (! grub_errno)
|
if (! grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
curload += strsize;
|
|
||||||
curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t));
|
|
||||||
symend = curload;
|
|
||||||
|
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
i * symentsize < symsize;
|
i * symentsize < symsize;
|
||||||
|
@ -305,25 +363,258 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
|
||||||
{
|
{
|
||||||
dynamic = sym->st_value;
|
dynamic = sym->st_value;
|
||||||
grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
|
grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
|
FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
|
||||||
sizeof (dynamic));
|
sizeof (dynamic));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_SSYM, &symstart,
|
FREEBSD_MODINFOMD_SSYM, &symstart,
|
||||||
sizeof (symstart));
|
sizeof (symstart));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
|
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
|
||||||
FREEBSD_MODINFOMD_ESYM, &symend,
|
FREEBSD_MODINFOMD_ESYM, &symend,
|
||||||
sizeof (symend));
|
sizeof (symend));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
*kern_end = ALIGN_PAGE (curload);
|
|
||||||
|
*kern_end = ALIGN_PAGE (symend);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||||
|
grub_file_t file, grub_addr_t *kern_end)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
Elf_Ehdr e;
|
||||||
|
Elf_Shdr *s, *symsh, *strsh;
|
||||||
|
char *shdr;
|
||||||
|
unsigned symsize, strsize;
|
||||||
|
Elf_Sym *sym;
|
||||||
|
void *sym_chunk;
|
||||||
|
grub_uint8_t *curload;
|
||||||
|
const char *str;
|
||||||
|
grub_size_t chunk_size;
|
||||||
|
Elf_Ehdr *e2;
|
||||||
|
struct grub_netbsd_btinfo_symtab symtab;
|
||||||
|
grub_addr_t symtarget;
|
||||||
|
|
||||||
|
err = read_headers (file, &e, &shdr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
if (s->sh_type == SHT_SYMTAB)
|
||||||
|
break;
|
||||||
|
if (s >= (Elf_Shdr *) ((char *) shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize))
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
symsize = s->sh_size;
|
||||||
|
symsh = s;
|
||||||
|
s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
|
||||||
|
strsize = s->sh_size;
|
||||||
|
strsh = s;
|
||||||
|
|
||||||
|
chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||||
|
+ ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t))
|
||||||
|
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||||
|
|
||||||
|
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
symtarget, chunk_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
sym_chunk = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
symtab.nsyms = 1;
|
||||||
|
symtab.ssyms = symtarget;
|
||||||
|
symtab.esyms = symtarget + chunk_size;
|
||||||
|
|
||||||
|
curload = sym_chunk;
|
||||||
|
|
||||||
|
e2 = (Elf_Ehdr *) curload;
|
||||||
|
grub_memcpy (curload, &e, sizeof (e));
|
||||||
|
e2->e_phoff = 0;
|
||||||
|
e2->e_phnum = 0;
|
||||||
|
e2->e_phentsize = 0;
|
||||||
|
e2->e_shstrndx = 0;
|
||||||
|
e2->e_shoff = sizeof (e);
|
||||||
|
|
||||||
|
curload += sizeof (e);
|
||||||
|
|
||||||
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
{
|
||||||
|
Elf_Shdr *s2;
|
||||||
|
s2 = (Elf_Shdr *) curload;
|
||||||
|
grub_memcpy (curload, s, e.e_shentsize);
|
||||||
|
if (s == symsh)
|
||||||
|
s2->sh_offset = sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||||
|
else if (s == strsh)
|
||||||
|
s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||||
|
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||||
|
else
|
||||||
|
s2->sh_offset = 0;
|
||||||
|
s2->sh_addr = s2->sh_offset;
|
||||||
|
curload += e.e_shentsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_seek (file, symsh->sh_offset) == (grub_off_t) -1)
|
||||||
|
return grub_errno;
|
||||||
|
sym = (Elf_Sym *) curload;
|
||||||
|
if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize)
|
||||||
|
{
|
||||||
|
if (! grub_errno)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
curload += ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t));
|
||||||
|
|
||||||
|
if (grub_file_seek (file, strsh->sh_offset) == (grub_off_t) -1)
|
||||||
|
return grub_errno;
|
||||||
|
str = (char *) curload;
|
||||||
|
if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize)
|
||||||
|
{
|
||||||
|
if (! grub_errno)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB,
|
||||||
|
&symtab,
|
||||||
|
sizeof (symtab));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*kern_end = ALIGN_PAGE (symtarget + chunk_size);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
|
||||||
|
grub_addr_t kern_start,
|
||||||
|
void *kern_chunk_src,
|
||||||
|
struct grub_openbsd_ramdisk_descriptor *desc)
|
||||||
|
{
|
||||||
|
unsigned symoff, stroff, symsize, strsize, symentsize;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
Elf_Ehdr e;
|
||||||
|
Elf_Shdr *s;
|
||||||
|
char *shdr;
|
||||||
|
|
||||||
|
err = read_headers (file, &e, &shdr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
|
||||||
|
+ e.e_shnum * e.e_shentsize);
|
||||||
|
s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
|
||||||
|
if (s->sh_type == SHT_SYMTAB)
|
||||||
|
break;
|
||||||
|
if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize))
|
||||||
|
{
|
||||||
|
grub_free (shdr);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
symsize = s->sh_size;
|
||||||
|
symentsize = s->sh_entsize;
|
||||||
|
symoff = s->sh_offset;
|
||||||
|
|
||||||
|
s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
|
||||||
|
stroff = s->sh_offset;
|
||||||
|
strsize = s->sh_size;
|
||||||
|
grub_free (shdr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL;
|
||||||
|
unsigned i;
|
||||||
|
char *strs;
|
||||||
|
|
||||||
|
syms = grub_malloc (symsize);
|
||||||
|
if (!syms)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_file_seek (file, symoff) == (grub_off_t) -1)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
if (grub_file_read (file, syms, symsize) != (grub_ssize_t) symsize)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
if (! grub_errno)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
strs = grub_malloc (strsize);
|
||||||
|
if (!strs)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_seek (file, stroff) == (grub_off_t) -1)
|
||||||
|
return grub_errno;
|
||||||
|
if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
grub_free (strs);
|
||||||
|
if (! grub_errno)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, sym = syms; i < symsize / symentsize;
|
||||||
|
i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
|
||||||
|
{
|
||||||
|
if (ELF_ST_TYPE (sym->st_info) != STT_OBJECT)
|
||||||
|
continue;
|
||||||
|
if (!sym->st_name)
|
||||||
|
continue;
|
||||||
|
if (grub_strcmp (strs + sym->st_name, "rd_root_image") == 0)
|
||||||
|
imagesym = sym;
|
||||||
|
if (grub_strcmp (strs + sym->st_name, "rd_root_size") == 0)
|
||||||
|
sizesym = sym;
|
||||||
|
if (imagesym && sizesym)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!imagesym || !sizesym)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
grub_free (strs);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
if (sizeof (*desc->size) != sizesym->st_size)
|
||||||
|
{
|
||||||
|
grub_free (syms);
|
||||||
|
grub_free (strs);
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "unexpected size of rd_root_size");
|
||||||
|
}
|
||||||
|
desc->max_size = imagesym->st_size;
|
||||||
|
desc->target = (imagesym->st_value & 0xFFFFFF) - kern_start
|
||||||
|
+ (grub_uint8_t *) kern_chunk_src;
|
||||||
|
desc->size = (grub_uint32_t *) ((sizesym->st_value & 0xFFFFFF) - kern_start
|
||||||
|
+ (grub_uint8_t *) kern_chunk_src);
|
||||||
|
grub_free (syms);
|
||||||
|
grub_free (strs);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -50,9 +50,10 @@
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_bsd64_pagetable (grub_uint8_t *target)
|
fill_bsd64_pagetable (grub_uint8_t *src, grub_addr_t target)
|
||||||
{
|
{
|
||||||
grub_uint64_t *pt2, *pt3, *pt4;
|
grub_uint64_t *pt2, *pt3, *pt4;
|
||||||
|
grub_addr_t pt2t, pt3t, pt4t;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#define PG_V 0x001
|
#define PG_V 0x001
|
||||||
|
@ -60,11 +61,15 @@ fill_bsd64_pagetable (grub_uint8_t *target)
|
||||||
#define PG_U 0x004
|
#define PG_U 0x004
|
||||||
#define PG_PS 0x080
|
#define PG_PS 0x080
|
||||||
|
|
||||||
pt4 = (grub_uint64_t *) target;
|
pt4 = (grub_uint64_t *) src;
|
||||||
pt3 = (grub_uint64_t *) (target + 4096);
|
pt3 = (grub_uint64_t *) (src + 4096);
|
||||||
pt2 = (grub_uint64_t *) (target + 8192);
|
pt2 = (grub_uint64_t *) (src + 8192);
|
||||||
|
|
||||||
grub_memset ((char *) target, 0, 4096 * 3);
|
pt4t = target;
|
||||||
|
pt3t = target + 4096;
|
||||||
|
pt2t = target + 8192;
|
||||||
|
|
||||||
|
grub_memset (src, 0, 4096 * 3);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is kinda brutal, but every single 1GB VM memory segment points to
|
* This is kinda brutal, but every single 1GB VM memory segment points to
|
||||||
|
@ -74,11 +79,11 @@ fill_bsd64_pagetable (grub_uint8_t *target)
|
||||||
for (i = 0; i < 512; i++)
|
for (i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
/* Each slot of the level 4 pages points to the same level 3 page */
|
/* Each slot of the level 4 pages points to the same level 3 page */
|
||||||
pt4[i] = (grub_addr_t) &pt3[0];
|
pt4[i] = (grub_addr_t) pt3t;
|
||||||
pt4[i] |= PG_V | PG_RW | PG_U;
|
pt4[i] |= PG_V | PG_RW | PG_U;
|
||||||
|
|
||||||
/* Each slot of the level 3 pages points to the same level 2 page */
|
/* Each slot of the level 3 pages points to the same level 2 page */
|
||||||
pt3[i] = (grub_addr_t) &pt2[0];
|
pt3[i] = (grub_addr_t) pt2t;
|
||||||
pt3[i] |= PG_V | PG_RW | PG_U;
|
pt3[i] |= PG_V | PG_RW | PG_U;
|
||||||
|
|
||||||
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
|
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
|
|
||||||
* Copyright (C) 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Based on the code from FreeBSD originally distributed under the
|
|
||||||
following terms: */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define MSR_EFER 0xc0000080
|
|
||||||
#define EFER_LME 0x00000100
|
|
||||||
#define CR4_PAE 0x00000020
|
|
||||||
#define CR4_PSE 0x00000010
|
|
||||||
#define CR0_PG 0x80000000
|
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
|
||||||
|
|
||||||
.p2align 2
|
|
||||||
|
|
||||||
.code32
|
|
||||||
|
|
||||||
|
|
||||||
VARIABLE(grub_bsd64_trampoline_start)
|
|
||||||
|
|
||||||
/* Discard `grub_unix_real_boot' return address. */
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
/* entry */
|
|
||||||
popl %edi
|
|
||||||
|
|
||||||
/* entry_hi */
|
|
||||||
popl %esi
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Turn on EFER.LME. */
|
|
||||||
movl $MSR_EFER, %ecx
|
|
||||||
rdmsr
|
|
||||||
orl $EFER_LME, %eax
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
/* Turn on PAE. */
|
|
||||||
movl %cr4, %eax
|
|
||||||
orl $(CR4_PAE | CR4_PSE), %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
/* Set %cr3 for PT4. */
|
|
||||||
popl %eax
|
|
||||||
movl %eax, %cr3
|
|
||||||
|
|
||||||
/* Push a dummy return address. */
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
/* Turn on paging (implicitly sets EFER.LMA). */
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $CR0_PG, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Now we're in compatibility mode. set %cs for long mode. */
|
|
||||||
/* lgdt */
|
|
||||||
.byte 0x0f
|
|
||||||
.byte 0x01
|
|
||||||
.byte 0x15
|
|
||||||
VARIABLE (grub_bsd64_trampoline_gdt)
|
|
||||||
.long 0x0
|
|
||||||
|
|
||||||
/* ljmp */
|
|
||||||
.byte 0xea
|
|
||||||
VARIABLE (grub_bsd64_trampoline_selfjump)
|
|
||||||
.long 0x0
|
|
||||||
.word 0x08
|
|
||||||
|
|
||||||
.code64
|
|
||||||
|
|
||||||
bsd64_longmode:
|
|
||||||
/* We're still running V=P, jump to entry point. */
|
|
||||||
movl %esi, %eax
|
|
||||||
salq $32, %rax
|
|
||||||
orq %rdi, %rax
|
|
||||||
pushq %rax
|
|
||||||
ret
|
|
||||||
VARIABLE(grub_bsd64_trampoline_end)
|
|
|
@ -1,945 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2006,2007,2008,2009,2010 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/loader.h>
|
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/file.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/term.h>
|
|
||||||
#include <grub/cpu/linux.h>
|
|
||||||
#include <grub/efi/api.h>
|
|
||||||
#include <grub/efi/efi.h>
|
|
||||||
#include <grub/command.h>
|
|
||||||
#include <grub/memory.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/video.h>
|
|
||||||
#include <grub/time.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
|
|
||||||
#define GRUB_LINUX_CL_OFFSET 0x1000
|
|
||||||
#define GRUB_LINUX_CL_END_OFFSET 0x2000
|
|
||||||
|
|
||||||
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
|
|
||||||
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
|
||||||
|
|
||||||
static grub_size_t linux_mem_size;
|
|
||||||
static int loaded;
|
|
||||||
static void *real_mode_mem;
|
|
||||||
static void *prot_mode_mem;
|
|
||||||
static void *initrd_mem;
|
|
||||||
static grub_efi_uintn_t real_mode_pages;
|
|
||||||
static grub_efi_uintn_t prot_mode_pages;
|
|
||||||
static grub_efi_uintn_t initrd_pages;
|
|
||||||
static void *mmap_buf;
|
|
||||||
|
|
||||||
static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
|
|
||||||
{
|
|
||||||
/* NULL. */
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* Reserved. */
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* Code segment. */
|
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
|
|
||||||
/* Data segment. */
|
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gdt_descriptor
|
|
||||||
{
|
|
||||||
grub_uint16_t limit;
|
|
||||||
void *base;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
static struct gdt_descriptor gdt_desc =
|
|
||||||
{
|
|
||||||
sizeof (gdt) - 1,
|
|
||||||
gdt
|
|
||||||
};
|
|
||||||
|
|
||||||
struct idt_descriptor
|
|
||||||
{
|
|
||||||
grub_uint16_t limit;
|
|
||||||
void *base;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
static struct idt_descriptor idt_desc =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline grub_size_t
|
|
||||||
page_align (grub_size_t size)
|
|
||||||
{
|
|
||||||
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the optimal number of pages for the memory map. Is it better to
|
|
||||||
move this code to efi/mm.c? */
|
|
||||||
static grub_efi_uintn_t
|
|
||||||
find_mmap_size (void)
|
|
||||||
{
|
|
||||||
static grub_efi_uintn_t mmap_size = 0;
|
|
||||||
|
|
||||||
if (mmap_size != 0)
|
|
||||||
return mmap_size;
|
|
||||||
|
|
||||||
mmap_size = (1 << 12);
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
grub_efi_memory_descriptor_t *mmap;
|
|
||||||
grub_efi_uintn_t desc_size;
|
|
||||||
|
|
||||||
mmap = grub_malloc (mmap_size);
|
|
||||||
if (! mmap)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
|
|
||||||
grub_free (mmap);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
grub_fatal ("cannot get memory map");
|
|
||||||
else if (ret > 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mmap_size += (1 << 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increase the size a bit for safety, because GRUB allocates more on
|
|
||||||
later, and EFI itself may allocate more. */
|
|
||||||
mmap_size += (1 << 12);
|
|
||||||
|
|
||||||
return page_align (mmap_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_pages (void)
|
|
||||||
{
|
|
||||||
if (real_mode_mem)
|
|
||||||
{
|
|
||||||
grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
|
|
||||||
real_mode_mem = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot_mode_mem)
|
|
||||||
{
|
|
||||||
grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
|
|
||||||
prot_mode_mem = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initrd_mem)
|
|
||||||
{
|
|
||||||
grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
|
|
||||||
initrd_mem = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate pages for the real mode code and the protected mode code
|
|
||||||
for linux as well as a memory map buffer. */
|
|
||||||
static int
|
|
||||||
allocate_pages (grub_size_t prot_size)
|
|
||||||
{
|
|
||||||
grub_efi_uintn_t desc_size;
|
|
||||||
grub_efi_memory_descriptor_t *mmap, *mmap_end;
|
|
||||||
grub_efi_uintn_t mmap_size, tmp_mmap_size;
|
|
||||||
grub_efi_memory_descriptor_t *desc;
|
|
||||||
grub_size_t real_size;
|
|
||||||
|
|
||||||
/* Make sure that each size is aligned to a page boundary. */
|
|
||||||
real_size = GRUB_LINUX_CL_END_OFFSET;
|
|
||||||
prot_size = page_align (prot_size);
|
|
||||||
mmap_size = find_mmap_size ();
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
|
|
||||||
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
|
|
||||||
|
|
||||||
/* Calculate the number of pages; Combine the real mode code with
|
|
||||||
the memory map buffer for simplicity. */
|
|
||||||
real_mode_pages = ((real_size + mmap_size) >> 12);
|
|
||||||
prot_mode_pages = (prot_size >> 12);
|
|
||||||
|
|
||||||
/* Initialize the memory pointers with NULL for convenience. */
|
|
||||||
real_mode_mem = 0;
|
|
||||||
prot_mode_mem = 0;
|
|
||||||
|
|
||||||
/* Read the memory map temporarily, to find free space. */
|
|
||||||
mmap = grub_malloc (mmap_size);
|
|
||||||
if (! mmap)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
tmp_mmap_size = mmap_size;
|
|
||||||
if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
|
|
||||||
grub_fatal ("cannot get memory map");
|
|
||||||
|
|
||||||
mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
|
|
||||||
|
|
||||||
/* First, find free pages for the real mode code
|
|
||||||
and the memory map buffer. */
|
|
||||||
for (desc = mmap;
|
|
||||||
desc < mmap_end;
|
|
||||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
|
||||||
{
|
|
||||||
/* Probably it is better to put the real mode code in the traditional
|
|
||||||
space for safety. */
|
|
||||||
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
|
|
||||||
&& desc->physical_start <= 0x90000
|
|
||||||
&& desc->num_pages >= real_mode_pages)
|
|
||||||
{
|
|
||||||
grub_efi_physical_address_t physical_end;
|
|
||||||
grub_efi_physical_address_t addr;
|
|
||||||
|
|
||||||
physical_end = desc->physical_start + (desc->num_pages << 12);
|
|
||||||
if (physical_end > 0x90000)
|
|
||||||
physical_end = 0x90000;
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
|
|
||||||
(unsigned) desc->physical_start,
|
|
||||||
(unsigned) physical_end);
|
|
||||||
addr = physical_end - real_size - mmap_size;
|
|
||||||
if (addr < 0x10000)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
|
|
||||||
(unsigned) real_mode_pages, (unsigned long) addr);
|
|
||||||
real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
|
|
||||||
if (! real_mode_mem)
|
|
||||||
grub_fatal ("cannot allocate pages");
|
|
||||||
|
|
||||||
desc->num_pages -= real_mode_pages;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! real_mode_mem)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_buf = (void *) ((char *) real_mode_mem + real_size);
|
|
||||||
|
|
||||||
/* Next, find free pages for the protected mode code. */
|
|
||||||
/* XXX what happens if anything is using this address? */
|
|
||||||
prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
|
|
||||||
if (! prot_mode_mem)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
||||||
"cannot allocate protected mode pages");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
|
|
||||||
"prot_mode_mem = %lx, prot_mode_pages = %x\n",
|
|
||||||
(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
|
|
||||||
(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
|
|
||||||
|
|
||||||
grub_free (mmap);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
grub_free (mmap);
|
|
||||||
free_pages ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
|
|
||||||
grub_uint64_t start, grub_uint64_t size,
|
|
||||||
grub_uint32_t type)
|
|
||||||
{
|
|
||||||
int n = *e820_num;
|
|
||||||
|
|
||||||
if (n >= GRUB_E820_MAX_ENTRY)
|
|
||||||
grub_fatal ("Too many e820 memory map entries");
|
|
||||||
|
|
||||||
if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
|
|
||||||
(e820_map[n - 1].type == type))
|
|
||||||
e820_map[n - 1].size += size;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e820_map[n].addr = start;
|
|
||||||
e820_map[n].size = size;
|
|
||||||
e820_map[n].type = type;
|
|
||||||
(*e820_num)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_setup_video (struct linux_kernel_params *params)
|
|
||||||
{
|
|
||||||
struct grub_video_mode_info mode_info;
|
|
||||||
void *framebuffer;
|
|
||||||
grub_err_t err;
|
|
||||||
|
|
||||||
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
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 = (grub_size_t) framebuffer;
|
|
||||||
params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height,
|
|
||||||
65536);
|
|
||||||
|
|
||||||
params->red_mask_size = mode_info.red_mask_size;
|
|
||||||
params->red_field_pos = mode_info.red_field_pos;
|
|
||||||
params->green_mask_size = mode_info.green_mask_size;
|
|
||||||
params->green_field_pos = mode_info.green_field_pos;
|
|
||||||
params->blue_mask_size = mode_info.blue_mask_size;
|
|
||||||
params->blue_field_pos = mode_info.blue_field_pos;
|
|
||||||
params->reserved_mask_size = mode_info.reserved_mask_size;
|
|
||||||
params->reserved_field_pos = mode_info.reserved_field_pos;
|
|
||||||
|
|
||||||
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
|
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
|
||||||
/* VESA packed modes may come with zeroed mask sizes, which need
|
|
||||||
to be set here according to DAC Palette width. If we don't,
|
|
||||||
this results in Linux displaying a black screen. */
|
|
||||||
if (mode_info.bpp <= 8)
|
|
||||||
{
|
|
||||||
struct grub_vbe_info_block controller_info;
|
|
||||||
int status;
|
|
||||||
int width = 8;
|
|
||||||
|
|
||||||
status = grub_vbe_bios_get_controller_info (&controller_info);
|
|
||||||
|
|
||||||
if (status == GRUB_VBE_STATUS_OK &&
|
|
||||||
(controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
|
|
||||||
status = grub_vbe_bios_set_dac_palette_width (&width);
|
|
||||||
|
|
||||||
if (status != GRUB_VBE_STATUS_OK)
|
|
||||||
/* 6 is default after mode reset. */
|
|
||||||
width = 6;
|
|
||||||
|
|
||||||
params->red_mask_size = params->green_mask_size
|
|
||||||
= params->blue_mask_size = width;
|
|
||||||
params->reserved_mask_size = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
extern grub_uint8_t grub_linux_trampoline_start[];
|
|
||||||
extern grub_uint8_t grub_linux_trampoline_end[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_boot (void)
|
|
||||||
{
|
|
||||||
struct linux_kernel_params *params;
|
|
||||||
grub_efi_uintn_t mmap_size;
|
|
||||||
grub_efi_uintn_t map_key;
|
|
||||||
grub_efi_uintn_t desc_size;
|
|
||||||
grub_efi_uint32_t desc_version;
|
|
||||||
int e820_num;
|
|
||||||
const char *modevar;
|
|
||||||
char *tmp;
|
|
||||||
grub_err_t err;
|
|
||||||
|
|
||||||
params = real_mode_mem;
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
|
|
||||||
(unsigned) params->code32_start,
|
|
||||||
(unsigned long) &(idt_desc.limit),
|
|
||||||
(unsigned long) &(gdt_desc.limit));
|
|
||||||
grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
|
|
||||||
(unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
|
|
||||||
(unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case GRUB_MACHINE_MEMORY_AVAILABLE:
|
|
||||||
grub_e820_add_region (params->e820_map, &e820_num,
|
|
||||||
addr, size, GRUB_E820_RAM);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MEMORY_ACPI
|
|
||||||
case GRUB_MACHINE_MEMORY_ACPI:
|
|
||||||
grub_e820_add_region (params->e820_map, &e820_num,
|
|
||||||
addr, size, GRUB_E820_ACPI);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MEMORY_NVS
|
|
||||||
case GRUB_MACHINE_MEMORY_NVS:
|
|
||||||
grub_e820_add_region (params->e820_map, &e820_num,
|
|
||||||
addr, size, GRUB_E820_NVS);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MEMORY_CODE
|
|
||||||
case GRUB_MACHINE_MEMORY_CODE:
|
|
||||||
grub_e820_add_region (params->e820_map, &e820_num,
|
|
||||||
addr, size, GRUB_E820_EXEC_CODE);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
grub_e820_add_region (params->e820_map, &e820_num,
|
|
||||||
addr, size, GRUB_E820_RESERVED);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
e820_num = 0;
|
|
||||||
grub_mmap_iterate (hook);
|
|
||||||
params->mmap_size = e820_num;
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "Trampoline at %p. code32=%x, real_mode_mem=%p\n",
|
|
||||||
((char *) prot_mode_mem + (prot_mode_pages << 12)),
|
|
||||||
(unsigned) params->code32_start, real_mode_mem);
|
|
||||||
|
|
||||||
modevar = grub_env_get ("gfxpayload");
|
|
||||||
|
|
||||||
/* Now all graphical modes are acceptable.
|
|
||||||
May change in future if we have modes without framebuffer. */
|
|
||||||
if (modevar && *modevar != 0)
|
|
||||||
{
|
|
||||||
tmp = grub_xasprintf ("%s;auto", modevar);
|
|
||||||
if (! tmp)
|
|
||||||
return grub_errno;
|
|
||||||
err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
|
|
||||||
grub_free (tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
|
|
||||||
|
|
||||||
if (!err)
|
|
||||||
err = grub_linux_setup_video (params);
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
||||||
grub_printf ("Booting however\n");
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_size = find_mmap_size ();
|
|
||||||
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
|
|
||||||
&desc_size, &desc_version) <= 0)
|
|
||||||
grub_fatal ("cannot get memory map");
|
|
||||||
|
|
||||||
if (! grub_efi_exit_boot_services (map_key))
|
|
||||||
grub_fatal ("cannot exit boot services");
|
|
||||||
|
|
||||||
/* Note that no boot services are available from here. */
|
|
||||||
|
|
||||||
/* Pass EFI parameters. */
|
|
||||||
if (grub_le_to_cpu16 (params->version) >= 0x0206)
|
|
||||||
{
|
|
||||||
params->v0206.efi_mem_desc_size = desc_size;
|
|
||||||
params->v0206.efi_mem_desc_version = desc_version;
|
|
||||||
params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
|
|
||||||
params->v0206.efi_mmap_size = mmap_size;
|
|
||||||
#ifdef __x86_64__
|
|
||||||
params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) mmap_buf >> 32);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
|
|
||||||
{
|
|
||||||
params->v0204.efi_mem_desc_size = desc_size;
|
|
||||||
params->v0204.efi_mem_desc_version = desc_version;
|
|
||||||
params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
|
|
||||||
params->v0204.efi_mmap_size = mmap_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
|
|
||||||
grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
|
|
||||||
grub_linux_trampoline_start,
|
|
||||||
grub_linux_trampoline_end - grub_linux_trampoline_start);
|
|
||||||
|
|
||||||
((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
|
|
||||||
+ (prot_mode_pages << 12)))
|
|
||||||
(params->code32_start, real_mode_mem);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Hardware interrupts are not safe any longer. */
|
|
||||||
asm volatile ("cli" : : );
|
|
||||||
|
|
||||||
/* Load the IDT and the GDT for the bootstrap. */
|
|
||||||
asm volatile ("lidt %0" : : "m" (idt_desc));
|
|
||||||
asm volatile ("lgdt %0" : : "m" (gdt_desc));
|
|
||||||
|
|
||||||
/* Pass parameters. */
|
|
||||||
asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
|
|
||||||
asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));
|
|
||||||
|
|
||||||
asm volatile ("xorl %%ebx, %%ebx" : : );
|
|
||||||
|
|
||||||
/* Enter Linux. */
|
|
||||||
asm volatile ("jmp *%%ecx" : : );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Never reach here. */
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_unload (void)
|
|
||||||
{
|
|
||||||
free_pages ();
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
loaded = 0;
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
grub_file_t file = 0;
|
|
||||||
struct linux_kernel_header lh;
|
|
||||||
struct linux_kernel_params *params;
|
|
||||||
grub_uint8_t setup_sects;
|
|
||||||
grub_size_t real_size, prot_size;
|
|
||||||
grub_ssize_t len;
|
|
||||||
int i;
|
|
||||||
char *dest;
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
|
||||||
if (! file)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EFI support is quite new, so reject old versions. */
|
|
||||||
if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
|
|
||||||
|| grub_le_to_cpu16 (lh.version) < 0x0203)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_OS, "too old version");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* I'm not sure how to support zImage on EFI. */
|
|
||||||
if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_OS, "zImage is not supported");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_sects = lh.setup_sects;
|
|
||||||
|
|
||||||
/* If SETUP_SECTS is not set, set it to the default (4). */
|
|
||||||
if (! setup_sects)
|
|
||||||
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
|
||||||
|
|
||||||
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
|
||||||
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
|
|
||||||
|
|
||||||
if (! allocate_pages (prot_size))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
params = (struct linux_kernel_params *) real_mode_mem;
|
|
||||||
grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
|
|
||||||
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
|
|
||||||
|
|
||||||
params->ps_mouse = params->padding10 = 0;
|
|
||||||
|
|
||||||
len = 0x400 - sizeof (lh);
|
|
||||||
if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
|
|
||||||
|
|
||||||
params->cl_magic = GRUB_LINUX_CL_MAGIC;
|
|
||||||
params->cl_offset = 0x1000;
|
|
||||||
params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
|
|
||||||
params->ramdisk_image = 0;
|
|
||||||
params->ramdisk_size = 0;
|
|
||||||
|
|
||||||
params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
|
|
||||||
params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
|
|
||||||
|
|
||||||
/* These are not needed to be precise, because Linux uses these values
|
|
||||||
only to raise an error when the decompression code cannot find good
|
|
||||||
space. */
|
|
||||||
params->ext_mem = ((32 * 0x100000) >> 10);
|
|
||||||
params->alt_mem = ((32 * 0x100000) >> 10);
|
|
||||||
|
|
||||||
{
|
|
||||||
grub_term_output_t term;
|
|
||||||
int found = 0;
|
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
|
||||||
if (grub_strcmp (term->name, "vga_text") == 0
|
|
||||||
|| grub_strcmp (term->name, "console") == 0)
|
|
||||||
{
|
|
||||||
grub_uint16_t pos = grub_term_getxy (term);
|
|
||||||
params->video_cursor_x = pos >> 8;
|
|
||||||
params->video_cursor_y = pos & 0xff;
|
|
||||||
params->video_width = grub_term_width (term);
|
|
||||||
params->video_height = grub_term_height (term);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
params->video_cursor_x = 0;
|
|
||||||
params->video_cursor_y = 0;
|
|
||||||
params->video_width = 80;
|
|
||||||
params->video_height = 25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params->video_page = 0; /* ??? */
|
|
||||||
params->video_mode = grub_efi_system_table->con_out->mode->mode;
|
|
||||||
params->video_ega_bx = 0;
|
|
||||||
params->have_vga = 0;
|
|
||||||
params->font_size = 16; /* XXX */
|
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (params->version) >= 0x0206)
|
|
||||||
{
|
|
||||||
params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
|
|
||||||
params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
|
|
||||||
#ifdef __x86_64__
|
|
||||||
params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
|
|
||||||
{
|
|
||||||
params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
|
|
||||||
params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* The structure is zeroed already. */
|
|
||||||
|
|
||||||
/* No VBE on EFI. */
|
|
||||||
params->lfb_width = 0;
|
|
||||||
params->lfb_height = 0;
|
|
||||||
params->lfb_depth = 0;
|
|
||||||
params->lfb_base = 0;
|
|
||||||
params->lfb_size = 0;
|
|
||||||
params->lfb_line_len = 0;
|
|
||||||
params->red_mask_size = 0;
|
|
||||||
params->red_field_pos = 0;
|
|
||||||
params->green_mask_size = 0;
|
|
||||||
params->green_field_pos = 0;
|
|
||||||
params->blue_mask_size = 0;
|
|
||||||
params->blue_field_pos = 0;
|
|
||||||
params->reserved_mask_size = 0;
|
|
||||||
params->reserved_field_pos = 0;
|
|
||||||
params->vesapm_segment = 0;
|
|
||||||
params->vesapm_offset = 0;
|
|
||||||
params->lfb_pages = 0;
|
|
||||||
params->vesa_attrib = 0;
|
|
||||||
|
|
||||||
/* No APM on EFI. */
|
|
||||||
params->apm_version = 0;
|
|
||||||
params->apm_code_segment = 0;
|
|
||||||
params->apm_entry = 0;
|
|
||||||
params->apm_16bit_code_segment = 0;
|
|
||||||
params->apm_data_segment = 0;
|
|
||||||
params->apm_flags = 0;
|
|
||||||
params->apm_code_len = 0;
|
|
||||||
params->apm_data_len = 0;
|
|
||||||
|
|
||||||
/* XXX is there any way to use SpeedStep on EFI? */
|
|
||||||
params->ist_signature = 0;
|
|
||||||
params->ist_command = 0;
|
|
||||||
params->ist_event = 0;
|
|
||||||
params->ist_perf_level = 0;
|
|
||||||
|
|
||||||
/* Let the kernel probe the information. */
|
|
||||||
grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info));
|
|
||||||
grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info));
|
|
||||||
|
|
||||||
/* No MCA on EFI. */
|
|
||||||
params->rom_config_len = 0;
|
|
||||||
|
|
||||||
/* No need to fake the BIOS's memory map. */
|
|
||||||
params->mmap_size = 0;
|
|
||||||
|
|
||||||
/* Let the kernel probe the information. */
|
|
||||||
params->ps_mouse = 0;
|
|
||||||
|
|
||||||
/* Clear padding for future compatibility. */
|
|
||||||
grub_memset (params->padding1, 0, sizeof (params->padding1));
|
|
||||||
grub_memset (params->padding2, 0, sizeof (params->padding2));
|
|
||||||
grub_memset (params->padding3, 0, sizeof (params->padding3));
|
|
||||||
grub_memset (params->padding4, 0, sizeof (params->padding4));
|
|
||||||
grub_memset (params->padding5, 0, sizeof (params->padding5));
|
|
||||||
grub_memset (params->padding6, 0, sizeof (params->padding6));
|
|
||||||
grub_memset (params->padding7, 0, sizeof (params->padding7));
|
|
||||||
grub_memset (params->padding8, 0, sizeof (params->padding8));
|
|
||||||
grub_memset (params->padding9, 0, sizeof (params->padding9));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The other EFI parameters are filled when booting. */
|
|
||||||
|
|
||||||
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
|
|
||||||
|
|
||||||
/* XXX there is no way to know if the kernel really supports EFI. */
|
|
||||||
grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
|
|
||||||
(unsigned) real_size, (unsigned) prot_size);
|
|
||||||
|
|
||||||
/* Detect explicitly specified memory size, if any. */
|
|
||||||
linux_mem_size = 0;
|
|
||||||
for (i = 1; i < argc; i++)
|
|
||||||
if (grub_memcmp (argv[i], "mem=", 4) == 0)
|
|
||||||
{
|
|
||||||
char *val = argv[i] + 4;
|
|
||||||
|
|
||||||
linux_mem_size = grub_strtoul (val, &val, 0);
|
|
||||||
|
|
||||||
if (grub_errno)
|
|
||||||
{
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
linux_mem_size = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int shift = 0;
|
|
||||||
|
|
||||||
switch (grub_tolower (val[0]))
|
|
||||||
{
|
|
||||||
case 'g':
|
|
||||||
shift += 10;
|
|
||||||
case 'm':
|
|
||||||
shift += 10;
|
|
||||||
case 'k':
|
|
||||||
shift += 10;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check an overflow. */
|
|
||||||
if (linux_mem_size > (~0UL >> shift))
|
|
||||||
linux_mem_size = 0;
|
|
||||||
else
|
|
||||||
linux_mem_size <<= shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
|
|
||||||
{
|
|
||||||
if (params->have_vga)
|
|
||||||
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Specify the boot file. */
|
|
||||||
dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
|
|
||||||
"BOOT_IMAGE=");
|
|
||||||
dest = grub_stpcpy (dest, argv[0]);
|
|
||||||
|
|
||||||
/* Copy kernel parameters. */
|
|
||||||
for (i = 1;
|
|
||||||
i < argc
|
|
||||||
&& dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
|
|
||||||
+ GRUB_LINUX_CL_END_OFFSET);
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
*dest++ = ' ';
|
|
||||||
dest = grub_stpcpy (dest, argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = prot_size;
|
|
||||||
if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
|
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
|
|
||||||
loaded = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
loaded = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
grub_file_t file = 0;
|
|
||||||
grub_ssize_t size;
|
|
||||||
grub_addr_t addr_min, addr_max;
|
|
||||||
grub_addr_t addr;
|
|
||||||
grub_efi_uintn_t mmap_size;
|
|
||||||
grub_efi_memory_descriptor_t *desc;
|
|
||||||
grub_efi_uintn_t desc_size;
|
|
||||||
struct linux_kernel_header *lh;
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! loaded)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
|
||||||
if (! file)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
size = grub_file_size (file);
|
|
||||||
initrd_pages = (page_align (size) >> 12);
|
|
||||||
|
|
||||||
lh = (struct linux_kernel_header *) real_mode_mem;
|
|
||||||
|
|
||||||
addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
|
|
||||||
if (linux_mem_size != 0 && linux_mem_size < addr_max)
|
|
||||||
addr_max = linux_mem_size;
|
|
||||||
|
|
||||||
/* Linux 2.3.xx has a bug in the memory range check, so avoid
|
|
||||||
the last page.
|
|
||||||
Linux 2.2.xx has a bug in the memory range check, which is
|
|
||||||
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
|
|
||||||
addr_max -= 0x10000;
|
|
||||||
|
|
||||||
/* Usually, the compression ratio is about 50%. */
|
|
||||||
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
|
|
||||||
+ page_align (size);
|
|
||||||
|
|
||||||
/* Find the highest address to put the initrd. */
|
|
||||||
mmap_size = find_mmap_size ();
|
|
||||||
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
|
|
||||||
grub_fatal ("cannot get memory map");
|
|
||||||
|
|
||||||
addr = 0;
|
|
||||||
for (desc = mmap_buf;
|
|
||||||
desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
|
|
||||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
|
||||||
{
|
|
||||||
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
|
|
||||||
&& desc->num_pages >= initrd_pages)
|
|
||||||
{
|
|
||||||
grub_efi_physical_address_t physical_end;
|
|
||||||
|
|
||||||
physical_end = desc->physical_start + (desc->num_pages << 12);
|
|
||||||
if (physical_end > addr_max)
|
|
||||||
physical_end = addr_max;
|
|
||||||
|
|
||||||
if (physical_end < page_align (size))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
physical_end -= page_align (size);
|
|
||||||
|
|
||||||
if ((physical_end >= addr_min) &&
|
|
||||||
(physical_end >= desc->physical_start) &&
|
|
||||||
(physical_end > addr))
|
|
||||||
addr = physical_end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr == 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
|
|
||||||
if (! initrd_mem)
|
|
||||||
grub_fatal ("cannot allocate pages");
|
|
||||||
|
|
||||||
if (grub_file_read (file, initrd_mem, size) != size)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
|
|
||||||
(unsigned) addr, (unsigned) size);
|
|
||||||
|
|
||||||
lh->ramdisk_image = addr;
|
|
||||||
lh->ramdisk_size = size;
|
|
||||||
lh->root_dev = 0x0100; /* XXX */
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (file)
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_command_t cmd_linux, cmd_initrd;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(linux)
|
|
||||||
{
|
|
||||||
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
|
|
||||||
0, N_("Load Linux."));
|
|
||||||
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
|
|
||||||
0, N_("Load initrd."));
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(linux)
|
|
||||||
{
|
|
||||||
grub_unregister_command (cmd_linux);
|
|
||||||
grub_unregister_command (cmd_initrd);
|
|
||||||
}
|
|
|
@ -1,311 +0,0 @@
|
||||||
/* linux.c - boot Linux zImage or bzImage */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 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/loader.h>
|
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/machine/memory.h>
|
|
||||||
#include <grub/file.h>
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/term.h>
|
|
||||||
#include <grub/cpu/linux.h>
|
|
||||||
#include <grub/ieee1275/ieee1275.h>
|
|
||||||
#include <grub/command.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
|
|
||||||
#define GRUB_OFW_LINUX_PARAMS_ADDR 0x90000
|
|
||||||
#define GRUB_OFW_LINUX_KERNEL_ADDR 0x100000
|
|
||||||
#define GRUB_OFW_LINUX_INITRD_ADDR 0x800000
|
|
||||||
|
|
||||||
#define GRUB_OFW_LINUX_CL_OFFSET 0x1e00
|
|
||||||
#define GRUB_OFW_LINUX_CL_LENGTH 0x100
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
|
||||||
|
|
||||||
static grub_size_t kernel_size;
|
|
||||||
static char *kernel_addr, *kernel_cmdline;
|
|
||||||
static grub_size_t initrd_size;
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_unload (void)
|
|
||||||
{
|
|
||||||
grub_free (kernel_cmdline);
|
|
||||||
grub_free (kernel_addr);
|
|
||||||
kernel_cmdline = 0;
|
|
||||||
kernel_addr = 0;
|
|
||||||
initrd_size = 0;
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static int
|
|
||||||
grub_ieee1275_debug (void)
|
|
||||||
{
|
|
||||||
struct enter_args
|
|
||||||
{
|
|
||||||
struct grub_ieee1275_common_hdr common;
|
|
||||||
}
|
|
||||||
args;
|
|
||||||
|
|
||||||
INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
|
|
||||||
|
|
||||||
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_boot (void)
|
|
||||||
{
|
|
||||||
struct linux_kernel_params *params;
|
|
||||||
struct linux_kernel_header *lh;
|
|
||||||
char *prot_code;
|
|
||||||
char *bootpath;
|
|
||||||
grub_ssize_t len;
|
|
||||||
|
|
||||||
bootpath = grub_env_get ("root");
|
|
||||||
if (bootpath)
|
|
||||||
grub_ieee1275_set_property (grub_ieee1275_chosen,
|
|
||||||
"bootpath", bootpath,
|
|
||||||
grub_strlen (bootpath) + 1,
|
|
||||||
&len);
|
|
||||||
|
|
||||||
params = (struct linux_kernel_params *) GRUB_OFW_LINUX_PARAMS_ADDR;
|
|
||||||
lh = (struct linux_kernel_header *) params;
|
|
||||||
|
|
||||||
grub_memset ((char *) params, 0, GRUB_OFW_LINUX_CL_OFFSET);
|
|
||||||
|
|
||||||
params->alt_mem = grub_mmap_get_upper () >> 10;
|
|
||||||
params->ext_mem = params->alt_mem;
|
|
||||||
|
|
||||||
lh->cmd_line_ptr = (char *)
|
|
||||||
(GRUB_OFW_LINUX_PARAMS_ADDR + GRUB_OFW_LINUX_CL_OFFSET);
|
|
||||||
|
|
||||||
params->cl_magic = GRUB_LINUX_CL_MAGIC;
|
|
||||||
params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET;
|
|
||||||
|
|
||||||
{
|
|
||||||
grub_term_output_t term;
|
|
||||||
int found = 0;
|
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
|
||||||
if (grub_strcmp (term->name, "ofconsole") == 0)
|
|
||||||
{
|
|
||||||
grub_uint16_t pos = grub_term_getxy (term);
|
|
||||||
params->video_cursor_x = pos >> 8;
|
|
||||||
params->video_cursor_y = pos & 0xff;
|
|
||||||
params->video_width = grub_term_width (term);
|
|
||||||
params->video_height = grub_term_height (term);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
params->video_cursor_x = 0;
|
|
||||||
params->video_cursor_y = 0;
|
|
||||||
params->video_width = 80;
|
|
||||||
params->video_height = 25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
params->font_size = 16;
|
|
||||||
|
|
||||||
params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
|
|
||||||
params->ofw_num_items = 1;
|
|
||||||
params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
|
|
||||||
params->ofw_idt = 0;
|
|
||||||
|
|
||||||
if (initrd_size)
|
|
||||||
{
|
|
||||||
lh->type_of_loader = 1;
|
|
||||||
lh->ramdisk_image = GRUB_OFW_LINUX_INITRD_ADDR;
|
|
||||||
lh->ramdisk_size = initrd_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kernel_cmdline)
|
|
||||||
grub_strcpy (lh->cmd_line_ptr, kernel_cmdline);
|
|
||||||
|
|
||||||
prot_code = (char *) GRUB_OFW_LINUX_KERNEL_ADDR;
|
|
||||||
grub_memcpy (prot_code, kernel_addr, kernel_size);
|
|
||||||
|
|
||||||
asm volatile ("movl %0, %%esi" : : "m" (params));
|
|
||||||
asm volatile ("movl %%esi, %%esp" : : );
|
|
||||||
asm volatile ("movl %0, %%ecx" : : "m" (prot_code));
|
|
||||||
asm volatile ("xorl %%ebx, %%ebx" : : );
|
|
||||||
asm volatile ("jmp *%%ecx" : : );
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
grub_file_t file = 0;
|
|
||||||
struct linux_kernel_header lh;
|
|
||||||
grub_uint8_t setup_sects;
|
|
||||||
grub_size_t real_size, prot_size;
|
|
||||||
int i;
|
|
||||||
char *dest;
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
|
||||||
if (! file)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ||
|
|
||||||
(lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_sects = lh.setup_sects;
|
|
||||||
if (! setup_sects)
|
|
||||||
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
|
||||||
|
|
||||||
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
|
||||||
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "Linux-%s, setup=0x%x, size=0x%x\n",
|
|
||||||
"bzImage", real_size, prot_size);
|
|
||||||
|
|
||||||
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
|
|
||||||
if (grub_errno)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
kernel_cmdline = grub_malloc (GRUB_OFW_LINUX_CL_LENGTH);
|
|
||||||
if (! kernel_cmdline)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
dest = kernel_cmdline;
|
|
||||||
for (i = 1;
|
|
||||||
i < argc
|
|
||||||
&& dest + grub_strlen (argv[i]) + 1 < (kernel_cmdline
|
|
||||||
+ GRUB_OFW_LINUX_CL_LENGTH);
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
*dest++ = ' ';
|
|
||||||
dest = grub_stpcpy (dest, argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_addr = grub_malloc (prot_size);
|
|
||||||
if (! kernel_addr)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
kernel_size = prot_size;
|
|
||||||
if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size)
|
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
|
|
||||||
|
|
||||||
fail:
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
grub_free (kernel_cmdline);
|
|
||||||
grub_free (kernel_addr);
|
|
||||||
kernel_cmdline = 0;
|
|
||||||
kernel_addr = 0;
|
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
grub_file_t file = 0;
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! kernel_addr)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
|
||||||
if (! file)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
initrd_size = grub_file_size (file);
|
|
||||||
if (grub_file_read (file, (void *) GRUB_OFW_LINUX_INITRD_ADDR,
|
|
||||||
initrd_size) != (int) initrd_size)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (file)
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_command_t cmd_linux, cmd_initrd;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(linux)
|
|
||||||
{
|
|
||||||
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
|
|
||||||
0, N_("Load Linux."));
|
|
||||||
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
|
|
||||||
0, N_("Load initrd."));
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(linux)
|
|
||||||
{
|
|
||||||
grub_unregister_command (cmd_linux);
|
|
||||||
grub_unregister_command (cmd_initrd);
|
|
||||||
}
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/machine/loader.h>
|
#include <grub/memory.h>
|
||||||
#include <grub/normal.h>
|
#include <grub/normal.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
|
@ -32,9 +32,23 @@
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
#include <grub/video_fb.h>
|
#include <grub/video_fb.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
|
#include <grub/i386/relocator.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#define HAS_VGA_TEXT 0
|
||||||
|
#define DEFAULT_VIDEO_MODE "800x600"
|
||||||
|
#elif defined (GRUB_MACHINE_IEEE1275)
|
||||||
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
|
#define HAS_VGA_TEXT 0
|
||||||
|
#define DEFAULT_VIDEO_MODE "text"
|
||||||
|
#else
|
||||||
#include <grub/i386/pc/vbe.h>
|
#include <grub/i386/pc/vbe.h>
|
||||||
#include <grub/i386/pc/console.h>
|
#include <grub/i386/pc/console.h>
|
||||||
#include <grub/i18n.h>
|
#define HAS_VGA_TEXT 1
|
||||||
|
#define DEFAULT_VIDEO_MODE "text"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GRUB_LINUX_CL_OFFSET 0x1000
|
#define GRUB_LINUX_CL_OFFSET 0x1000
|
||||||
#define GRUB_LINUX_CL_END_OFFSET 0x2000
|
#define GRUB_LINUX_CL_END_OFFSET 0x2000
|
||||||
|
@ -44,36 +58,24 @@ static grub_dl_t my_mod;
|
||||||
static grub_size_t linux_mem_size;
|
static grub_size_t linux_mem_size;
|
||||||
static int loaded;
|
static int loaded;
|
||||||
static void *real_mode_mem;
|
static void *real_mode_mem;
|
||||||
|
static grub_addr_t real_mode_target;
|
||||||
static void *prot_mode_mem;
|
static void *prot_mode_mem;
|
||||||
|
static grub_addr_t prot_mode_target;
|
||||||
static void *initrd_mem;
|
static void *initrd_mem;
|
||||||
|
static grub_addr_t initrd_mem_target;
|
||||||
static grub_uint32_t real_mode_pages;
|
static grub_uint32_t real_mode_pages;
|
||||||
static grub_uint32_t prot_mode_pages;
|
static grub_uint32_t prot_mode_pages;
|
||||||
static grub_uint32_t initrd_pages;
|
static grub_uint32_t initrd_pages;
|
||||||
|
static struct grub_relocator *relocator = NULL;
|
||||||
|
static void *efi_mmap_buf;
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
static grub_efi_uintn_t efi_mmap_size;
|
||||||
|
#else
|
||||||
|
static const grub_size_t efi_mmap_size = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
|
/* FIXME */
|
||||||
{
|
#if 0
|
||||||
/* NULL. */
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* Reserved. */
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* Code segment. */
|
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
|
|
||||||
/* Data segment. */
|
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gdt_descriptor
|
|
||||||
{
|
|
||||||
grub_uint16_t limit;
|
|
||||||
void *base;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
static struct gdt_descriptor gdt_desc =
|
|
||||||
{
|
|
||||||
sizeof (gdt) - 1,
|
|
||||||
gdt
|
|
||||||
};
|
|
||||||
|
|
||||||
struct idt_descriptor
|
struct idt_descriptor
|
||||||
{
|
{
|
||||||
grub_uint16_t limit;
|
grub_uint16_t limit;
|
||||||
|
@ -85,6 +87,7 @@ static struct idt_descriptor idt_desc =
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
#ifdef GRUB_MACHINE_PCBIOS
|
||||||
struct linux_vesafb_res
|
struct linux_vesafb_res
|
||||||
|
@ -261,6 +264,48 @@ page_align (grub_size_t size)
|
||||||
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
|
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
/* Find the optimal number of pages for the memory map. Is it better to
|
||||||
|
move this code to efi/mm.c? */
|
||||||
|
static grub_efi_uintn_t
|
||||||
|
find_efi_mmap_size (void)
|
||||||
|
{
|
||||||
|
static grub_efi_uintn_t mmap_size = 0;
|
||||||
|
|
||||||
|
if (mmap_size != 0)
|
||||||
|
return mmap_size;
|
||||||
|
|
||||||
|
mmap_size = (1 << 12);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
grub_efi_memory_descriptor_t *mmap;
|
||||||
|
grub_efi_uintn_t desc_size;
|
||||||
|
|
||||||
|
mmap = grub_malloc (mmap_size);
|
||||||
|
if (! mmap)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
|
||||||
|
grub_free (mmap);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
grub_fatal ("cannot get memory map");
|
||||||
|
else if (ret > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mmap_size += (1 << 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase the size a bit for safety, because GRUB allocates more on
|
||||||
|
later, and EFI itself may allocate more. */
|
||||||
|
mmap_size += (1 << 12);
|
||||||
|
|
||||||
|
return page_align (mmap_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Find the optimal number of pages for the memory map. */
|
/* Find the optimal number of pages for the memory map. */
|
||||||
static grub_size_t
|
static grub_size_t
|
||||||
find_mmap_size (void)
|
find_mmap_size (void)
|
||||||
|
@ -290,32 +335,47 @@ find_mmap_size (void)
|
||||||
static void
|
static void
|
||||||
free_pages (void)
|
free_pages (void)
|
||||||
{
|
{
|
||||||
|
grub_relocator_unload (relocator);
|
||||||
|
relocator = NULL;
|
||||||
real_mode_mem = prot_mode_mem = initrd_mem = 0;
|
real_mode_mem = prot_mode_mem = initrd_mem = 0;
|
||||||
|
real_mode_target = prot_mode_target = initrd_mem_target = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate pages for the real mode code and the protected mode code
|
/* Allocate pages for the real mode code and the protected mode code
|
||||||
for linux as well as a memory map buffer. */
|
for linux as well as a memory map buffer. */
|
||||||
static int
|
static grub_err_t
|
||||||
allocate_pages (grub_size_t prot_size)
|
allocate_pages (grub_size_t prot_size)
|
||||||
{
|
{
|
||||||
grub_size_t real_size, mmap_size;
|
grub_size_t real_size, mmap_size;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
/* Make sure that each size is aligned to a page boundary. */
|
/* Make sure that each size is aligned to a page boundary. */
|
||||||
real_size = GRUB_LINUX_CL_END_OFFSET;
|
real_size = GRUB_LINUX_CL_END_OFFSET;
|
||||||
prot_size = page_align (prot_size);
|
prot_size = page_align (prot_size);
|
||||||
mmap_size = find_mmap_size ();
|
mmap_size = find_mmap_size ();
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
efi_mmap_size = find_efi_mmap_size ();
|
||||||
|
#endif
|
||||||
|
|
||||||
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
|
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
|
||||||
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
|
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
|
||||||
|
|
||||||
/* Calculate the number of pages; Combine the real mode code with
|
/* Calculate the number of pages; Combine the real mode code with
|
||||||
the memory map buffer for simplicity. */
|
the memory map buffer for simplicity. */
|
||||||
real_mode_pages = ((real_size + mmap_size) >> 12);
|
real_mode_pages = ((real_size + mmap_size + efi_mmap_size) >> 12);
|
||||||
prot_mode_pages = (prot_size >> 12);
|
prot_mode_pages = (prot_size >> 12);
|
||||||
|
|
||||||
/* Initialize the memory pointers with NULL for convenience. */
|
/* Initialize the memory pointers with NULL for convenience. */
|
||||||
free_pages ();
|
free_pages ();
|
||||||
|
|
||||||
|
relocator = grub_relocator_new ();
|
||||||
|
if (!relocator)
|
||||||
|
{
|
||||||
|
err = grub_errno;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Should request low memory from the heap when this feature is
|
/* FIXME: Should request low memory from the heap when this feature is
|
||||||
implemented. */
|
implemented. */
|
||||||
|
|
||||||
|
@ -336,35 +396,55 @@ allocate_pages (grub_size_t prot_size)
|
||||||
if (addr + size > 0x90000)
|
if (addr + size > 0x90000)
|
||||||
size = 0x90000 - addr;
|
size = 0x90000 - addr;
|
||||||
|
|
||||||
if (real_size + mmap_size > size)
|
if (real_size + mmap_size + efi_mmap_size > size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
real_mode_mem =
|
real_mode_target = ((addr + size) - (real_size + mmap_size + efi_mmap_size));
|
||||||
(void *) (grub_size_t) ((addr + size) - (real_size + mmap_size));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
grub_mmap_iterate (hook);
|
grub_mmap_iterate (hook);
|
||||||
if (! real_mode_mem)
|
if (! real_mode_target)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
prot_mode_mem = (void *) 0x100000;
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
real_mode_target,
|
||||||
|
(real_size + mmap_size
|
||||||
|
+ efi_mmap_size));
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
real_mode_mem = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
|
||||||
|
|
||||||
|
prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
prot_mode_target, prot_size);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
prot_mode_mem = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
|
grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
|
||||||
"prot_mode_mem = %lx, prot_mode_pages = %x\n",
|
"prot_mode_mem = %lx, prot_mode_pages = %x\n",
|
||||||
(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
|
(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
|
||||||
(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
|
(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
|
||||||
|
|
||||||
return 1;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
free_pages ();
|
free_pages ();
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -389,7 +469,7 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static grub_err_t
|
||||||
grub_linux_setup_video (struct linux_kernel_params *params)
|
grub_linux_setup_video (struct linux_kernel_params *params)
|
||||||
{
|
{
|
||||||
struct grub_video_mode_info mode_info;
|
struct grub_video_mode_info mode_info;
|
||||||
|
@ -448,14 +528,9 @@ grub_linux_setup_video (struct linux_kernel_params *params)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
extern grub_uint8_t grub_linux_trampoline_start[];
|
|
||||||
extern grub_uint8_t grub_linux_trampoline_end[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_boot (void)
|
grub_linux_boot (void)
|
||||||
{
|
{
|
||||||
|
@ -463,16 +538,26 @@ grub_linux_boot (void)
|
||||||
int e820_num;
|
int e820_num;
|
||||||
grub_err_t err = 0;
|
grub_err_t err = 0;
|
||||||
char *modevar, *tmp;
|
char *modevar, *tmp;
|
||||||
|
struct grub_relocator32_state state;
|
||||||
|
|
||||||
params = real_mode_mem;
|
params = real_mode_mem;
|
||||||
|
|
||||||
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
|
#ifdef GRUB_MACHINE_IEEE1275
|
||||||
(unsigned) params->code32_start,
|
{
|
||||||
(unsigned long) &(idt_desc.limit),
|
char *bootpath;
|
||||||
(unsigned long) &(gdt_desc.limit));
|
grub_ssize_t len;
|
||||||
grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
|
|
||||||
(unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
|
bootpath = grub_env_get ("root");
|
||||||
(unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
|
if (bootpath)
|
||||||
|
grub_ieee1275_set_property (grub_ieee1275_chosen,
|
||||||
|
"bootpath", bootpath,
|
||||||
|
grub_strlen (bootpath) + 1,
|
||||||
|
&len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "code32_start = %x\n",
|
||||||
|
(unsigned) params->code32_start);
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
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)
|
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
|
||||||
|
@ -522,14 +607,14 @@ grub_linux_boot (void)
|
||||||
May change in future if we have modes without framebuffer. */
|
May change in future if we have modes without framebuffer. */
|
||||||
if (modevar && *modevar != 0)
|
if (modevar && *modevar != 0)
|
||||||
{
|
{
|
||||||
tmp = grub_xasprintf ("%s;text", modevar);
|
tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
|
||||||
if (! tmp)
|
if (! tmp)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
err = grub_video_set_mode (tmp, 0, 0);
|
err = grub_video_set_mode (tmp, 0, 0);
|
||||||
grub_free (tmp);
|
grub_free (tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = grub_video_set_mode ("text", 0, 0);
|
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@ -548,23 +633,34 @@ grub_linux_boot (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
|
||||||
params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
|
params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
|
||||||
params->video_width = 80;
|
params->video_mode = 0x3;
|
||||||
params->video_height = 25;
|
#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. */
|
/* Initialize these last, because terminal position could be affected by printfs above. */
|
||||||
|
#ifndef GRUB_MACHINE_IEEE1275
|
||||||
if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
|
if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
grub_term_output_t term;
|
grub_term_output_t term;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
if (grub_strcmp (term->name, "vga_text") == 0
|
if (grub_strcmp (term->name, "vga_text") == 0
|
||||||
|| grub_strcmp (term->name, "console") == 0)
|
|| grub_strcmp (term->name, "console") == 0
|
||||||
|
|| grub_strcmp (term->name, "ofconsole") == 0)
|
||||||
{
|
{
|
||||||
grub_uint16_t pos = grub_term_getxy (term);
|
grub_uint16_t pos = grub_term_getxy (term);
|
||||||
params->video_cursor_x = pos >> 8;
|
params->video_cursor_x = pos >> 8;
|
||||||
params->video_cursor_y = pos & 0xff;
|
params->video_cursor_y = pos & 0xff;
|
||||||
|
params->video_width = grub_term_width (term);
|
||||||
|
params->video_height = grub_term_height (term);
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -572,34 +668,59 @@ grub_linux_boot (void)
|
||||||
{
|
{
|
||||||
params->video_cursor_x = 0;
|
params->video_cursor_x = 0;
|
||||||
params->video_cursor_y = 0;
|
params->video_cursor_y = 0;
|
||||||
|
params->video_width = 80;
|
||||||
|
params->video_height = 25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef GRUB_MACHINE_IEEE1275
|
||||||
|
{
|
||||||
grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
|
params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
|
||||||
grub_linux_trampoline_start,
|
params->ofw_num_items = 1;
|
||||||
grub_linux_trampoline_end - grub_linux_trampoline_start);
|
params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
|
||||||
|
params->ofw_idt = 0;
|
||||||
((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
|
}
|
||||||
+ (prot_mode_pages << 12)))
|
|
||||||
(params->code32_start, real_mode_mem);
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Hardware interrupts are not safe any longer. */
|
|
||||||
asm volatile ("cli" : : );
|
|
||||||
|
|
||||||
/* Load the IDT and the GDT for the bootstrap. */
|
|
||||||
asm volatile ("lidt %0" : : "m" (idt_desc));
|
|
||||||
asm volatile ("lgdt %0" : : "m" (gdt_desc));
|
|
||||||
|
|
||||||
/* Enter Linux. */
|
|
||||||
asm volatile ("jmp *%2" : : "b" (0), "S" (real_mode_mem), "g" (params->code32_start));
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Never reach here. */
|
#ifdef GRUB_MACHINE_EFI
|
||||||
return GRUB_ERR_NONE;
|
{
|
||||||
|
grub_efi_uintn_t efi_desc_size;
|
||||||
|
grub_efi_uint32_t efi_desc_version;
|
||||||
|
err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL,
|
||||||
|
&efi_desc_size, &efi_desc_version);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Note that no boot services are available from here. */
|
||||||
|
|
||||||
|
/* Pass EFI parameters. */
|
||||||
|
if (grub_le_to_cpu16 (params->version) >= 0x0206)
|
||||||
|
{
|
||||||
|
params->v0206.efi_mem_desc_size = efi_desc_size;
|
||||||
|
params->v0206.efi_mem_desc_version = efi_desc_version;
|
||||||
|
params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) efi_mmap_buf;
|
||||||
|
params->v0206.efi_mmap_size = efi_mmap_size;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) efi_mmap_buf >> 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
|
||||||
|
{
|
||||||
|
params->v0204.efi_mem_desc_size = efi_desc_size;
|
||||||
|
params->v0204.efi_mem_desc_version = efi_desc_version;
|
||||||
|
params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) efi_mmap_buf;
|
||||||
|
params->v0204.efi_mmap_size = efi_mmap_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME. */
|
||||||
|
/* asm volatile ("lidt %0" : : "m" (idt_desc)); */
|
||||||
|
state.ebp = state.edi = state.ebx = 0;
|
||||||
|
state.esi = real_mode_target;
|
||||||
|
state.esp = real_mode_target;
|
||||||
|
state.eip = params->code32_start;
|
||||||
|
return grub_relocator32_boot (relocator, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -685,7 +806,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
||||||
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
|
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
|
||||||
|
|
||||||
if (! allocate_pages (prot_size))
|
if (allocate_pages (prot_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
params = (struct linux_kernel_params *) real_mode_mem;
|
params = (struct linux_kernel_params *) real_mode_mem;
|
||||||
|
@ -708,7 +829,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
params->cl_magic = GRUB_LINUX_CL_MAGIC;
|
params->cl_magic = GRUB_LINUX_CL_MAGIC;
|
||||||
params->cl_offset = 0x1000;
|
params->cl_offset = 0x1000;
|
||||||
|
|
||||||
params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
|
params->cmd_line_ptr = real_mode_target + 0x1000;
|
||||||
params->ramdisk_image = 0;
|
params->ramdisk_image = 0;
|
||||||
params->ramdisk_size = 0;
|
params->ramdisk_size = 0;
|
||||||
|
|
||||||
|
@ -724,14 +845,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
/* Ignored by Linux. */
|
/* Ignored by Linux. */
|
||||||
params->video_page = 0;
|
params->video_page = 0;
|
||||||
|
|
||||||
/* Must be non-zero even in text mode, or Linux will think there's no VGA. */
|
|
||||||
params->video_mode = 0x3;
|
|
||||||
|
|
||||||
/* Only used when `video_mode == 0x7', otherwise ignored. */
|
/* Only used when `video_mode == 0x7', otherwise ignored. */
|
||||||
params->video_ega_bx = 0;
|
params->video_ega_bx = 0;
|
||||||
|
|
||||||
params->font_size = 16; /* XXX */
|
params->font_size = 16; /* XXX */
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
if (grub_le_to_cpu16 (params->version) >= 0x0206)
|
||||||
|
{
|
||||||
|
params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
|
||||||
|
params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
|
||||||
|
#ifdef __x86_64__
|
||||||
|
params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
|
||||||
|
{
|
||||||
|
params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
|
||||||
|
params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The other parameters are filled when booting. */
|
/* The other parameters are filled when booting. */
|
||||||
|
|
||||||
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
|
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
|
||||||
|
@ -888,7 +1022,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
len = prot_size;
|
len = prot_size;
|
||||||
if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
|
if (grub_file_read (file, prot_mode_mem, len) != len)
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
@ -920,6 +1054,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
grub_addr_t addr_min, addr_max;
|
grub_addr_t addr_min, addr_max;
|
||||||
grub_addr_t addr;
|
grub_addr_t addr;
|
||||||
|
grub_err_t err;
|
||||||
struct linux_kernel_header *lh;
|
struct linux_kernel_header *lh;
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
|
@ -967,12 +1102,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
addr_max -= 0x10000;
|
addr_max -= 0x10000;
|
||||||
|
|
||||||
/* Usually, the compression ratio is about 50%. */
|
/* Usually, the compression ratio is about 50%. */
|
||||||
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
|
addr_min = (grub_addr_t) prot_mode_target + ((prot_mode_pages * 3) << 12)
|
||||||
+ page_align (size);
|
+ page_align (size);
|
||||||
|
|
||||||
if (addr_max > grub_os_area_addr + grub_os_area_size)
|
|
||||||
addr_max = grub_os_area_addr + grub_os_area_size;
|
|
||||||
|
|
||||||
/* Put the initrd as high as possible, 4KiB aligned. */
|
/* Put the initrd as high as possible, 4KiB aligned. */
|
||||||
addr = (addr_max - size) & ~0xFFF;
|
addr = (addr_max - size) & ~0xFFF;
|
||||||
|
|
||||||
|
@ -982,7 +1114,16 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
initrd_mem = (void *) addr;
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
|
addr_min, addr, size, 0x1000,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_HIGH);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
initrd_mem = get_virtual_current_address (ch);
|
||||||
|
initrd_mem_target = get_physical_target_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_file_read (file, initrd_mem, size) != size)
|
if (grub_file_read (file, initrd_mem, size) != size)
|
||||||
{
|
{
|
||||||
|
@ -993,7 +1134,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
|
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
|
||||||
(unsigned) addr, (unsigned) size);
|
(unsigned) addr, (unsigned) size);
|
||||||
|
|
||||||
lh->ramdisk_image = addr;
|
lh->ramdisk_image = initrd_mem_target;
|
||||||
lh->ramdisk_size = size;
|
lh->ramdisk_size = size;
|
||||||
lh->root_dev = 0x0100; /* XXX */
|
lh->root_dev = 0x0100; /* XXX */
|
||||||
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 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/symbol.h>
|
|
||||||
|
|
||||||
|
|
||||||
.p2align 4 /* force 16-byte alignment */
|
|
||||||
VARIABLE(grub_linux_trampoline_start)
|
|
||||||
cli
|
|
||||||
/* %rdi contains protected memory start and %rsi
|
|
||||||
contains real memory start. */
|
|
||||||
|
|
||||||
mov %rsi, %rbx
|
|
||||||
|
|
||||||
call base
|
|
||||||
base:
|
|
||||||
pop %rsi
|
|
||||||
|
|
||||||
#ifdef APPLE_CC
|
|
||||||
lea (cont1 - base) (%esi, 1), %rax
|
|
||||||
mov %eax, (jump_vector - base) (%esi, 1)
|
|
||||||
|
|
||||||
lea (gdt - base) (%esi, 1), %rax
|
|
||||||
mov %rax, (gdtaddr - base) (%esi, 1)
|
|
||||||
|
|
||||||
/* Switch to compatibility mode. */
|
|
||||||
|
|
||||||
lidt (idtdesc - base) (%esi, 1)
|
|
||||||
lgdt (gdtdesc - base) (%esi, 1)
|
|
||||||
|
|
||||||
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
|
|
||||||
ljmp *(jump_vector - base) (%esi, 1)
|
|
||||||
#else
|
|
||||||
lea (cont1 - base) (%rsi, 1), %rax
|
|
||||||
mov %eax, (jump_vector - base) (%rsi, 1)
|
|
||||||
|
|
||||||
lea (gdt - base) (%rsi, 1), %rax
|
|
||||||
mov %rax, (gdtaddr - base) (%rsi, 1)
|
|
||||||
|
|
||||||
/* Switch to compatibility mode. */
|
|
||||||
|
|
||||||
lidt (idtdesc - base) (%rsi, 1)
|
|
||||||
lgdt (gdtdesc - base) (%rsi, 1)
|
|
||||||
|
|
||||||
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
|
|
||||||
ljmp *(jump_vector - base) (%rsi, 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cont1:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/* Update other registers. */
|
|
||||||
mov $0x18, %eax
|
|
||||||
mov %eax, %ds
|
|
||||||
mov %eax, %es
|
|
||||||
mov %eax, %fs
|
|
||||||
mov %eax, %gs
|
|
||||||
mov %eax, %ss
|
|
||||||
|
|
||||||
/* Disable paging. */
|
|
||||||
mov %cr0, %eax
|
|
||||||
and $0x7fffffff, %eax
|
|
||||||
mov %eax, %cr0
|
|
||||||
|
|
||||||
/* Disable amd64. */
|
|
||||||
mov $0xc0000080, %ecx
|
|
||||||
rdmsr
|
|
||||||
and $0xfffffeff, %eax
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
/* Turn off PAE. */
|
|
||||||
movl %cr4, %eax
|
|
||||||
and $0xffffffcf, %eax
|
|
||||||
mov %eax, %cr4
|
|
||||||
|
|
||||||
jmp cont2
|
|
||||||
cont2:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
mov %ebx, %esi
|
|
||||||
|
|
||||||
jmp *%edi
|
|
||||||
|
|
||||||
/* GDT. */
|
|
||||||
.p2align 4
|
|
||||||
gdt:
|
|
||||||
/* NULL. */
|
|
||||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
/* Reserved. */
|
|
||||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
|
|
||||||
/* Code segment. */
|
|
||||||
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
|
|
||||||
|
|
||||||
/* Data segment. */
|
|
||||||
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
|
|
||||||
|
|
||||||
gdtdesc:
|
|
||||||
.word 31
|
|
||||||
gdtaddr:
|
|
||||||
.quad gdt
|
|
||||||
|
|
||||||
idtdesc:
|
|
||||||
.word 0
|
|
||||||
idtaddr:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
.p2align 4
|
|
||||||
jump_vector:
|
|
||||||
/* Jump location. Is filled by the code */
|
|
||||||
.long 0
|
|
||||||
.long 0x10
|
|
||||||
VARIABLE(grub_linux_trampoline_end)
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <grub/machine/biosnum.h>
|
#include <grub/machine/biosnum.h>
|
||||||
#endif
|
#endif
|
||||||
#include <grub/multiboot.h>
|
#include <grub/multiboot.h>
|
||||||
#include <grub/cpu/multiboot.h>
|
|
||||||
#include <grub/cpu/relocator.h>
|
#include <grub/cpu/relocator.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/device.h>
|
#include <grub/device.h>
|
||||||
|
@ -30,6 +29,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
#include <grub/relocator.h>
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
|
|
||||||
|
@ -52,6 +52,10 @@ static unsigned modcnt;
|
||||||
static char *cmdline = NULL;
|
static char *cmdline = NULL;
|
||||||
static grub_uint32_t bootdev;
|
static grub_uint32_t bootdev;
|
||||||
static int bootdev_set;
|
static int bootdev_set;
|
||||||
|
static grub_size_t elf_sec_num, elf_sec_entsize;
|
||||||
|
static unsigned elf_sec_shstrndx;
|
||||||
|
static void *elf_sections;
|
||||||
|
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_multiboot_load (grub_file_t file)
|
grub_multiboot_load (grub_file_t file)
|
||||||
|
@ -103,25 +107,24 @@ grub_multiboot_load (grub_file_t file)
|
||||||
int load_size = ((header->load_end_addr == 0) ? file->size - offset :
|
int load_size = ((header->load_end_addr == 0) ? file->size - offset :
|
||||||
header->load_end_addr - header->load_addr);
|
header->load_end_addr - header->load_addr);
|
||||||
grub_size_t code_size;
|
grub_size_t code_size;
|
||||||
|
void *source;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
if (header->bss_end_addr)
|
if (header->bss_end_addr)
|
||||||
code_size = (header->bss_end_addr - header->load_addr);
|
code_size = (header->bss_end_addr - header->load_addr);
|
||||||
else
|
else
|
||||||
code_size = load_size;
|
code_size = load_size;
|
||||||
grub_multiboot_payload_dest = header->load_addr;
|
|
||||||
|
|
||||||
grub_multiboot_pure_size += code_size;
|
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||||
|
&ch, header->load_addr,
|
||||||
/* Allocate a bit more to avoid relocations in most cases. */
|
code_size);
|
||||||
grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
|
if (err)
|
||||||
grub_multiboot_payload_orig
|
|
||||||
= grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
|
|
||||||
|
|
||||||
if (! grub_multiboot_payload_orig)
|
|
||||||
{
|
{
|
||||||
|
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return grub_errno;
|
return err;
|
||||||
}
|
}
|
||||||
|
source = get_virtual_current_address (ch);
|
||||||
|
|
||||||
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +132,7 @@ grub_multiboot_load (grub_file_t file)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
|
grub_file_read (file, source, load_size);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
{
|
{
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
|
@ -137,11 +140,10 @@ grub_multiboot_load (grub_file_t file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->bss_end_addr)
|
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);
|
header->bss_end_addr - header->load_addr - load_size);
|
||||||
|
|
||||||
grub_multiboot_payload_eip = header->entry_addr;
|
grub_multiboot_payload_eip = header->entry_addr;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -184,13 +186,14 @@ grub_multiboot_load (grub_file_t file)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_size_t
|
static grub_size_t
|
||||||
grub_multiboot_get_mbi_size (void)
|
grub_multiboot_get_mbi_size (void)
|
||||||
{
|
{
|
||||||
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
|
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
|
||||||
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
|
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
|
||||||
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4)
|
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4)
|
||||||
+ grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
|
+ grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
|
||||||
|
+ elf_sec_entsize * elf_sec_num
|
||||||
+ 256 * sizeof (struct multiboot_color);
|
+ 256 * sizeof (struct multiboot_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,20 +312,32 @@ retrieve_video_parameters (struct multiboot_info *mbi,
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
|
grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||||
grub_size_t bufsize)
|
|
||||||
{
|
{
|
||||||
grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off;
|
|
||||||
grub_uint32_t ptrdest = dest + buf_off;
|
|
||||||
struct multiboot_info *mbi;
|
struct multiboot_info *mbi;
|
||||||
struct multiboot_mod_list *modlist;
|
struct multiboot_mod_list *modlist;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
struct module *cur;
|
struct module *cur;
|
||||||
grub_size_t mmap_size;
|
grub_size_t mmap_size;
|
||||||
grub_err_t err;
|
grub_uint8_t *ptrorig;
|
||||||
|
grub_addr_t ptrdest;
|
||||||
|
|
||||||
if (bufsize < grub_multiboot_get_mbi_size ())
|
grub_err_t err;
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
|
grub_size_t bufsize;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
bufsize = grub_multiboot_get_mbi_size ();
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||||
|
0, 0xffffffff - bufsize,
|
||||||
|
bufsize, 4,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
ptrorig = get_virtual_current_address (ch);
|
||||||
|
ptrdest = (grub_addr_t) get_virtual_current_address (ch);
|
||||||
|
|
||||||
|
*target = ptrdest;
|
||||||
|
|
||||||
mbi = (struct multiboot_info *) ptrorig;
|
mbi = (struct multiboot_info *) ptrorig;
|
||||||
ptrorig += sizeof (*mbi);
|
ptrorig += sizeof (*mbi);
|
||||||
|
@ -386,6 +401,17 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
|
||||||
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
|
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elf_sec_num)
|
||||||
|
{
|
||||||
|
mbi->u.elf_sec.addr = ptrdest;
|
||||||
|
grub_memcpy (ptrorig, elf_sections, elf_sec_entsize * elf_sec_num);
|
||||||
|
mbi->u.elf_sec.num = elf_sec_num;
|
||||||
|
mbi->u.elf_sec.size = elf_sec_entsize;
|
||||||
|
mbi->u.elf_sec.shndx = elf_sec_shstrndx;
|
||||||
|
|
||||||
|
mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;
|
||||||
|
}
|
||||||
|
|
||||||
err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
|
err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@ -396,6 +422,16 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||||
|
unsigned shndx, void *data)
|
||||||
|
{
|
||||||
|
elf_sec_num = num;
|
||||||
|
elf_sec_shstrndx = shndx;
|
||||||
|
elf_sec_entsize = entsize;
|
||||||
|
elf_sections = data;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_multiboot_free_mbi (void)
|
grub_multiboot_free_mbi (void)
|
||||||
{
|
{
|
||||||
|
@ -416,6 +452,11 @@ grub_multiboot_free_mbi (void)
|
||||||
}
|
}
|
||||||
modules = NULL;
|
modules = NULL;
|
||||||
modules_last = NULL;
|
modules_last = NULL;
|
||||||
|
|
||||||
|
grub_free (elf_sections);
|
||||||
|
elf_sections = NULL;
|
||||||
|
elf_sec_entsize = 0;
|
||||||
|
elf_sec_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
|
|
|
@ -32,7 +32,9 @@
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
#include <grub/cpu/relocator.h>
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
|
#include <grub/i386/floppy.h>
|
||||||
|
|
||||||
#define GRUB_LINUX_CL_OFFSET 0x9000
|
#define GRUB_LINUX_CL_OFFSET 0x9000
|
||||||
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
|
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
|
||||||
|
@ -41,22 +43,37 @@ static grub_dl_t my_mod;
|
||||||
|
|
||||||
static grub_size_t linux_mem_size;
|
static grub_size_t linux_mem_size;
|
||||||
static int loaded;
|
static int loaded;
|
||||||
|
static struct grub_relocator *relocator = NULL;
|
||||||
|
static grub_addr_t grub_linux_real_target;
|
||||||
|
static char *grub_linux_real_chunk;
|
||||||
|
static grub_size_t grub_linux16_prot_size;
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux16_boot (void)
|
||||||
|
{
|
||||||
|
grub_uint16_t segment;
|
||||||
|
struct grub_relocator16_state state;
|
||||||
|
|
||||||
|
segment = grub_linux_real_target >> 4;
|
||||||
|
state.gs = state.fs = state.es = state.ds = state.ss = segment;
|
||||||
|
state.sp = GRUB_LINUX_SETUP_STACK;
|
||||||
|
state.cs = segment + 0x20;
|
||||||
|
state.ip = 0;
|
||||||
|
|
||||||
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
grub_stop_floppy ();
|
||||||
|
|
||||||
|
return grub_relocator16_boot (relocator, state);
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_unload (void)
|
grub_linux_unload (void)
|
||||||
{
|
{
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
return GRUB_ERR_NONE;
|
grub_relocator_unload (relocator);
|
||||||
}
|
relocator = NULL;
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux16_boot (void)
|
|
||||||
{
|
|
||||||
grub_video_set_mode ("text", 0, 0);
|
|
||||||
grub_linux16_real_boot ();
|
|
||||||
|
|
||||||
/* Not reached. */
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +84,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_file_t file = 0;
|
grub_file_t file = 0;
|
||||||
struct linux_kernel_header lh;
|
struct linux_kernel_header lh;
|
||||||
grub_uint8_t setup_sects;
|
grub_uint8_t setup_sects;
|
||||||
grub_size_t real_size, prot_size;
|
grub_size_t real_size;
|
||||||
grub_ssize_t len;
|
grub_ssize_t len;
|
||||||
int i;
|
int i;
|
||||||
char *dest;
|
char *dest;
|
||||||
|
char *grub_linux_prot_chunk;
|
||||||
|
int grub_linux_is_bzimage;
|
||||||
|
grub_addr_t grub_linux_prot_target;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -84,14 +105,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (! file)
|
if (! file)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((grub_size_t) grub_file_size (file) > grub_os_area_size)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
|
|
||||||
(grub_size_t) grub_file_size (file),
|
|
||||||
grub_os_area_size);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
|
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
|
||||||
|
@ -121,12 +134,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
|
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
|
||||||
|
|
||||||
/* Put the real mode part at as a high location as possible. */
|
/* Put the real mode part at as a high location as possible. */
|
||||||
grub_linux_real_addr
|
grub_linux_real_target = grub_mmap_get_lower ()
|
||||||
= (char *) UINT_TO_PTR (grub_mmap_get_lower ()
|
- GRUB_LINUX_SETUP_MOVE_SIZE;
|
||||||
- GRUB_LINUX_SETUP_MOVE_SIZE);
|
|
||||||
/* But it must not exceed the traditional area. */
|
/* But it must not exceed the traditional area. */
|
||||||
if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR)
|
if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR)
|
||||||
grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (lh.version) >= 0x0201)
|
if (grub_le_to_cpu16 (lh.version) >= 0x0201)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +147,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (lh.version) >= 0x0202)
|
if (grub_le_to_cpu16 (lh.version) >= 0x0202)
|
||||||
lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET;
|
lh.cmd_line_ptr = grub_linux_real_target + GRUB_LINUX_CL_OFFSET;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
|
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
|
||||||
|
@ -151,7 +163,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
||||||
|
|
||||||
grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If SETUP_SECTS is not set, set it to the default (4). */
|
/* If SETUP_SECTS is not set, set it to the default (4). */
|
||||||
|
@ -159,32 +171,36 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
||||||
|
|
||||||
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
||||||
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
|
grub_linux16_prot_size = grub_file_size (file)
|
||||||
|
- real_size - GRUB_DISK_SECTOR_SIZE;
|
||||||
grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size;
|
|
||||||
|
|
||||||
if (! grub_linux_is_bzimage
|
if (! grub_linux_is_bzimage
|
||||||
&& ((char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size > grub_linux_real_addr))
|
&& GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size
|
||||||
|
> grub_linux_real_target)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead",
|
grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead",
|
||||||
(char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size,
|
(char *) GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size,
|
||||||
(grub_size_t) grub_linux_real_addr);
|
(grub_size_t) grub_linux_real_target);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE
|
if (grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE
|
||||||
> (char *) UINT_TO_PTR (grub_mmap_get_lower ()))
|
> grub_mmap_get_lower ())
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
"too small lower memory (0x%x > 0x%x)",
|
"too small lower memory (0x%x > 0x%x)",
|
||||||
grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE,
|
grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE,
|
||||||
(int) grub_mmap_get_lower ());
|
(int) grub_mmap_get_lower ());
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_dprintf ("linux", "Linux-%s, setup=0x%x, size=0x%x\n",
|
grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n",
|
||||||
grub_linux_is_bzimage ? "bzImage" : "zImage",
|
grub_linux_is_bzimage ? "bzImage" : "zImage", real_size,
|
||||||
real_size, prot_size);
|
grub_linux16_prot_size);
|
||||||
|
|
||||||
|
relocator = grub_relocator_new ();
|
||||||
|
if (!relocator)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
if (grub_memcmp (argv[i], "vga=", 4) == 0)
|
if (grub_memcmp (argv[i], "vga=", 4) == 0)
|
||||||
|
@ -242,11 +258,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
grub_linux_real_target,
|
||||||
|
GRUB_LINUX_SETUP_MOVE_SIZE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
grub_linux_real_chunk = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
/* Put the real mode code at the temporary address. */
|
/* Put the real mode code at the temporary address. */
|
||||||
grub_memmove (grub_linux_tmp_addr, &lh, sizeof (lh));
|
grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh));
|
||||||
|
|
||||||
len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
|
len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
|
||||||
if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len)
|
if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -255,21 +281,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
|
if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
|
||||||
|| grub_le_to_cpu16 (lh.version) < 0x0200)
|
|| grub_le_to_cpu16 (lh.version) < 0x0200)
|
||||||
/* Clear the heap space. */
|
/* Clear the heap space. */
|
||||||
grub_memset (grub_linux_tmp_addr
|
grub_memset (grub_linux_real_chunk
|
||||||
+ ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS),
|
+ ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS),
|
||||||
0,
|
0,
|
||||||
((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
|
((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
|
||||||
<< GRUB_DISK_SECTOR_BITS));
|
<< GRUB_DISK_SECTOR_BITS));
|
||||||
|
|
||||||
/* Specify the boot file. */
|
/* Specify the boot file. */
|
||||||
dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET,
|
dest = grub_stpcpy (grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
|
||||||
"BOOT_IMAGE=");
|
"BOOT_IMAGE=");
|
||||||
dest = grub_stpcpy (dest, argv[0]);
|
dest = grub_stpcpy (dest, argv[0]);
|
||||||
|
|
||||||
/* Copy kernel parameters. */
|
/* Copy kernel parameters. */
|
||||||
for (i = 1;
|
for (i = 1;
|
||||||
i < argc
|
i < argc
|
||||||
&& dest + grub_strlen (argv[i]) + 1 < (grub_linux_tmp_addr
|
&& dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk
|
||||||
+ GRUB_LINUX_CL_END_OFFSET);
|
+ GRUB_LINUX_CL_END_OFFSET);
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
|
@ -277,14 +303,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
dest = grub_stpcpy (dest, argv[i]);
|
dest = grub_stpcpy (dest, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = prot_size;
|
if (grub_linux_is_bzimage)
|
||||||
if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
|
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
|
||||||
|
else
|
||||||
|
grub_linux_prot_target = GRUB_LINUX_ZIMAGE_ADDR;
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
grub_linux_prot_target,
|
||||||
|
grub_linux16_prot_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
grub_linux_prot_chunk = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = grub_linux16_prot_size;
|
||||||
|
if (grub_file_read (file, grub_linux_prot_chunk, grub_linux16_prot_size)
|
||||||
|
!= (grub_ssize_t) grub_linux16_prot_size)
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
{
|
{
|
||||||
grub_linux_prot_size = prot_size;
|
grub_loader_set (grub_linux16_boot, grub_linux_unload, 0);
|
||||||
grub_loader_set (grub_linux16_boot, grub_linux_unload, 1);
|
|
||||||
loaded = 1;
|
loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +337,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
grub_relocator_unload (relocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -308,8 +349,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_file_t file = 0;
|
grub_file_t file = 0;
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
grub_addr_t addr_max, addr_min, addr;
|
grub_addr_t addr_max, addr_min;
|
||||||
struct linux_kernel_header *lh;
|
struct linux_kernel_header *lh;
|
||||||
|
grub_uint8_t *initrd_chunk;
|
||||||
|
grub_addr_t initrd_addr;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
{
|
{
|
||||||
|
@ -323,7 +367,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
lh = (struct linux_kernel_header *) grub_linux_tmp_addr;
|
lh = (struct linux_kernel_header *) grub_linux_real_chunk;
|
||||||
|
|
||||||
if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
|
if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
|
||||||
&& grub_le_to_cpu16 (lh->version) >= 0x0200))
|
&& grub_le_to_cpu16 (lh->version) >= 0x0200))
|
||||||
|
@ -355,10 +399,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
|
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
|
||||||
addr_max -= 0x10000;
|
addr_max -= 0x10000;
|
||||||
|
|
||||||
if (addr_max > grub_os_area_addr + grub_os_area_size)
|
addr_min = GRUB_LINUX_BZIMAGE_ADDR + grub_linux16_prot_size;
|
||||||
addr_max = grub_os_area_addr + grub_os_area_size;
|
|
||||||
|
|
||||||
addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
file = grub_file_open (argv[0]);
|
||||||
if (!file)
|
if (!file)
|
||||||
|
@ -366,22 +407,25 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
size = grub_file_size (file);
|
size = grub_file_size (file);
|
||||||
|
|
||||||
/* Put the initrd as high as possible, 4KiB aligned. */
|
{
|
||||||
addr = (addr_max - size) & ~0xFFF;
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
|
addr_min, addr_max - size,
|
||||||
|
size, 0x1000,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_HIGH);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
initrd_chunk = get_virtual_current_address (ch);
|
||||||
|
initrd_addr = get_physical_target_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
if (addr < addr_min)
|
if (grub_file_read (file, initrd_chunk, size) != size)
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_file_read (file, (void *) addr, size) != size)
|
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
lh->ramdisk_image = addr;
|
lh->ramdisk_image = initrd_addr;
|
||||||
lh->ramdisk_size = size;
|
lh->ramdisk_size = size;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
157
grub-core/loader/i386/pc/ntldr.c
Normal file
157
grub-core/loader/i386/pc/ntldr.c
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/* chainloader.c - boot another boot loader */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2002,2004,2007,2009,2010 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/loader.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/device.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/machine/biosnum.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/video.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/cpu/relocator.h>
|
||||||
|
|
||||||
|
static grub_dl_t my_mod;
|
||||||
|
static struct grub_relocator *rel;
|
||||||
|
static grub_uint32_t edx = 0xffffffff;
|
||||||
|
|
||||||
|
#define GRUB_NTLDR_SEGMENT 0x2000
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_ntldr_boot (void)
|
||||||
|
{
|
||||||
|
struct grub_relocator16_state state = {
|
||||||
|
.cs = GRUB_NTLDR_SEGMENT,
|
||||||
|
.ip = 0,
|
||||||
|
.ds = 0,
|
||||||
|
.es = 0,
|
||||||
|
.fs = 0,
|
||||||
|
.gs = 0,
|
||||||
|
.ss = 0,
|
||||||
|
.sp = 0x7c00,
|
||||||
|
.edx = edx
|
||||||
|
};
|
||||||
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
return grub_relocator16_boot (rel, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_ntldr_unload (void)
|
||||||
|
{
|
||||||
|
grub_relocator_unload (rel);
|
||||||
|
rel = NULL;
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
grub_file_t file = 0;
|
||||||
|
grub_err_t err;
|
||||||
|
void *bs, *ntldr;
|
||||||
|
grub_size_t ntldrsize;
|
||||||
|
grub_device_t dev;
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
rel = grub_relocator_new ();
|
||||||
|
if (!rel)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
file = grub_file_open (argv[0]);
|
||||||
|
if (! file)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
|
||||||
|
GRUB_DISK_SECTOR_SIZE);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
bs = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
edx = grub_get_root_biosnumber ();
|
||||||
|
dev = grub_device_open (0);
|
||||||
|
|
||||||
|
if (dev && dev->disk)
|
||||||
|
{
|
||||||
|
err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_device_close (dev);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
grub_device_close (dev);
|
||||||
|
|
||||||
|
ntldrsize = grub_file_size (file);
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
|
||||||
|
ntldrsize);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
ntldr = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_read (file, ntldr, ntldrsize)
|
||||||
|
!= (grub_ssize_t) ntldrsize)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
|
||||||
|
grub_ntldr_unload ();
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_command_t cmd;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(ntldr)
|
||||||
|
{
|
||||||
|
cmd = grub_register_command ("ntldr", grub_cmd_ntldr,
|
||||||
|
0, N_("Load NTLDR or BootMGR."));
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(ntldr)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd);
|
||||||
|
}
|
|
@ -41,7 +41,6 @@
|
||||||
#define DEFAULT_VIDEO_MODE "auto"
|
#define DEFAULT_VIDEO_MODE "auto"
|
||||||
|
|
||||||
char grub_xnu_cmdline[1024];
|
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;
|
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
|
||||||
|
|
||||||
/* Aliases set for some tables. */
|
/* Aliases set for some tables. */
|
||||||
|
@ -837,11 +836,11 @@ grub_xnu_boot_resume (void)
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
|
|
||||||
state.esp = grub_xnu_stack;
|
state.esp = grub_xnu_stack;
|
||||||
|
state.ebp = grub_xnu_stack;
|
||||||
state.eip = grub_xnu_entry_point;
|
state.eip = grub_xnu_entry_point;
|
||||||
state.eax = grub_xnu_arg1;
|
state.eax = grub_xnu_arg1;
|
||||||
|
|
||||||
return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
|
return grub_relocator32_boot (grub_xnu_relocator, state);
|
||||||
state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup video for xnu. */
|
/* Setup video for xnu. */
|
||||||
|
@ -883,6 +882,18 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
|
||||||
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
|
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
|
||||||
|
|
||||||
if (grub_xnu_bitmap)
|
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)
|
||||||
{
|
{
|
||||||
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
|
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
|
||||||
err = grub_video_bitmap_create_scaled (&bitmap,
|
err = grub_video_bitmap_create_scaled (&bitmap,
|
||||||
|
@ -940,18 +951,18 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_xnu_boot (void)
|
grub_xnu_boot (void)
|
||||||
{
|
{
|
||||||
struct grub_xnu_boot_params *bootparams_relloc;
|
struct grub_xnu_boot_params *bootparams;
|
||||||
grub_off_t bootparams_relloc_off;
|
grub_addr_t bootparams_target;
|
||||||
grub_off_t mmap_relloc_off;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_efi_uintn_t memory_map_size = 0;
|
grub_efi_uintn_t memory_map_size = 0;
|
||||||
grub_efi_memory_descriptor_t *memory_map;
|
grub_efi_memory_descriptor_t *memory_map;
|
||||||
|
grub_addr_t memory_map_target;
|
||||||
grub_efi_uintn_t map_key = 0;
|
grub_efi_uintn_t map_key = 0;
|
||||||
grub_efi_uintn_t descriptor_size = 0;
|
grub_efi_uintn_t descriptor_size = 0;
|
||||||
grub_efi_uint32_t descriptor_version = 0;
|
grub_efi_uint32_t descriptor_version = 0;
|
||||||
grub_uint64_t firstruntimepage, lastruntimepage;
|
grub_uint64_t firstruntimepage, lastruntimepage;
|
||||||
grub_uint64_t curruntimepage;
|
grub_uint64_t curruntimepage;
|
||||||
void *devtree;
|
grub_addr_t devtree_target;
|
||||||
grub_size_t devtreelen;
|
grub_size_t devtreelen;
|
||||||
int i;
|
int i;
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
|
@ -995,26 +1006,25 @@ grub_xnu_boot (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Relocate the boot parameters to heap. */
|
/* Relocate the boot parameters to heap. */
|
||||||
bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
|
err = grub_xnu_heap_malloc (sizeof (*bootparams),
|
||||||
if (! bootparams_relloc)
|
(void **) &bootparams, &bootparams_target);
|
||||||
return grub_errno;
|
if (err)
|
||||||
bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
|
return err;
|
||||||
- (grub_uint8_t *) grub_xnu_heap_start;
|
|
||||||
|
|
||||||
/* Set video. */
|
/* Set video. */
|
||||||
err = grub_xnu_set_video (bootparams_relloc);
|
err = grub_xnu_set_video (bootparams);
|
||||||
if (err != GRUB_ERR_NONE)
|
if (err != GRUB_ERR_NONE)
|
||||||
{
|
{
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
grub_printf ("Booting in blind mode\n");
|
grub_printf ("Booting in blind mode\n");
|
||||||
|
|
||||||
bootparams_relloc->lfb_mode = 0;
|
bootparams->lfb_mode = 0;
|
||||||
bootparams_relloc->lfb_width = 0;
|
bootparams->lfb_width = 0;
|
||||||
bootparams_relloc->lfb_height = 0;
|
bootparams->lfb_height = 0;
|
||||||
bootparams_relloc->lfb_depth = 0;
|
bootparams->lfb_depth = 0;
|
||||||
bootparams_relloc->lfb_line_len = 0;
|
bootparams->lfb_line_len = 0;
|
||||||
bootparams_relloc->lfb_base = 0;
|
bootparams->lfb_base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
|
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
|
||||||
|
@ -1025,38 +1035,30 @@ grub_xnu_boot (void)
|
||||||
/* We will do few allocations later. Reserve some space for possible
|
/* We will do few allocations later. Reserve some space for possible
|
||||||
memory map growth. */
|
memory map growth. */
|
||||||
memory_map_size += 20 * descriptor_size;
|
memory_map_size += 20 * descriptor_size;
|
||||||
memory_map = grub_xnu_heap_malloc (memory_map_size);
|
err = grub_xnu_heap_malloc (memory_map_size,
|
||||||
if (! memory_map)
|
(void **) &memory_map, &memory_map_target);
|
||||||
return grub_errno;
|
|
||||||
mmap_relloc_off = (grub_uint8_t *) memory_map
|
|
||||||
- (grub_uint8_t *) grub_xnu_heap_start;
|
|
||||||
|
|
||||||
err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
bootparams_relloc = (struct grub_xnu_boot_params *)
|
|
||||||
(bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
|
|
||||||
|
|
||||||
grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
|
err = grub_xnu_writetree_toheap (&devtree_target, &devtreelen);
|
||||||
sizeof (bootparams_relloc->cmdline));
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
bootparams_relloc->devtree
|
grub_memcpy (bootparams->cmdline, grub_xnu_cmdline,
|
||||||
= ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start)
|
sizeof (bootparams->cmdline));
|
||||||
+ grub_xnu_heap_will_be_at;
|
|
||||||
bootparams_relloc->devtreelen = devtreelen;
|
|
||||||
|
|
||||||
memory_map = (grub_efi_memory_descriptor_t *)
|
bootparams->devtree = devtree_target;
|
||||||
((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off);
|
bootparams->devtreelen = devtreelen;
|
||||||
|
|
||||||
if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
|
err = grub_autoefi_finish_boot_services (&memory_map_size, memory_map,
|
||||||
&map_key, &descriptor_size,
|
&map_key, &descriptor_size,
|
||||||
&descriptor_version) <= 0)
|
&descriptor_version);
|
||||||
return grub_errno;
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
bootparams_relloc->efi_system_table
|
bootparams->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table);
|
||||||
= PTR_TO_UINT32 (grub_autoefi_system_table);
|
|
||||||
|
|
||||||
firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at
|
firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start
|
||||||
+ grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
|
+ grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
|
||||||
/ GRUB_XNU_PAGESIZE) + 20;
|
/ GRUB_XNU_PAGESIZE) + 20;
|
||||||
curruntimepage = firstruntimepage;
|
curruntimepage = firstruntimepage;
|
||||||
|
@ -1077,7 +1079,7 @@ grub_xnu_boot (void)
|
||||||
<= PTR_TO_UINT64 (grub_autoefi_system_table)
|
<= PTR_TO_UINT64 (grub_autoefi_system_table)
|
||||||
&& curdesc->physical_start + (curdesc->num_pages << 12)
|
&& curdesc->physical_start + (curdesc->num_pages << 12)
|
||||||
> PTR_TO_UINT64 (grub_autoefi_system_table))
|
> PTR_TO_UINT64 (grub_autoefi_system_table))
|
||||||
bootparams_relloc->efi_system_table
|
bootparams->efi_system_table
|
||||||
= PTR_TO_UINT64 (grub_autoefi_system_table)
|
= PTR_TO_UINT64 (grub_autoefi_system_table)
|
||||||
- curdesc->physical_start + curdesc->virtual_start;
|
- curdesc->physical_start + curdesc->virtual_start;
|
||||||
if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
|
if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
|
||||||
|
@ -1087,28 +1089,25 @@ grub_xnu_boot (void)
|
||||||
|
|
||||||
lastruntimepage = curruntimepage;
|
lastruntimepage = curruntimepage;
|
||||||
|
|
||||||
bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
|
bootparams->efi_mmap = memory_map_target;
|
||||||
bootparams_relloc->efi_mmap_size = memory_map_size;
|
bootparams->efi_mmap_size = memory_map_size;
|
||||||
bootparams_relloc->efi_mem_desc_size = descriptor_size;
|
bootparams->efi_mem_desc_size = descriptor_size;
|
||||||
bootparams_relloc->efi_mem_desc_version = descriptor_version;
|
bootparams->efi_mem_desc_version = descriptor_version;
|
||||||
|
|
||||||
bootparams_relloc->heap_start = grub_xnu_heap_will_be_at;
|
bootparams->heap_start = grub_xnu_heap_target_start;
|
||||||
bootparams_relloc->heap_size = grub_xnu_heap_size;
|
bootparams->heap_size = grub_xnu_heap_size;
|
||||||
bootparams_relloc->efi_runtime_first_page = firstruntimepage;
|
bootparams->efi_runtime_first_page = firstruntimepage;
|
||||||
|
|
||||||
bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage;
|
bootparams->efi_runtime_npages = lastruntimepage - firstruntimepage;
|
||||||
bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
|
bootparams->efi_uintnbits = SIZEOF_OF_UINTN * 8;
|
||||||
|
|
||||||
bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
|
bootparams->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
|
||||||
bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
|
bootparams->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
|
||||||
|
|
||||||
/* Parameters for asm helper. */
|
/* Parameters for asm helper. */
|
||||||
grub_xnu_stack = bootparams_relloc->heap_start
|
grub_xnu_stack = bootparams->heap_start
|
||||||
+ bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
|
+ bootparams->heap_size + GRUB_XNU_PAGESIZE;
|
||||||
grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
|
grub_xnu_arg1 = bootparams_target;
|
||||||
|
|
||||||
if (! grub_autoefi_exit_boot_services (map_key))
|
|
||||||
return grub_error (GRUB_ERR_IO, "can't exit boot services");
|
|
||||||
|
|
||||||
grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
|
grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
|
||||||
descriptor_version,memory_map);
|
descriptor_version,memory_map);
|
||||||
|
@ -1116,8 +1115,8 @@ grub_xnu_boot (void)
|
||||||
state.eip = grub_xnu_entry_point;
|
state.eip = grub_xnu_entry_point;
|
||||||
state.eax = grub_xnu_arg1;
|
state.eax = grub_xnu_arg1;
|
||||||
state.esp = grub_xnu_stack;
|
state.esp = grub_xnu_stack;
|
||||||
return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
|
state.ebp = grub_xnu_stack;
|
||||||
state);
|
return grub_relocator32_boot (grub_xnu_relocator, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd_devprop_load;
|
static grub_command_t cmd_devprop_load;
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/mips/relocator.h>
|
#include <grub/mips/relocator.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
|
@ -33,15 +32,13 @@
|
||||||
#include <grub/pci.h>
|
#include <grub/pci.h>
|
||||||
#include <grub/machine/time.h>
|
#include <grub/machine/time.h>
|
||||||
|
|
||||||
#define ELF32_LOADMASK (0x00000000UL)
|
|
||||||
#define ELF64_LOADMASK (0x0000000000000000ULL)
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
static int loaded;
|
static int loaded;
|
||||||
|
|
||||||
static grub_size_t linux_size;
|
static grub_size_t linux_size;
|
||||||
|
|
||||||
|
static struct grub_relocator *relocator;
|
||||||
static grub_uint8_t *playground;
|
static grub_uint8_t *playground;
|
||||||
static grub_addr_t target_addr, entry_addr;
|
static grub_addr_t target_addr, entry_addr;
|
||||||
static int linux_argc;
|
static int linux_argc;
|
||||||
|
@ -60,15 +57,7 @@ grub_linux_boot (void)
|
||||||
state.gpr[5] = target_addr + argv_off;
|
state.gpr[5] = target_addr + argv_off;
|
||||||
state.gpr[6] = target_addr + envp_off;
|
state.gpr[6] = target_addr + envp_off;
|
||||||
state.jumpreg = 1;
|
state.jumpreg = 1;
|
||||||
grub_relocator32_boot (playground, target_addr, state);
|
grub_relocator32_boot (relocator, state);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_linux_release_mem (void)
|
|
||||||
{
|
|
||||||
grub_relocator32_free (playground);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -76,14 +65,12 @@ grub_linux_release_mem (void)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_unload (void)
|
grub_linux_unload (void)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_relocator_unload (relocator);
|
||||||
|
|
||||||
err = grub_linux_release_mem ();
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
|
||||||
return err;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -91,9 +78,10 @@ grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
|
||||||
{
|
{
|
||||||
Elf32_Addr base;
|
Elf32_Addr base;
|
||||||
int extraoff;
|
int extraoff;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
/* Linux's entry point incorrectly contains a virtual address. */
|
/* Linux's entry point incorrectly contains a virtual address. */
|
||||||
entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
|
entry_addr = elf->ehdr.ehdr32.e_entry;
|
||||||
|
|
||||||
linux_size = grub_elf32_size (elf, &base);
|
linux_size = grub_elf32_size (elf, &base);
|
||||||
if (linux_size == 0)
|
if (linux_size == 0)
|
||||||
|
@ -105,10 +93,20 @@ grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
|
||||||
extraoff = linux_size;
|
extraoff = linux_size;
|
||||||
linux_size += extra_size;
|
linux_size += extra_size;
|
||||||
|
|
||||||
playground = grub_relocator32_alloc (linux_size);
|
relocator = grub_relocator_new ();
|
||||||
if (!playground)
|
if (!relocator)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
target_addr & 0x1fffffff,
|
||||||
|
linux_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
playground = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
*extra_mem = playground + extraoff;
|
*extra_mem = playground + extraoff;
|
||||||
|
|
||||||
/* Now load the segments into the area we claimed. */
|
/* Now load the segments into the area we claimed. */
|
||||||
|
@ -135,9 +133,10 @@ grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
|
||||||
{
|
{
|
||||||
Elf64_Addr base;
|
Elf64_Addr base;
|
||||||
int extraoff;
|
int extraoff;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
/* Linux's entry point incorrectly contains a virtual address. */
|
/* Linux's entry point incorrectly contains a virtual address. */
|
||||||
entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
|
entry_addr = elf->ehdr.ehdr64.e_entry;
|
||||||
|
|
||||||
linux_size = grub_elf64_size (elf, &base);
|
linux_size = grub_elf64_size (elf, &base);
|
||||||
if (linux_size == 0)
|
if (linux_size == 0)
|
||||||
|
@ -149,10 +148,20 @@ grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
|
||||||
extraoff = linux_size;
|
extraoff = linux_size;
|
||||||
linux_size += extra_size;
|
linux_size += extra_size;
|
||||||
|
|
||||||
playground = grub_relocator32_alloc (linux_size);
|
relocator = grub_relocator_new ();
|
||||||
if (!playground)
|
if (!relocator)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
target_addr & 0x1fffffff,
|
||||||
|
linux_size);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
playground = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
*extra_mem = playground + extraoff;
|
*extra_mem = playground + extraoff;
|
||||||
|
|
||||||
/* Now load the segments into the area we claimed. */
|
/* Now load the segments into the area we claimed. */
|
||||||
|
@ -322,7 +331,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_file_t file = 0;
|
grub_file_t file = 0;
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
grub_size_t overhead;
|
void *initrd_src;
|
||||||
|
grub_addr_t initrd_dest;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
|
||||||
|
@ -339,19 +350,25 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
size = grub_file_size (file);
|
size = grub_file_size (file);
|
||||||
|
|
||||||
overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000)
|
{
|
||||||
- (target_addr + linux_size);
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
playground = grub_relocator32_realloc (playground,
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
linux_size + overhead + size);
|
target_addr + linux_size + 0x10000,
|
||||||
|
(0xffffffff - size) + 1,
|
||||||
|
size, 0x10000,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
|
||||||
if (!playground)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
return grub_errno;
|
return err;
|
||||||
}
|
}
|
||||||
|
initrd_src = get_virtual_current_address (ch);
|
||||||
|
initrd_dest = get_physical_target_address (ch) | 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
grub_file_close (file);
|
||||||
|
@ -361,7 +378,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
grub_snprintf ((char *) playground + rd_addr_arg_off,
|
grub_snprintf ((char *) playground + rd_addr_arg_off,
|
||||||
sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
|
sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
|
||||||
(unsigned long long) target_addr + linux_size + overhead);
|
(unsigned long long) initrd_dest);
|
||||||
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
||||||
= target_addr + rd_addr_arg_off;
|
= target_addr + rd_addr_arg_off;
|
||||||
linux_argc++;
|
linux_argc++;
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/multiboot.h>
|
#include <grub/multiboot.h>
|
||||||
#include <grub/cpu/multiboot.h>
|
#include <grub/cpu/multiboot.h>
|
||||||
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/elf.h>
|
#include <grub/elf.h>
|
||||||
#include <grub/aout.h>
|
#include <grub/aout.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
|
@ -50,18 +50,14 @@
|
||||||
#include <grub/efi/efi.h>
|
#include <grub/efi/efi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct grub_relocator *grub_multiboot_relocator = NULL;
|
||||||
|
grub_uint32_t grub_multiboot_payload_eip;
|
||||||
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
|
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
|
||||||
#define DEFAULT_VIDEO_MODE "text"
|
#define DEFAULT_VIDEO_MODE "text"
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_VIDEO_MODE "auto"
|
#define DEFAULT_VIDEO_MODE "auto"
|
||||||
#endif
|
#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_video;
|
||||||
static int accepts_ega_text;
|
static int accepts_ega_text;
|
||||||
static int console_required;
|
static int console_required;
|
||||||
|
@ -119,45 +115,23 @@ grub_multiboot_set_video_mode (void)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_multiboot_boot (void)
|
grub_multiboot_boot (void)
|
||||||
{
|
{
|
||||||
grub_size_t mbi_size;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE;
|
struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE;
|
||||||
|
|
||||||
state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip;
|
state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip;
|
||||||
|
|
||||||
mbi_size = grub_multiboot_get_mbi_size ();
|
err = grub_multiboot_make_mbi (&state.MULTIBOOT_MBI_REGISTER);
|
||||||
if (grub_multiboot_alloc_mbi < mbi_size)
|
|
||||||
{
|
|
||||||
grub_multiboot_payload_orig
|
|
||||||
= grub_relocator32_realloc (grub_multiboot_payload_orig,
|
|
||||||
grub_multiboot_pure_size + mbi_size);
|
|
||||||
if (!grub_multiboot_payload_orig)
|
|
||||||
return grub_errno;
|
|
||||||
grub_multiboot_alloc_mbi = mbi_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GRUB_USE_MULTIBOOT2
|
|
||||||
state.MULTIBOOT_MBI_REGISTER = ALIGN_UP (grub_multiboot_payload_dest
|
|
||||||
+ grub_multiboot_pure_size,
|
|
||||||
MULTIBOOT_TAG_ALIGN);
|
|
||||||
#else
|
|
||||||
state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest
|
|
||||||
+ grub_multiboot_pure_size;
|
|
||||||
#endif
|
|
||||||
err = grub_multiboot_make_mbi (grub_multiboot_payload_orig,
|
|
||||||
grub_multiboot_payload_dest,
|
|
||||||
grub_multiboot_pure_size, mbi_size);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
#ifdef GRUB_MACHINE_EFI
|
||||||
if (! grub_efi_finish_boot_services ())
|
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
|
||||||
grub_fatal ("cannot exit boot services");
|
if (err)
|
||||||
|
return err;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
grub_relocator32_boot (grub_multiboot_payload_orig,
|
grub_relocator32_boot (grub_multiboot_relocator, state);
|
||||||
grub_multiboot_payload_dest,
|
|
||||||
state);
|
|
||||||
|
|
||||||
/* Not reached. */
|
/* Not reached. */
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -168,11 +142,9 @@ grub_multiboot_unload (void)
|
||||||
{
|
{
|
||||||
grub_multiboot_free_mbi ();
|
grub_multiboot_free_mbi ();
|
||||||
|
|
||||||
grub_relocator32_free (grub_multiboot_payload_orig);
|
grub_relocator_unload (grub_multiboot_relocator);
|
||||||
|
grub_multiboot_relocator = NULL;
|
||||||
|
|
||||||
grub_multiboot_alloc_mbi = 0;
|
|
||||||
|
|
||||||
grub_multiboot_payload_orig = NULL;
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -262,8 +234,11 @@ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
|
||||||
/* Skip filename. */
|
/* Skip filename. */
|
||||||
grub_multiboot_init_mbi (argc - 1, argv + 1);
|
grub_multiboot_init_mbi (argc - 1, argv + 1);
|
||||||
|
|
||||||
grub_relocator32_free (grub_multiboot_payload_orig);
|
grub_relocator_unload (grub_multiboot_relocator);
|
||||||
grub_multiboot_payload_orig = NULL;
|
grub_multiboot_relocator = grub_relocator_new ();
|
||||||
|
|
||||||
|
if (!grub_multiboot_relocator)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
err = grub_multiboot_load (file);
|
err = grub_multiboot_load (file);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -279,8 +254,8 @@ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
{
|
{
|
||||||
grub_relocator32_free (grub_multiboot_payload_orig);
|
grub_relocator_unload (grub_multiboot_relocator);
|
||||||
grub_multiboot_free_mbi ();
|
grub_multiboot_relocator = NULL;
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +268,8 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_file_t file = 0;
|
grub_file_t file = 0;
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
char *module = 0;
|
void *module = NULL;
|
||||||
|
grub_addr_t target;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
int nounzip = 0;
|
int nounzip = 0;
|
||||||
|
|
||||||
|
@ -310,7 +286,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
|
||||||
|
|
||||||
if (!grub_multiboot_payload_orig)
|
if (!grub_multiboot_relocator)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
"you need to load the multiboot kernel first");
|
"you need to load the multiboot kernel first");
|
||||||
|
|
||||||
|
@ -322,15 +298,22 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
size = grub_file_size (file);
|
size = grub_file_size (file);
|
||||||
module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
|
{
|
||||||
if (! module)
|
grub_relocator_chunk_t ch;
|
||||||
{
|
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||||
grub_file_close (file);
|
0, (0xffffffff - size) + 1,
|
||||||
return grub_errno;
|
size, MULTIBOOT_MOD_ALIGN,
|
||||||
}
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
module = get_virtual_current_address (ch);
|
||||||
|
target = (grub_addr_t) get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
err = grub_multiboot_add_module ((grub_addr_t) module, size,
|
err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
|
||||||
argc - 1, argv + 1);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
|
|
@ -51,9 +51,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
|
||||||
{
|
{
|
||||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
|
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
|
||||||
char *phdr_base;
|
char *phdr_base;
|
||||||
int lowest_segment = -1, highest_segment = -1;
|
|
||||||
int i;
|
int i;
|
||||||
grub_size_t code_size;
|
|
||||||
|
|
||||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX)
|
if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX)
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
|
return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
|
||||||
|
@ -87,55 +85,45 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
|
||||||
phdr_base = (char *) buffer + ehdr->e_phoff;
|
phdr_base = (char *) buffer + ehdr->e_phoff;
|
||||||
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
|
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++)
|
|
||||||
if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
|
|
||||||
{
|
|
||||||
/* Beware that segment 0 isn't necessarily loadable */
|
|
||||||
if (lowest_segment == -1
|
|
||||||
|| phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
|
|
||||||
lowest_segment = i;
|
|
||||||
if (highest_segment == -1
|
|
||||||
|| phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
|
|
||||||
highest_segment = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowest_segment == -1)
|
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "ELF contains no loadable segments");
|
|
||||||
|
|
||||||
code_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
|
|
||||||
grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
|
|
||||||
|
|
||||||
grub_multiboot_pure_size += code_size;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Load every loadable segment in memory. */
|
/* Load every loadable segment in memory. */
|
||||||
for (i = 0; i < ehdr->e_phnum; i++)
|
for (i = 0; i < ehdr->e_phnum; i++)
|
||||||
{
|
{
|
||||||
if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
|
if (phdr(i)->p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (long) (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
|
grub_err_t err;
|
||||||
|
void *source;
|
||||||
|
|
||||||
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
|
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
|
||||||
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
|
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
|
||||||
|
|
||||||
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
|
{
|
||||||
== (grub_off_t) -1)
|
grub_relocator_chunk_t ch;
|
||||||
return grub_error (GRUB_ERR_BAD_OS,
|
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||||
"invalid offset in program header");
|
&ch, phdr(i)->p_paddr,
|
||||||
|
phdr(i)->p_memsz);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
source = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
|
if (phdr(i)->p_filesz != 0)
|
||||||
!= (grub_ssize_t) phdr(i)->p_filesz)
|
{
|
||||||
return grub_error (GRUB_ERR_BAD_OS,
|
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
|
||||||
"couldn't read segment from file");
|
== (grub_off_t) -1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset in program header");
|
||||||
|
|
||||||
|
if (grub_file_read (file, source, phdr(i)->p_filesz)
|
||||||
|
!= (grub_ssize_t) phdr(i)->p_filesz)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read segment from file");
|
||||||
|
}
|
||||||
|
|
||||||
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
|
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
|
||||||
grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
|
grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
|
||||||
phdr(i)->p_memsz - phdr(i)->p_filesz);
|
phdr(i)->p_memsz - phdr(i)->p_filesz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,14 +132,87 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
|
||||||
if (phdr(i)->p_vaddr <= ehdr->e_entry
|
if (phdr(i)->p_vaddr <= ehdr->e_entry
|
||||||
&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
|
&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
|
||||||
{
|
{
|
||||||
grub_multiboot_payload_eip = grub_multiboot_payload_dest
|
grub_multiboot_payload_eip = (ehdr->e_entry - phdr(i)->p_vaddr)
|
||||||
+ (ehdr->e_entry - phdr(i)->p_vaddr) + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr);
|
+ phdr(i)->p_paddr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == ehdr->e_phnum)
|
if (i == ehdr->e_phnum)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
|
return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
|
||||||
|
#elif defined (__mips)
|
||||||
|
grub_multiboot_payload_eip |= 0x80000000;
|
||||||
|
#else
|
||||||
|
#error Please complete this
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ehdr->e_shnum)
|
||||||
|
{
|
||||||
|
grub_uint8_t *shdr, *shdrptr;
|
||||||
|
|
||||||
|
shdr = grub_malloc (ehdr->e_shnum * ehdr->e_shentsize);
|
||||||
|
if (!shdr)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset to section headers");
|
||||||
|
|
||||||
|
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
|
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read sections headers from file");
|
||||||
|
|
||||||
|
for (shdrptr = shdr, i = 0; i < ehdr->e_shnum;
|
||||||
|
shdrptr += ehdr->e_shentsize, i++)
|
||||||
|
{
|
||||||
|
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
|
||||||
|
void *src;
|
||||||
|
grub_addr_t target;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
/* This section is a loaded section,
|
||||||
|
so we don't care. */
|
||||||
|
if (sh->sh_addr != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* This section is empty, so we don't care. */
|
||||||
|
if (sh->sh_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||||
|
&ch, 0,
|
||||||
|
(0xffffffff - sh->sh_size)
|
||||||
|
+ 1, sh->sh_size,
|
||||||
|
sh->sh_addralign,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
src = get_virtual_current_address (ch);
|
||||||
|
target = get_physical_target_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset in section header");
|
||||||
|
|
||||||
|
if (grub_file_read (file, src, sh->sh_size)
|
||||||
|
!= (grub_ssize_t) sh->sh_size)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read segment from file");
|
||||||
|
sh->sh_addr = target;
|
||||||
|
}
|
||||||
|
grub_multiboot_add_elfsyms (ehdr->e_shnum, ehdr->e_shentsize,
|
||||||
|
ehdr->e_shstrndx, shdr);
|
||||||
|
}
|
||||||
|
|
||||||
#undef phdr
|
#undef phdr
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -55,6 +55,19 @@ static unsigned modcnt;
|
||||||
static char *cmdline = NULL;
|
static char *cmdline = NULL;
|
||||||
static int bootdev_set;
|
static int bootdev_set;
|
||||||
static grub_uint32_t biosdev, slice, part;
|
static grub_uint32_t biosdev, slice, part;
|
||||||
|
static grub_size_t elf_sec_num, elf_sec_entsize;
|
||||||
|
static unsigned elf_sec_shstrndx;
|
||||||
|
static void *elf_sections;
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||||
|
unsigned shndx, void *data)
|
||||||
|
{
|
||||||
|
elf_sec_num = num;
|
||||||
|
elf_sec_shstrndx = shndx;
|
||||||
|
elf_sec_entsize = entsize;
|
||||||
|
elf_sections = data;
|
||||||
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_multiboot_load (grub_file_t file)
|
grub_multiboot_load (grub_file_t file)
|
||||||
|
@ -190,25 +203,24 @@ grub_multiboot_load (grub_file_t file)
|
||||||
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
|
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
|
||||||
addr_tag->load_end_addr - addr_tag->load_addr);
|
addr_tag->load_end_addr - addr_tag->load_addr);
|
||||||
grub_size_t code_size;
|
grub_size_t code_size;
|
||||||
|
void *source;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
if (addr_tag->bss_end_addr)
|
if (addr_tag->bss_end_addr)
|
||||||
code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
|
code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
|
||||||
else
|
else
|
||||||
code_size = load_size;
|
code_size = load_size;
|
||||||
grub_multiboot_payload_dest = addr_tag->load_addr;
|
|
||||||
|
|
||||||
grub_multiboot_pure_size += code_size;
|
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||||
|
&ch, addr_tag->load_addr,
|
||||||
/* Allocate a bit more to avoid relocations in most cases. */
|
code_size);
|
||||||
grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
|
if (err)
|
||||||
grub_multiboot_payload_orig
|
|
||||||
= grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
|
|
||||||
|
|
||||||
if (! grub_multiboot_payload_orig)
|
|
||||||
{
|
{
|
||||||
|
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return grub_errno;
|
return err;
|
||||||
}
|
}
|
||||||
|
source = get_virtual_current_address (ch);
|
||||||
|
|
||||||
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
||||||
{
|
{
|
||||||
|
@ -216,7 +228,7 @@ grub_multiboot_load (grub_file_t file)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
|
grub_file_read (file, source, load_size);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
{
|
{
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
|
@ -224,7 +236,7 @@ grub_multiboot_load (grub_file_t file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr_tag->bss_end_addr)
|
if (addr_tag->bss_end_addr)
|
||||||
grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
|
grub_memset ((grub_uint32_t *) source + load_size, 0,
|
||||||
addr_tag->bss_end_addr - addr_tag->load_addr - load_size);
|
addr_tag->bss_end_addr - addr_tag->load_addr - load_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -252,7 +264,7 @@ grub_multiboot_load (grub_file_t file)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_size_t
|
static grub_size_t
|
||||||
grub_multiboot_get_mbi_size (void)
|
grub_multiboot_get_mbi_size (void)
|
||||||
{
|
{
|
||||||
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||||
|
@ -263,6 +275,8 @@ grub_multiboot_get_mbi_size (void)
|
||||||
+ (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
|
+ (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
|
||||||
+ sizeof (struct multiboot_tag_basic_meminfo)
|
+ sizeof (struct multiboot_tag_basic_meminfo)
|
||||||
+ ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
|
+ ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
|
||||||
|
+ sizeof (struct multiboot_tag_elf_sections)
|
||||||
|
+ elf_sec_entsize * elf_sec_num
|
||||||
+ (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
|
+ (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
|
||||||
* sizeof (struct multiboot_mmap_entry))
|
* sizeof (struct multiboot_mmap_entry))
|
||||||
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
|
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
|
||||||
|
@ -456,18 +470,34 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
|
grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||||
grub_size_t bufsize)
|
|
||||||
{
|
{
|
||||||
grub_uint8_t *ptrorig;
|
grub_uint8_t *ptrorig;
|
||||||
grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off
|
grub_uint8_t *mbistart;
|
||||||
+ (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
grub_size_t bufsize;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
if (bufsize < grub_multiboot_get_mbi_size ())
|
bufsize = grub_multiboot_get_mbi_size ();
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
|
|
||||||
|
|
||||||
ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
|
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||||
|
0, 0xffffffff - bufsize,
|
||||||
|
bufsize, 4,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ptrorig = get_virtual_current_address (ch);
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
*target = get_physical_target_address (ch);
|
||||||
|
#elif defined (__mips)
|
||||||
|
*target = get_physical_target_address (ch) | 0x80000000;
|
||||||
|
#else
|
||||||
|
#error Please complete this
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mbistart = ptrorig;
|
||||||
|
ptrorig += 2 * sizeof (grub_uint32_t);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
|
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
|
||||||
|
@ -508,6 +538,19 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
|
||||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
|
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct multiboot_tag_elf_sections *tag
|
||||||
|
= (struct multiboot_tag_elf_sections *) ptrorig;
|
||||||
|
tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS;
|
||||||
|
tag->size = sizeof (struct multiboot_tag_elf_sections)
|
||||||
|
+ elf_sec_entsize * elf_sec_num;
|
||||||
|
grub_memcpy (tag->sections, elf_sections, elf_sec_entsize * elf_sec_num);
|
||||||
|
tag->num = elf_sec_num;
|
||||||
|
tag->entsize = elf_sec_entsize;
|
||||||
|
tag->shndx = elf_sec_shstrndx;
|
||||||
|
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct multiboot_tag_basic_meminfo *tag
|
struct multiboot_tag_basic_meminfo *tag
|
||||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/ieee1275/ieee1275.h>
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/ieee1275/ieee1275.h>
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/gzio.h>
|
#include <grub/gzio.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
|
@ -40,45 +40,30 @@ static int driverspackagenum = 0;
|
||||||
static int driversnum = 0;
|
static int driversnum = 0;
|
||||||
int grub_xnu_is_64bit = 0;
|
int grub_xnu_is_64bit = 0;
|
||||||
|
|
||||||
void *grub_xnu_heap_start = 0;
|
grub_addr_t grub_xnu_heap_target_start = 0;
|
||||||
grub_size_t grub_xnu_heap_size = 0;
|
grub_size_t grub_xnu_heap_size = 0;
|
||||||
|
struct grub_relocator *grub_xnu_relocator;
|
||||||
/* Allocate heap by 32MB-blocks. */
|
|
||||||
#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_xnu_register_memory (char *prefix, int *suffix,
|
grub_xnu_register_memory (char *prefix, int *suffix,
|
||||||
void *addr, grub_size_t size);
|
grub_addr_t addr, grub_size_t size);
|
||||||
void *
|
grub_err_t
|
||||||
grub_xnu_heap_malloc (int size)
|
grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
|
||||||
{
|
{
|
||||||
void *val;
|
grub_err_t err;
|
||||||
int oldblknum, newblknum;
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
/* The page after the heap is used for stack. Ensure it's usable. */
|
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
|
||||||
if (grub_xnu_heap_size)
|
grub_xnu_heap_target_start
|
||||||
oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
|
+ grub_xnu_heap_size, size);
|
||||||
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
|
if (err)
|
||||||
else
|
return err;
|
||||||
oldblknum = 0;
|
|
||||||
newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
|
|
||||||
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
|
|
||||||
if (oldblknum != newblknum)
|
|
||||||
{
|
|
||||||
/* FIXME: instruct realloc to allocate at 1MB if possible once
|
|
||||||
advanced mm is ready. */
|
|
||||||
grub_xnu_heap_start
|
|
||||||
= XNU_RELOCATOR (realloc) (grub_xnu_heap_start,
|
|
||||||
newblknum
|
|
||||||
* GRUB_XNU_HEAP_ALLOC_BLOCK);
|
|
||||||
if (!grub_xnu_heap_start)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size;
|
*src = get_virtual_current_address (ch);
|
||||||
|
*target = grub_xnu_heap_target_start + grub_xnu_heap_size;
|
||||||
grub_xnu_heap_size += size;
|
grub_xnu_heap_size += size;
|
||||||
grub_dprintf ("xnu", "val=%p\n", val);
|
grub_dprintf ("xnu", "val=%p\n", *src);
|
||||||
return val;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure next block of the heap will be aligned.
|
/* Make sure next block of the heap will be aligned.
|
||||||
|
@ -87,11 +72,9 @@ grub_xnu_heap_malloc (int size)
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_xnu_align_heap (int align)
|
grub_xnu_align_heap (int align)
|
||||||
{
|
{
|
||||||
int align_overhead = align - grub_xnu_heap_size % align;
|
grub_xnu_heap_size
|
||||||
if (align_overhead == align)
|
= ALIGN_UP (grub_xnu_heap_target_start+ grub_xnu_heap_size, align)
|
||||||
return GRUB_ERR_NONE;
|
- grub_xnu_heap_target_start;
|
||||||
if (! grub_xnu_heap_malloc (align_overhead))
|
|
||||||
return grub_errno;
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,13 +190,14 @@ grub_xnu_writetree_toheap_real (void *curptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_xnu_writetree_toheap (void **start, grub_size_t *size)
|
grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size)
|
||||||
{
|
{
|
||||||
struct grub_xnu_devtree_key *chosen;
|
struct grub_xnu_devtree_key *chosen;
|
||||||
struct grub_xnu_devtree_key *memorymap;
|
struct grub_xnu_devtree_key *memorymap;
|
||||||
struct grub_xnu_devtree_key *driverkey;
|
struct grub_xnu_devtree_key *driverkey;
|
||||||
struct grub_xnu_extdesc *extdesc;
|
struct grub_xnu_extdesc *extdesc;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
void *src;
|
||||||
|
|
||||||
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
|
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -244,16 +228,17 @@ grub_xnu_writetree_toheap (void **start, grub_size_t *size)
|
||||||
|
|
||||||
/* Allocate the space based on the size with dummy value. */
|
/* Allocate the space based on the size with dummy value. */
|
||||||
*size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
|
*size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
|
||||||
*start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
|
err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE),
|
||||||
- *size % GRUB_XNU_PAGESIZE);
|
&src, target);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* Put real data in the dummy. */
|
/* Put real data in the dummy. */
|
||||||
extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start
|
extdesc->addr = *target;
|
||||||
+ grub_xnu_heap_will_be_at;
|
|
||||||
extdesc->size = (grub_uint32_t) *size;
|
extdesc->size = (grub_uint32_t) *size;
|
||||||
|
|
||||||
/* Write the tree to heap. */
|
/* Write the tree to heap. */
|
||||||
grub_xnu_writetree_toheap_real (*start, grub_xnu_devtree_root, "/");
|
grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/");
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,8 +323,9 @@ grub_xnu_unload (void)
|
||||||
/* Free loaded image. */
|
/* Free loaded image. */
|
||||||
driversnum = 0;
|
driversnum = 0;
|
||||||
driverspackagenum = 0;
|
driverspackagenum = 0;
|
||||||
grub_free (grub_xnu_heap_start);
|
grub_relocator_unload (grub_xnu_relocator);
|
||||||
grub_xnu_heap_start = 0;
|
grub_xnu_relocator = NULL;
|
||||||
|
grub_xnu_heap_target_start = 0;
|
||||||
grub_xnu_heap_size = 0;
|
grub_xnu_heap_size = 0;
|
||||||
grub_xnu_unlock ();
|
grub_xnu_unlock ();
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -354,6 +340,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_uint32_t startcode, endcode;
|
grub_uint32_t startcode, endcode;
|
||||||
int i;
|
int i;
|
||||||
char *ptr, *loadaddr;
|
char *ptr, *loadaddr;
|
||||||
|
grub_addr_t loadaddr_target;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||||
|
@ -381,15 +368,18 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
|
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
|
||||||
(unsigned long) endcode, (unsigned long) startcode);
|
(unsigned long) endcode, (unsigned long) startcode);
|
||||||
|
|
||||||
loadaddr = grub_xnu_heap_malloc (endcode - startcode);
|
grub_xnu_relocator = grub_relocator_new ();
|
||||||
grub_xnu_heap_will_be_at = startcode;
|
if (!grub_xnu_relocator)
|
||||||
|
return grub_errno;
|
||||||
|
grub_xnu_heap_target_start = startcode;
|
||||||
|
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
|
||||||
|
&loadaddr_target);
|
||||||
|
|
||||||
if (! loadaddr)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_macho_close (macho);
|
grub_macho_close (macho);
|
||||||
grub_xnu_unload ();
|
grub_xnu_unload ();
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
return err;
|
||||||
"not enough memory to load kernel");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load kernel. */
|
/* Load kernel. */
|
||||||
|
@ -452,6 +442,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_uint64_t startcode, endcode;
|
grub_uint64_t startcode, endcode;
|
||||||
int i;
|
int i;
|
||||||
char *ptr, *loadaddr;
|
char *ptr, *loadaddr;
|
||||||
|
grub_addr_t loadaddr_target;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||||
|
@ -482,15 +473,18 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
|
grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
|
||||||
(unsigned long) endcode, (unsigned long) startcode);
|
(unsigned long) endcode, (unsigned long) startcode);
|
||||||
|
|
||||||
loadaddr = grub_xnu_heap_malloc (endcode - startcode);
|
grub_xnu_relocator = grub_relocator_new ();
|
||||||
grub_xnu_heap_will_be_at = startcode;
|
if (!grub_xnu_relocator)
|
||||||
|
return grub_errno;
|
||||||
|
grub_xnu_heap_target_start = startcode;
|
||||||
|
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
|
||||||
|
&loadaddr_target);
|
||||||
|
|
||||||
if (! loadaddr)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_macho_close (macho);
|
grub_macho_close (macho);
|
||||||
grub_xnu_unload ();
|
grub_xnu_unload ();
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
return err;
|
||||||
"not enough memory to load kernel");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load kernel. */
|
/* Load kernel. */
|
||||||
|
@ -548,7 +542,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
|
||||||
and increment SUFFIX. */
|
and increment SUFFIX. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_xnu_register_memory (char *prefix, int *suffix,
|
grub_xnu_register_memory (char *prefix, int *suffix,
|
||||||
void *addr, grub_size_t size)
|
grub_addr_t addr, grub_size_t size)
|
||||||
{
|
{
|
||||||
struct grub_xnu_devtree_key *chosen;
|
struct grub_xnu_devtree_key *chosen;
|
||||||
struct grub_xnu_devtree_key *memorymap;
|
struct grub_xnu_devtree_key *memorymap;
|
||||||
|
@ -585,8 +579,7 @@ grub_xnu_register_memory (char *prefix, int *suffix,
|
||||||
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
|
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
|
||||||
if (! driverkey->data)
|
if (! driverkey->data)
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
|
||||||
extdesc->addr = grub_xnu_heap_will_be_at +
|
extdesc->addr = addr;
|
||||||
((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
|
|
||||||
extdesc->size = (grub_uint32_t) size;
|
extdesc->size = (grub_uint32_t) size;
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -628,7 +621,8 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
|
||||||
grub_file_t infoplist;
|
grub_file_t infoplist;
|
||||||
struct grub_xnu_extheader *exthead;
|
struct grub_xnu_extheader *exthead;
|
||||||
int neededspace = sizeof (*exthead);
|
int neededspace = sizeof (*exthead);
|
||||||
grub_uint8_t *buf;
|
grub_uint8_t *buf, *buf0;
|
||||||
|
grub_addr_t buf_target;
|
||||||
grub_size_t infoplistsize = 0, machosize = 0;
|
grub_size_t infoplistsize = 0, machosize = 0;
|
||||||
char *name, *nameend;
|
char *name, *nameend;
|
||||||
int namelen;
|
int namelen;
|
||||||
|
@ -683,7 +677,10 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
|
||||||
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
|
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
buf = grub_xnu_heap_malloc (neededspace);
|
err = grub_xnu_heap_malloc (neededspace, (void **) &buf0, &buf_target);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
buf = buf0;
|
||||||
|
|
||||||
exthead = (struct grub_xnu_extheader *) buf;
|
exthead = (struct grub_xnu_extheader *) buf;
|
||||||
grub_memset (exthead, 0, sizeof (*exthead));
|
grub_memset (exthead, 0, sizeof (*exthead));
|
||||||
|
@ -692,8 +689,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
|
||||||
/* Load the binary. */
|
/* Load the binary. */
|
||||||
if (macho)
|
if (macho)
|
||||||
{
|
{
|
||||||
exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
|
exthead->binaryaddr = buf_target + (buf - buf0);
|
||||||
+ grub_xnu_heap_will_be_at;
|
|
||||||
exthead->binarysize = machosize;
|
exthead->binarysize = machosize;
|
||||||
if (grub_xnu_is_64bit)
|
if (grub_xnu_is_64bit)
|
||||||
err = grub_macho_readfile64 (macho, buf);
|
err = grub_macho_readfile64 (macho, buf);
|
||||||
|
@ -712,8 +708,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
|
||||||
/* Load the plist. */
|
/* Load the plist. */
|
||||||
if (infoplist)
|
if (infoplist)
|
||||||
{
|
{
|
||||||
exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
|
exthead->infoplistaddr = buf_target + (buf - buf0);
|
||||||
+ grub_xnu_heap_will_be_at;
|
|
||||||
exthead->infoplistsize = infoplistsize + 1;
|
exthead->infoplistsize = infoplistsize + 1;
|
||||||
if (grub_file_read (infoplist, buf, infoplistsize)
|
if (grub_file_read (infoplist, buf, infoplistsize)
|
||||||
!= (grub_ssize_t) (infoplistsize))
|
!= (grub_ssize_t) (infoplistsize))
|
||||||
|
@ -729,15 +724,14 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
|
||||||
}
|
}
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
|
||||||
exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
|
exthead->nameaddr = (buf - buf0) + buf_target;
|
||||||
+ grub_xnu_heap_will_be_at;
|
|
||||||
exthead->namesize = namelen + 1;
|
exthead->namesize = namelen + 1;
|
||||||
grub_memcpy (buf, name, namelen);
|
grub_memcpy (buf, name, namelen);
|
||||||
buf[namelen] = 0;
|
buf[namelen] = 0;
|
||||||
buf += namelen + 1;
|
buf += namelen + 1;
|
||||||
|
|
||||||
/* Announce to kernel */
|
/* Announce to kernel */
|
||||||
return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
|
return grub_xnu_register_memory ("Driver-", &driversnum, buf_target,
|
||||||
neededspace);
|
neededspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,6 +742,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
void *loadto;
|
void *loadto;
|
||||||
|
grub_addr_t loadto_target;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_off_t readoff = 0;
|
grub_off_t readoff = 0;
|
||||||
grub_ssize_t readlen = -1;
|
grub_ssize_t readlen = -1;
|
||||||
|
@ -836,11 +831,11 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadto = grub_xnu_heap_malloc (readlen);
|
err = grub_xnu_heap_malloc (readlen, &loadto, &loadto_target);
|
||||||
if (! loadto)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
return grub_errno;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the file. */
|
/* Read the file. */
|
||||||
|
@ -855,7 +850,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
/* Pass it to kernel. */
|
/* Pass it to kernel. */
|
||||||
return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
|
return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
|
||||||
loadto, readlen);
|
loadto_target, readlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -864,6 +859,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
void *loadto;
|
void *loadto;
|
||||||
|
grub_addr_t loadto_target;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_size_t size;
|
grub_size_t size;
|
||||||
|
|
||||||
|
@ -884,9 +880,9 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
size = grub_file_size (file);
|
size = grub_file_size (file);
|
||||||
|
|
||||||
loadto = grub_xnu_heap_malloc (size);
|
err = grub_xnu_heap_malloc (size, &loadto, &loadto_target);
|
||||||
if (! loadto)
|
if (err)
|
||||||
return grub_errno;
|
return err;
|
||||||
if (grub_file_read (file, loadto, size)
|
if (grub_file_read (file, loadto, size)
|
||||||
!= (grub_ssize_t) (size))
|
!= (grub_ssize_t) (size))
|
||||||
{
|
{
|
||||||
|
@ -894,7 +890,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_error_push ();
|
grub_error_push ();
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
|
return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
|
||||||
}
|
}
|
||||||
return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
|
return grub_xnu_register_memory ("RAMDisk", 0, loadto_target, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if the kext should be loaded according to plist
|
/* Returns true if the kext should be loaded according to plist
|
||||||
|
|
|
@ -45,10 +45,12 @@ grub_xnu_resume (char *imagename)
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
grub_size_t total_header_size;
|
grub_size_t total_header_size;
|
||||||
struct grub_xnu_hibernate_header hibhead;
|
struct grub_xnu_hibernate_header hibhead;
|
||||||
grub_uint8_t *buf;
|
void *code;
|
||||||
|
void *image;
|
||||||
grub_uint32_t codedest;
|
grub_uint32_t codedest;
|
||||||
grub_uint32_t codesize;
|
grub_uint32_t codesize;
|
||||||
|
grub_addr_t target_image;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
file = grub_file_open (imagename);
|
file = grub_file_open (imagename);
|
||||||
if (! file)
|
if (! file)
|
||||||
|
@ -94,18 +96,44 @@ grub_xnu_resume (char *imagename)
|
||||||
/* Try to allocate necessary space.
|
/* Try to allocate necessary space.
|
||||||
FIXME: mm isn't good enough yet to handle huge allocations.
|
FIXME: mm isn't good enough yet to handle huge allocations.
|
||||||
*/
|
*/
|
||||||
grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size
|
grub_xnu_relocator = grub_relocator_new ();
|
||||||
+ codesize
|
if (!grub_xnu_relocator)
|
||||||
+ GRUB_XNU_PAGESIZE);
|
|
||||||
if (! buf)
|
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, codedest,
|
||||||
|
codesize + GRUB_XNU_PAGESIZE);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
code = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
|
||||||
|
(0xffffffff - hibhead.image_size) + 1,
|
||||||
|
hibhead.image_size,
|
||||||
|
GRUB_XNU_PAGESIZE,
|
||||||
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
image = get_virtual_current_address (ch);
|
||||||
|
target_image = get_physical_target_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read code part. */
|
/* Read code part. */
|
||||||
if (grub_file_seek (file, total_header_size) == (grub_off_t) -1
|
if (grub_file_seek (file, total_header_size) == (grub_off_t) -1
|
||||||
|| grub_file_read (file, buf, codesize)
|
|| grub_file_read (file, code, codesize)
|
||||||
!= (grub_ssize_t) codesize)
|
!= (grub_ssize_t) codesize)
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
@ -114,8 +142,7 @@ grub_xnu_resume (char *imagename)
|
||||||
|
|
||||||
/* Read image. */
|
/* Read image. */
|
||||||
if (grub_file_seek (file, 0) == (grub_off_t) -1
|
if (grub_file_seek (file, 0) == (grub_off_t) -1
|
||||||
|| grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE,
|
|| grub_file_read (file, image, hibhead.image_size)
|
||||||
hibhead.image_size)
|
|
||||||
!= (grub_ssize_t) hibhead.image_size)
|
!= (grub_ssize_t) hibhead.image_size)
|
||||||
{
|
{
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
@ -124,12 +151,11 @@ grub_xnu_resume (char *imagename)
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
|
||||||
/* Setup variables needed by asm helper. */
|
/* Setup variables needed by asm helper. */
|
||||||
grub_xnu_heap_will_be_at = codedest;
|
grub_xnu_heap_target_start = codedest;
|
||||||
grub_xnu_heap_start = buf;
|
grub_xnu_heap_size = target_image + hibhead.image_size - codedest;
|
||||||
grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size;
|
|
||||||
grub_xnu_stack = (codedest + hibhead.stack);
|
grub_xnu_stack = (codedest + hibhead.stack);
|
||||||
grub_xnu_entry_point = (codedest + hibhead.entry_point);
|
grub_xnu_entry_point = (codedest + hibhead.entry_point);
|
||||||
grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE;
|
grub_xnu_arg1 = target_image;
|
||||||
|
|
||||||
grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point);
|
grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point);
|
||||||
grub_dprintf ("xnu", "image at 0x%x\n",
|
grub_dprintf ("xnu", "image at 0x%x\n",
|
||||||
|
|
|
@ -297,13 +297,10 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
|
||||||
{
|
{
|
||||||
grub_size_t msg_len = grub_strlen (msg);
|
grub_size_t msg_len = grub_strlen (msg);
|
||||||
|
|
||||||
*unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
|
*unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
|
||||||
|
|
||||||
if (!*unicode_msg)
|
if (!*unicode_msg)
|
||||||
{
|
return -1;
|
||||||
grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
|
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
|
||||||
(grub_uint8_t *) msg, -1, 0);
|
(grub_uint8_t *) msg, -1, 0);
|
||||||
|
@ -1215,6 +1212,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
||||||
struct grub_unicode_glyph *visual_ptr;
|
struct grub_unicode_glyph *visual_ptr;
|
||||||
*visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0])
|
*visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0])
|
||||||
* logical_len);
|
* logical_len);
|
||||||
|
if (!visual_ptr)
|
||||||
|
return -1;
|
||||||
for (ptr = logical; ptr <= logical + logical_len; ptr++)
|
for (ptr = logical; ptr <= logical + logical_len; ptr++)
|
||||||
{
|
{
|
||||||
if (ptr == logical + logical_len || *ptr == '\n')
|
if (ptr == logical + logical_len || *ptr == '\n')
|
||||||
|
|
|
@ -585,6 +585,7 @@ grub_cmdline_get (const char *prompt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\e':
|
case '\e':
|
||||||
|
grub_free (cl_terms);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case '\b':
|
case '\b':
|
||||||
|
@ -635,5 +636,6 @@ grub_cmdline_get (const char *prompt)
|
||||||
|
|
||||||
ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
|
ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
|
||||||
grub_free (buf);
|
grub_free (buf);
|
||||||
|
grub_free (cl_terms);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,10 +125,11 @@ set_colors (void)
|
||||||
|
|
||||||
/* Replace default `normal' colors with the ones specified by user (if any). */
|
/* Replace default `normal' colors with the ones specified by user (if any). */
|
||||||
char *
|
char *
|
||||||
grub_env_write_color_normal (struct grub_env_var *var, const char *val)
|
grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
|
||||||
|
const char *val)
|
||||||
{
|
{
|
||||||
if (grub_parse_color_name_pair (&color_normal, val))
|
if (grub_parse_color_name_pair (&color_normal, val))
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
set_colors ();
|
set_colors ();
|
||||||
|
|
||||||
|
@ -137,10 +138,11 @@ grub_env_write_color_normal (struct grub_env_var *var, const char *val)
|
||||||
|
|
||||||
/* Replace default `highlight' colors with the ones specified by user (if any). */
|
/* Replace default `highlight' colors with the ones specified by user (if any). */
|
||||||
char *
|
char *
|
||||||
grub_env_write_color_highlight (struct grub_env_var *var, const char *val)
|
grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
|
||||||
|
const char *val)
|
||||||
{
|
{
|
||||||
if (grub_parse_color_name_pair (&color_highlight, val))
|
if (grub_parse_color_name_pair (&color_highlight, val))
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
set_colors ();
|
set_colors ();
|
||||||
|
|
||||||
|
|
|
@ -499,7 +499,10 @@ grub_normal_do_completion (char *buf, int *restore,
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (argc != 0)
|
if (argc != 0)
|
||||||
grub_free (argv[0]);
|
{
|
||||||
|
grub_free (argv);
|
||||||
|
grub_free (argv[0]);
|
||||||
|
}
|
||||||
grub_free (match);
|
grub_free (match);
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,20 @@ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
|
||||||
void
|
void
|
||||||
grub_wait_after_message (void)
|
grub_wait_after_message (void)
|
||||||
{
|
{
|
||||||
|
grub_uint64_t endtime;
|
||||||
grub_xputs ("\n");
|
grub_xputs ("\n");
|
||||||
grub_printf_ (N_("Press any key to continue..."));
|
grub_printf_ (N_("Press any key to continue..."));
|
||||||
(void) grub_getkey ();
|
grub_refresh ();
|
||||||
|
|
||||||
|
endtime = grub_get_time_ms () + 10000;
|
||||||
|
|
||||||
|
while (grub_get_time_ms () < endtime)
|
||||||
|
if (grub_checkkey () >= 0)
|
||||||
|
{
|
||||||
|
grub_getkey ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
grub_xputs ("\n");
|
grub_xputs ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ static int grub_more;
|
||||||
|
|
||||||
static int grub_normal_char_counter = 0;
|
static int grub_normal_char_counter = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
putcode_real (grub_uint32_t code, struct grub_term_output *term);
|
||||||
|
|
||||||
int
|
int
|
||||||
grub_normal_get_char_counter (void)
|
grub_normal_get_char_counter (void)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +86,7 @@ print_more (void)
|
||||||
{
|
{
|
||||||
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
||||||
}
|
}
|
||||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
|
||||||
|
|
||||||
grub_free (unicode_str);
|
grub_free (unicode_str);
|
||||||
|
|
||||||
|
@ -94,6 +97,7 @@ print_more (void)
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
grub_print_spaces (term, 8);
|
grub_print_spaces (term, 8);
|
||||||
grub_term_restore_pos (pos);
|
grub_term_restore_pos (pos);
|
||||||
|
grub_free (pos);
|
||||||
|
|
||||||
/* Scroll one lines or an entire page, depending on the key. */
|
/* Scroll one lines or an entire page, depending on the key. */
|
||||||
|
|
||||||
|
@ -202,8 +206,39 @@ void
|
||||||
grub_puts_terminal (const char *str, struct grub_term_output *term)
|
grub_puts_terminal (const char *str, struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
grub_uint32_t *unicode_str, *unicode_last_position;
|
grub_uint32_t *unicode_str, *unicode_last_position;
|
||||||
|
grub_error_push ();
|
||||||
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
||||||
&unicode_last_position);
|
&unicode_last_position);
|
||||||
|
grub_error_pop ();
|
||||||
|
if (!unicode_str)
|
||||||
|
{
|
||||||
|
for (; *str; str++)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c =
|
||||||
|
{
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0,
|
||||||
|
.estimated_width = 1,
|
||||||
|
.base = *str
|
||||||
|
};
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
{
|
||||||
|
(term->putchar) (term, &c);
|
||||||
|
}
|
||||||
|
if (*str == '\n')
|
||||||
|
{
|
||||||
|
c.base = '\r';
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
{
|
||||||
|
(term->putchar) (term, &c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
||||||
grub_free (unicode_str);
|
grub_free (unicode_str);
|
||||||
|
@ -742,15 +777,43 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
||||||
void
|
void
|
||||||
grub_xputs_normal (const char *str)
|
grub_xputs_normal (const char *str)
|
||||||
{
|
{
|
||||||
grub_term_output_t term;
|
grub_uint32_t *unicode_str = NULL, *unicode_last_position;
|
||||||
grub_uint32_t *unicode_str, *unicode_last_position;
|
|
||||||
int backlog = 0;
|
int backlog = 0;
|
||||||
|
grub_term_output_t term;
|
||||||
|
|
||||||
|
grub_error_push ();
|
||||||
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
||||||
&unicode_last_position);
|
&unicode_last_position);
|
||||||
|
grub_error_pop ();
|
||||||
|
|
||||||
if (!unicode_str)
|
if (!unicode_str)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
for (; *str; str++)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c =
|
||||||
|
{
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0,
|
||||||
|
.estimated_width = 1,
|
||||||
|
.base = *str
|
||||||
|
};
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
{
|
||||||
|
(term->putchar) (term, &c);
|
||||||
|
}
|
||||||
|
if (*str == '\n')
|
||||||
|
{
|
||||||
|
c.base = '\r';
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
{
|
||||||
|
(term->putchar) (term, &c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,76 +119,86 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
|
||||||
lexer->recordpos += len;
|
lexer->recordpos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append '\n' to SRC, before '\0' */
|
|
||||||
static char *
|
|
||||||
append_newline (const char *src)
|
|
||||||
{
|
|
||||||
char *line;
|
|
||||||
grub_size_t len;
|
|
||||||
|
|
||||||
len = grub_strlen (src);
|
|
||||||
line = grub_malloc (len + 2);
|
|
||||||
if (!line)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
grub_strcpy (line, src);
|
|
||||||
|
|
||||||
line[len] = '\n';
|
|
||||||
line[len + 1] = '\0';
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read next line of input if necessary, and set yyscanner buffers. */
|
/* Read next line of input if necessary, and set yyscanner buffers. */
|
||||||
int
|
int
|
||||||
grub_script_lexer_yywrap (struct grub_parser_param *parserstate)
|
grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
|
||||||
|
const char *input)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *line;
|
char *p = 0;
|
||||||
char *line2;
|
char *line = 0;
|
||||||
YY_BUFFER_STATE buffer;
|
YY_BUFFER_STATE buffer;
|
||||||
struct grub_lexer_param *lexerstate = parserstate->lexerstate;
|
struct grub_lexer_param *lexerstate = parserstate->lexerstate;
|
||||||
|
|
||||||
if (!lexerstate->refs)
|
if (! lexerstate->refs && ! lexerstate->prefix && ! input)
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
if (!lexerstate->getline)
|
if (! lexerstate->getline && ! input)
|
||||||
{
|
{
|
||||||
grub_script_yyerror (parserstate, "unexpected end of file");
|
grub_script_yyerror (parserstate, "unexpected end of file");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = 0;
|
line = 0;
|
||||||
buffer = 0;
|
if (! input)
|
||||||
lexerstate->getline (&line, 1);
|
lexerstate->getline (&line, 1);
|
||||||
if (!line)
|
|
||||||
{
|
|
||||||
grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = grub_strlen (line);
|
|
||||||
if (line[len - 1] == '\n')
|
|
||||||
{
|
|
||||||
buffer = yy_scan_string (line, lexerstate->yyscanner);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
line = grub_strdup (input);
|
||||||
|
|
||||||
|
/* Ensure '\n' at the end. */
|
||||||
|
if (line && line[0] == '\0')
|
||||||
{
|
{
|
||||||
line2 = append_newline (line);
|
grub_free (line);
|
||||||
if (line2)
|
line = grub_strdup ("\n");
|
||||||
{
|
|
||||||
buffer = yy_scan_string (line2, lexerstate->yyscanner);
|
|
||||||
grub_free (line2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line && (len = grub_strlen(line)) && line[len - 1] != '\n')
|
||||||
|
{
|
||||||
|
p = grub_realloc (line, len + 2);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
p[len++] = '\n';
|
||||||
|
p[len] = '\0';
|
||||||
|
}
|
||||||
|
line = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! line)
|
||||||
|
{
|
||||||
|
grub_script_yyerror (parserstate, "out of memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepend any left over unput-text. */
|
||||||
|
if (lexerstate->prefix)
|
||||||
|
{
|
||||||
|
int plen = grub_strlen (lexerstate->prefix);
|
||||||
|
|
||||||
|
p = grub_malloc (len + plen + 1);
|
||||||
|
if (! p)
|
||||||
|
{
|
||||||
|
grub_free (line);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
grub_strcpy (p, lexerstate->prefix);
|
||||||
|
lexerstate->prefix = 0;
|
||||||
|
|
||||||
|
grub_strcpy (p + plen, line);
|
||||||
|
grub_free (line);
|
||||||
|
|
||||||
|
line = p;
|
||||||
|
len = len + plen;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = yy_scan_string (line, lexerstate->yyscanner);
|
||||||
grub_free (line);
|
grub_free (line);
|
||||||
if (!buffer)
|
|
||||||
|
if (! buffer)
|
||||||
{
|
{
|
||||||
grub_script_yyerror (parserstate, 0);
|
grub_script_yyerror (parserstate, 0);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grub_lexer_param *
|
struct grub_lexer_param *
|
||||||
|
@ -196,7 +206,6 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script,
|
||||||
grub_reader_getline_t getline)
|
grub_reader_getline_t getline)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *script2;
|
|
||||||
YY_BUFFER_STATE buffer;
|
YY_BUFFER_STATE buffer;
|
||||||
struct grub_lexer_param *lexerstate;
|
struct grub_lexer_param *lexerstate;
|
||||||
|
|
||||||
|
@ -220,34 +229,18 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = 0;
|
yyset_extra (parser, lexerstate->yyscanner);
|
||||||
script = script ? : "\n";
|
parser->lexerstate = lexerstate;
|
||||||
len = grub_strlen (script);
|
|
||||||
|
|
||||||
if (script[len - 1] == '\n')
|
if (grub_script_lexer_yywrap (parser, script ?: "\n"))
|
||||||
{
|
|
||||||
buffer = yy_scan_string (script, lexerstate->yyscanner);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
script2 = append_newline (script);
|
|
||||||
if (script2)
|
|
||||||
{
|
|
||||||
buffer = yy_scan_string (script2, lexerstate->yyscanner);
|
|
||||||
grub_free (script2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!buffer)
|
|
||||||
{
|
{
|
||||||
|
parser->lexerstate = 0;
|
||||||
yylex_destroy (lexerstate->yyscanner);
|
yylex_destroy (lexerstate->yyscanner);
|
||||||
grub_free (lexerstate->yyscanner);
|
grub_free (lexerstate->yyscanner);
|
||||||
|
|
||||||
grub_free (lexerstate->text);
|
grub_free (lexerstate->text);
|
||||||
grub_free (lexerstate);
|
grub_free (lexerstate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
yyset_extra (parser, lexerstate->yyscanner);
|
|
||||||
|
|
||||||
return lexerstate;
|
return lexerstate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,7 +377,10 @@ grub_script_parse (char *script, grub_reader_getline_t getline)
|
||||||
|
|
||||||
parsestate = grub_zalloc (sizeof (*parsestate));
|
parsestate = grub_zalloc (sizeof (*parsestate));
|
||||||
if (!parsestate)
|
if (!parsestate)
|
||||||
return 0;
|
{
|
||||||
|
grub_free (parsed);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the lexer. */
|
/* Initialize the lexer. */
|
||||||
lexstate = grub_script_lexer_init (parsestate, script, getline);
|
lexstate = grub_script_lexer_init (parsestate, script, getline);
|
||||||
|
@ -400,6 +403,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline)
|
||||||
grub_script_mem_free (memfree);
|
grub_script_mem_free (memfree);
|
||||||
grub_script_lexer_fini (lexstate);
|
grub_script_lexer_fini (lexstate);
|
||||||
grub_free (parsestate);
|
grub_free (parsestate);
|
||||||
|
grub_free (parsed);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue