Merge Mainline.
This commit is contained in:
commit
85fd555441
191 changed files with 9311 additions and 1208 deletions
27
.bzrignore
27
.bzrignore
|
@ -26,12 +26,16 @@ docs/*.info
|
||||||
docs/stamp-vti
|
docs/stamp-vti
|
||||||
docs/version.texi
|
docs/version.texi
|
||||||
*.elf
|
*.elf
|
||||||
|
example_grub_script_test
|
||||||
|
example_scripted_test
|
||||||
|
example_unit_test
|
||||||
*.exec
|
*.exec
|
||||||
genkernsyms.sh
|
genkernsyms.sh
|
||||||
gensymlist.sh
|
gensymlist.sh
|
||||||
gentrigtables
|
gentrigtables
|
||||||
grub-bin2h
|
grub-bin2h
|
||||||
grub-dumpbios
|
grub_cmd_echo
|
||||||
|
grub_cmd_regexp
|
||||||
grub-editenv
|
grub-editenv
|
||||||
grub-emu
|
grub-emu
|
||||||
grub_emu_init.c
|
grub_emu_init.c
|
||||||
|
@ -49,9 +53,28 @@ grub-probe
|
||||||
grub_probe_init.c
|
grub_probe_init.c
|
||||||
grub_probe_init.h
|
grub_probe_init.h
|
||||||
grub-reboot
|
grub-reboot
|
||||||
|
grub_script_blanklines
|
||||||
|
grub_script_blockarg
|
||||||
|
grub_script_break
|
||||||
grub-script-check
|
grub-script-check
|
||||||
grub_script_check_init.c
|
grub_script_check_init.c
|
||||||
grub_script_check_init.h
|
grub_script_check_init.h
|
||||||
|
grub_script_comments
|
||||||
|
grub_script_continue
|
||||||
|
grub_script_dollar
|
||||||
|
grub_script_echo1
|
||||||
|
grub_script_echo_keywords
|
||||||
|
grub_script_expansion
|
||||||
|
grub_script_final_semicolon
|
||||||
|
grub_script_for1
|
||||||
|
grub_script_functions
|
||||||
|
grub_script_if
|
||||||
|
grub_script_not
|
||||||
|
grub_script_return
|
||||||
|
grub_script_setparams
|
||||||
|
grub_script_shift
|
||||||
|
grub_script_vars1
|
||||||
|
grub_script_while1
|
||||||
grub_script.tab.c
|
grub_script.tab.c
|
||||||
grub_script.tab.h
|
grub_script.tab.h
|
||||||
grub_script.yy.c
|
grub_script.yy.c
|
||||||
|
@ -75,6 +98,7 @@ Makefile
|
||||||
*.mod
|
*.mod
|
||||||
mod-*.c
|
mod-*.c
|
||||||
missing
|
missing
|
||||||
|
partmap_test
|
||||||
*.pf2
|
*.pf2
|
||||||
*.pp
|
*.pp
|
||||||
po/*.mo
|
po/*.mo
|
||||||
|
@ -109,6 +133,7 @@ grub-core/Makefile.gcry.def
|
||||||
grub-core/contrib
|
grub-core/contrib
|
||||||
grub-core/genmod.sh
|
grub-core/genmod.sh
|
||||||
grub-core/gensyminfo.sh
|
grub-core/gensyminfo.sh
|
||||||
|
grub-core/modinfo.sh
|
||||||
grub-core/*.module
|
grub-core/*.module
|
||||||
grub-core/*.pp
|
grub-core/*.pp
|
||||||
util/bash-completion.d/grub
|
util/bash-completion.d/grub
|
||||||
|
|
946
ChangeLog
946
ChangeLog
|
@ -1,3 +1,947 @@
|
||||||
|
2011-05-21 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/disk/arc/arcdisk.c (reopen): Close old handle before
|
||||||
|
opening new one.
|
||||||
|
|
||||||
|
2011-05-21 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
2011-05-21 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Don't stat devices unless we have to.
|
||||||
|
|
||||||
|
* grub-core/kern/emu/getroot.c (grub_find_device): Recognize
|
||||||
|
dir == /dev/mapper.
|
||||||
|
(grub_guess_root_device): Use already known os_dev if possible.
|
||||||
|
* grub-core/kern/emu/hostdisk.c
|
||||||
|
(convert_system_partition_to_system_disk): Scan only in /dev/mapper
|
||||||
|
if device is known to be a dm one.
|
||||||
|
|
||||||
|
2011-05-20 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub-mkconfig.in: Export GRUB_CMDLINE_LINUX_XEN_REPLACE and
|
||||||
|
GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT.
|
||||||
|
Reported by: Pawel Tecza.
|
||||||
|
|
||||||
|
2011-05-19 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/Makefile.core.def (lsacpi): Fix ia64 mismerge.
|
||||||
|
(lsefisystab): Likewise.
|
||||||
|
(lssal): Likewise.
|
||||||
|
(lsefimmap): Likewise.
|
||||||
|
(hdparm): Enable on qemu-mips.
|
||||||
|
(setjmp): Add ia64 nodist.
|
||||||
|
(serial): Simplify tags.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* Makefile.util.def (grub-ofpathname): Install manual page.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* grub-core/fs/squash4.c: Add missing GRUB_MOD_LICENSE.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* .bzrignore: Add grub-core/modinfo.sh and a number of test files.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Downgrade a printf
|
||||||
|
into dprintf.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Use full 64-bit division.
|
||||||
|
|
||||||
|
* grub-core/kern/misc.c (grub_divmod64_full): Renamed to ...
|
||||||
|
(grub_divmod64): ... this.
|
||||||
|
* include/grub/misc.h (grub_divmod64): Removed. All users switch to full
|
||||||
|
version.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub-mkrescue.in: Use portable `.' rather than non-portable
|
||||||
|
`source'.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* grub-core/genmod.sh.in: Use 'set -e' rather than '#! /bin/sh -e',
|
||||||
|
to avoid accidents when debugging with 'sh -x'.
|
||||||
|
* grub-core/gensyminfo.sh.in: Likewise.
|
||||||
|
* tests/example_scripted_test.in: Likewise.
|
||||||
|
* tests/grub_cmd_regexp.in: Likewise.
|
||||||
|
* tests/grub_script_blanklines.in: Likewise.
|
||||||
|
* tests/grub_script_dollar.in: Likewise.
|
||||||
|
* tests/grub_script_expansion.in: Likewise.
|
||||||
|
* tests/grub_script_final_semicolon.in: Likewise.
|
||||||
|
* tests/partmap_test.in: Likewise.
|
||||||
|
* tests/util/grub-shell-tester.in: Likewise.
|
||||||
|
* tests/util/grub-shell.in: Likewise.
|
||||||
|
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
Move gfxmenu color handling to video, so that gfxterm can use it
|
||||||
|
too.
|
||||||
|
|
||||||
|
* grub-core/gfxmenu/named_colors.c: Move to ...
|
||||||
|
* grub-core/video/colors.c: ... here. Rename
|
||||||
|
grub_gui_get_named_color to grub_video_get_named_color.
|
||||||
|
* grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ...
|
||||||
|
* grub-core/video/colors.c (my_isxdigit): ... here.
|
||||||
|
* grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component):
|
||||||
|
Move to ...
|
||||||
|
* grub-core/video/colors.c (parse_hex_color_component): ... here.
|
||||||
|
* grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move
|
||||||
|
to ...
|
||||||
|
* grub-core/video/colors.c (grub_video_parse_color): ... here.
|
||||||
|
|
||||||
|
* include/grub/gui.h (grub_gui_color_t): Move to ...
|
||||||
|
* include/grub/video.h (grub_video_rgba_color_t): ... here.
|
||||||
|
* include/grub/gui.h (grub_gui_color_rgb): Move to ...
|
||||||
|
* include/grub/video.h (grub_video_rgba_color_rgb): ... here.
|
||||||
|
* include/grub/gui.h (grub_gui_map_color): Move to ...
|
||||||
|
* include/grub/video.h (grub_video_map_rgba_color): ... here.
|
||||||
|
* include/grub/gui_string_util.h (grub_gui_get_named_color): Move
|
||||||
|
to ...
|
||||||
|
* include/grub/video.h (grub_video_get_named_color): ... here.
|
||||||
|
* include/grub/gui_string_util.h (grub_gui_parse_color): Move to ...
|
||||||
|
* include/grub/video.h (grub_video_parse_color): ... here.
|
||||||
|
|
||||||
|
* grub-core/Makefile.core.def (kernel) [videoinkernel]: Add
|
||||||
|
video/colors.c.
|
||||||
|
(gfxmenu): Remove gfxmenu/named_colors.c.
|
||||||
|
(video) [videomodules]: Add video/colors.c.
|
||||||
|
|
||||||
|
Add a background_color command.
|
||||||
|
|
||||||
|
* grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New
|
||||||
|
function.
|
||||||
|
(GRUB_MOD_INIT): Register background_color command.
|
||||||
|
(GRUB_MOD_FINI): Unregister background_color command.
|
||||||
|
(redraw_screen_rect): Allow blend/replace of text layer to be
|
||||||
|
controlled independently from whether there is a background bitmap.
|
||||||
|
(grub_gfxterm_background_image_cmd): Change blend_text_bg when
|
||||||
|
changing bitmap.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Patch BPB in ntldr and chainloader --bpb.
|
||||||
|
|
||||||
|
* grub-core/fs/fat.c: Include grub/fat.h.
|
||||||
|
(grub_fat_bpb): Moved to ...
|
||||||
|
* include/grub/fat.h (grub_fat_bpb): ... here. New file.
|
||||||
|
* grub-core/loader/i386/pc/chainloader.c: Include grub/fat.h and
|
||||||
|
grub/ntfs.h.
|
||||||
|
* include/grub/i386/pc/chainloader.h (grub_chainloader_flags_t):
|
||||||
|
Moved from here...
|
||||||
|
* grub-core/loader/i386/pc/chainloader.c (grub_chainloader_flags_t): ...
|
||||||
|
here.
|
||||||
|
* grub-core/loader/i386/pc/chainloader.c (grub_chainloader_patch_bpb):
|
||||||
|
New function.
|
||||||
|
(grub_chainloader_cmd): Patch BPB if --bpb is given.
|
||||||
|
(GRUB_MOD_INIT): Show --bpb.
|
||||||
|
* grub-core/loader/i386/pc/ntldr.c (grub_cmd_ntldr): Patch BPB.
|
||||||
|
* grub-core/normal/main.c (features): New variable.
|
||||||
|
(GRUB_MOD_INIT): Set feature_* variables.
|
||||||
|
* include/grub/i386/pc/chainloader.h (grub_chainloader_patch_bpb): New
|
||||||
|
proto.
|
||||||
|
* include/grub/ntfs.h (grub_ntfs_bpb): New field bios_drive.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/Makefile.core.def (ieee1275_fb): Use enable=powerpc_ieee1275
|
||||||
|
for cleanness.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
FreeDOS direct loading support.
|
||||||
|
|
||||||
|
* docs/grub.texi (Supported OS): Add FreeDOS.
|
||||||
|
* grub-core/Makefile.core.def (freedos): New module.
|
||||||
|
* grub-core/lib/i386/relocator.c (grub_relocator16_ebx): New extern
|
||||||
|
variable.
|
||||||
|
(grub_relocator16_boot): Handle %ebx.
|
||||||
|
* grub-core/lib/i386/relocator16.S: Likewise.
|
||||||
|
* grub-core/loader/i386/pc/freedos.c: New file.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Long Linux command line support.
|
||||||
|
|
||||||
|
* grub-core/loader/i386/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed.
|
||||||
|
(maximal_cmdline_size): New variable.
|
||||||
|
(allocate_pages): Use maximal_cmdline_size.
|
||||||
|
(grub_cmd_linux): Set and use maximal_cmdline_size.
|
||||||
|
* grub-core/loader/i386/pc/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed.
|
||||||
|
(allocate_pages): Use maximal_cmdline_size.
|
||||||
|
(grub_cmd_linux): Set and use maximal_cmdline_size.
|
||||||
|
* include/grub/i386/linux.h (GRUB_LINUX_SETUP_MOVE_SIZE): Removed.
|
||||||
|
(linux_kernel_header): Add fields kernel_alignment, relocatable, pad
|
||||||
|
and cmdline_size.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
2011-05-18 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
Improve devmapper support
|
||||||
|
|
||||||
|
* grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Removed.
|
||||||
|
(grub_util_is_lvm): New function.
|
||||||
|
(grub_util_get_dev_abstraction): Assume dmraid if not lvm rather
|
||||||
|
than lvm if not dmraid.
|
||||||
|
Handle mapped md nodes.
|
||||||
|
* grub-core/kern/emu/hostdisk.c (device_is_mapped): Rename to ...
|
||||||
|
(grub_util_device_is_mapped): ... this. Make always available. All users
|
||||||
|
updated.
|
||||||
|
(grub_util_get_dm_node_linear_info) [HAVE_DEVICE_MAPPER]: New function.
|
||||||
|
(convert_system_partition_to_system_disk): Handle lvm, mpath and
|
||||||
|
dmraid nodes.
|
||||||
|
* include/grub/emu/misc.h (grub_util_device_is_mapped): New proto.
|
||||||
|
|
||||||
|
2011-05-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Unify grub-mkrescue (except powerpc) and grrub-mknetdir across platforms
|
||||||
|
|
||||||
|
* grub-core/Makefile.am (platform_DATA): Add modinfo.sh.
|
||||||
|
* grub-core/modinfo.sh.in: New file.
|
||||||
|
* grub-core/Makefile.core.def (modinfo.sh): New script.
|
||||||
|
* util/grub-mknetdir.in: Use modinfo.sh.
|
||||||
|
* util/grub-mkrescue.in: Likewise.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size):
|
||||||
|
Fix potential usage of Elf32 instead of Elf64 when compiling on
|
||||||
|
32-bit architecture. Add endianness macros while on it.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Use mipsel- rather than mips- in directories involving mipsel ports to
|
||||||
|
allow both endiannesses coexist.
|
||||||
|
|
||||||
|
* configure.ac: proparate target_cpu=mipsel rather than resetting to
|
||||||
|
mips. All conditions adjusted.
|
||||||
|
* tests/util/grub-shell-tester.in: Remove gratuitious target_cpu
|
||||||
|
variable.
|
||||||
|
* util/grub-install.in: Adjust conditions to take renaming into account.
|
||||||
|
* util/grub-mkimage.c (image_targets): Likewise. New target
|
||||||
|
mips-qemu_mips-elf for bigendian mips.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Avoid unnecessary copying on MIPS.
|
||||||
|
|
||||||
|
* grub-core/boot/decompressor/none.c (grub_decompress_core): Exit
|
||||||
|
early if src == dest.
|
||||||
|
* util/grub-mkimage.c (generate_image): Arange for src == dest if
|
||||||
|
compression is none.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Reduce memory footprint on SGI by putting modules before the kernel
|
||||||
|
as opposed to after.
|
||||||
|
|
||||||
|
* grub-core/Makefile.core.def (kernel): Increase linking address.
|
||||||
|
(none_decompress): Likewise.
|
||||||
|
(xz_decompress): Likewise.
|
||||||
|
* grub-core/boot/mips/startup_raw.S: Use prewritten uncompression
|
||||||
|
address.
|
||||||
|
* grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory
|
||||||
|
layout change.
|
||||||
|
(grub_arch_modules_addr): New function.
|
||||||
|
* grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here...
|
||||||
|
* grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here
|
||||||
|
* grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and
|
||||||
|
here.
|
||||||
|
* grub-core/kern/mips/startup.S (total_size): Rename to ...
|
||||||
|
(grub_total_modules_size): ... this. Make global.
|
||||||
|
[GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss.
|
||||||
|
* include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR):
|
||||||
|
New definition.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise.
|
||||||
|
(GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased.
|
||||||
|
* util/grub-mkimage.c (image_target_desc): New flag
|
||||||
|
PLATFORM_FLAGS_MODULES_BEFORE_KERNEL.
|
||||||
|
(image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc.
|
||||||
|
(generate_image): Handle images with modules before kernel.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Prevent potential loss of memory map by overwrite on qemu-mips.
|
||||||
|
|
||||||
|
* grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]:
|
||||||
|
Save ram size in $s4.
|
||||||
|
* grub-core/kern/mips/qemu_mips/init.c (RAMSIZE): Removed.
|
||||||
|
All users changed to grub_arch_memsize.
|
||||||
|
* grub-core/kern/mips/startup.S (grub_arch_machine): Restrict to
|
||||||
|
Loongson.
|
||||||
|
[GRUB_MACHINE_MIPS_QEMU_MIPS]: Save grub_arch_memsize.
|
||||||
|
* grub-core/loader/mips/linux.c (grub_linux_boot): Pass memory size.
|
||||||
|
* include/grub/mips/qemu_mips/memory.h (grub_arch_memsize): New
|
||||||
|
external variable.
|
||||||
|
|
||||||
|
2011-05-17 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* .bzrignore: Remove grub-dumpbios.
|
||||||
|
|
||||||
|
2011-05-17 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub.d/20_linux_xen.in: Honour GRUB_CMDLINE_LINUX_XEN_REPLACE
|
||||||
|
and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace
|
||||||
|
GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the
|
||||||
|
existing options which append).
|
||||||
|
* docs/grub.texi (Simple configuration): Document new options.
|
||||||
|
Reported by: Ian Jackson. Fixes Debian bug #617538.
|
||||||
|
|
||||||
|
2011-05-17 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub-fstest.c (cmd_cat): New function.
|
||||||
|
(fstest): Handle CMD_CAT.
|
||||||
|
(options): Add cat.
|
||||||
|
(argp_parser): Handle cat.
|
||||||
|
|
||||||
|
2011-05-17 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* Makefile.util.def (grub-bin2h): Don't install.
|
||||||
|
* docs/man/grub-bin2h.h2m: Remove.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/mips/startup.S (grub_arch_cpuclock): Move to the right
|
||||||
|
place.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Reenable qemu-mips port.
|
||||||
|
|
||||||
|
* configure.ac: Handle --target=qemu-mips and --target=qemu_mips.
|
||||||
|
Fix small arc bug while on it.
|
||||||
|
* gentpl.py: Handle qemu_mips.
|
||||||
|
* grub-core/Makefile.am: Likewise.
|
||||||
|
* grub-core/Makefile.core.def: Likewise.
|
||||||
|
* grub-core/disk/ata.c [GRUB_MACHINE_MIPS_QEMU_MIPS]: Remove
|
||||||
|
inappropriate includes.
|
||||||
|
(grub_ata_pciinit) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Removed.
|
||||||
|
(grub_ata_initialize): [GRUB_MACHINE_MIPS_QEMU_MIPS]: Rewritten.
|
||||||
|
* grub-core/kern/main.c (grub_modules_get_end)
|
||||||
|
[GRUB_MACHINE_MIPS_QEMU_MIPS]: Enable.
|
||||||
|
* grub-core/kern/mips/qemu-mips: Moved to ..
|
||||||
|
* grub-core/kern/mips/qemu_mips: ... this.
|
||||||
|
* grub-core/kern/mips/qemu_mips/init.c (grub_get_rtc): Removed.
|
||||||
|
(grub_machine_init): Call terminfo_init and serial_init.
|
||||||
|
* grub-core/kern/mips/startup.S: Change MIPS_LOONGSON to MACHINE.
|
||||||
|
* grub-core/loader/mips/linux.c (params) [GRUB_MACHINE_MIPS_QEMU_MIPS]:
|
||||||
|
New variable.
|
||||||
|
(grub_linux_boot) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Handle the qemu-mips
|
||||||
|
parameter passing.
|
||||||
|
(grub_linux_unload) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Free params.
|
||||||
|
(grub_cmd_linux) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Handle params.
|
||||||
|
(grub_cmd_initrd) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Likewise.
|
||||||
|
* include/grub/mips/qemu_mips/cmos.h: New file.
|
||||||
|
* include/grub/mips/qemu-mips/kernel.h: Don't include cpu/kernel.h.
|
||||||
|
* include/grub/mips/qemu-mips/memory.h (grub_machine_mmap_iterate):
|
||||||
|
Removed.
|
||||||
|
* include/grub/mips/qemu-mips/serial.h (GRUB_MACHINE_SERIAL_PORTS):
|
||||||
|
Use correct mips-style address.
|
||||||
|
* include/grub/mips/qemu-mips/time.h: Include cpu/time.h.
|
||||||
|
(GRUB_TICKS_PER_SECOND): Removed.
|
||||||
|
(grub_get_rtc): Likewise.
|
||||||
|
(grub_cpu_idle): Likewise.
|
||||||
|
* include/grub/offsets.h (GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR):
|
||||||
|
New definition.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN): Likewise.
|
||||||
|
* util/grub-mkimage.c (image_targets): Add mipsel-qemu_mips-elf.
|
||||||
|
|
||||||
|
2011-05-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
SGI ARCS port.
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrubmods.a): Add dvh.c.
|
||||||
|
* conf/Makefile.common (CCASFLAGS_PLATFORM): Add -mips3 on all mips
|
||||||
|
platforms.
|
||||||
|
* configure.ac: New target mips-arc.
|
||||||
|
* gentpl.py: Likewise.
|
||||||
|
* grub-core/Makefile.am: Likewise.
|
||||||
|
* grub-core/Makefile.core.def: Likewise.
|
||||||
|
(xz_decompress): Remove -D GRUB_MACHINE_LINK_ADDR.
|
||||||
|
(none_decompress): Likewise.
|
||||||
|
(lsdev): New module.
|
||||||
|
(datetime): Use lib/arc/datetime.c on ARC.
|
||||||
|
(part_dvh): New module.
|
||||||
|
* grub-core/commands/arc/lsdev.c: New file.
|
||||||
|
* grub-core/disk/arc/arcdisk.c: Likewise.
|
||||||
|
* grub-core/kern/mips/arc/init.c: Likewise.
|
||||||
|
* grub-core/kern/mips/cache_flush.S: Don't flush non 4-byte
|
||||||
|
aligned addresses.
|
||||||
|
* grub-core/kern/mips/dl.c (grub_arch_dl_check_header): Fix bigendian
|
||||||
|
support.
|
||||||
|
(grub_arch_dl_relocate_symbols): Likewise.
|
||||||
|
* grub-core/kern/mips/loongson/init.c (grub_get_rtc): Moved from here...
|
||||||
|
* grub-core/kern/mips/init.c (grub_get_rtc): ... here.
|
||||||
|
* grub-core/kern/mips/startup.S (grub_arch_cpuclock): Have on all
|
||||||
|
platforms.
|
||||||
|
* grub-core/lib/arc/datetime.c: New file.
|
||||||
|
* grub-core/loader/mips/linux.c: Always include time.h. Don't include
|
||||||
|
pci.h on non-loongson.
|
||||||
|
(envp_off) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove.
|
||||||
|
(grub_linux_boot): Set unused registers to 0.
|
||||||
|
(grub_cmd_linux) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove envp.
|
||||||
|
* grub-core/mmap/mips/loongson/uppermem.c: Moved from here ...
|
||||||
|
* grub-core/mmap/mips/uppermem.c: ...here.
|
||||||
|
* grub-core/partmap/dvh.c: New file.
|
||||||
|
* grub-core/term/arc/console.c: Likewise.
|
||||||
|
* grub-core/term/terminfo.c (ANSI_C0_STR): New const.
|
||||||
|
(grub_terminfo_set_current): Add terminal "arc".
|
||||||
|
(grub_terminfo_readkey): Support ARC sequences.
|
||||||
|
* include/grub/arc/arc.h: New file.
|
||||||
|
* include/grub/arc/console.h: Likewise.
|
||||||
|
* include/grub/disk.h (grub_disk_dev_id): Add
|
||||||
|
GRUB_DISK_DEVICE_ARCDISK_ID.
|
||||||
|
* include/grub/mips/arc/kernel.h: New file.
|
||||||
|
* include/grub/mips/arc/memory.h: Likewise.
|
||||||
|
* include/grub/mips/arc/time.h: Likewise.
|
||||||
|
* include/grub/mips/loongson/kernel.h (grub_halt): Moved from here ...
|
||||||
|
* include/grub/mips/kernel.h (grub_halt): ... here.
|
||||||
|
* include/grub/mips/loongson.h (GRUB_CPU_REGISTER_WRAP): Moved from
|
||||||
|
here...
|
||||||
|
* include/grub/mips/mips.h (GRUB_CPU_REGISTER_WRAP): ... here.
|
||||||
|
(GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): Moved from here ...
|
||||||
|
* include/grub/mips/mips.h (GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): .. here
|
||||||
|
* include/grub/mips/loongson/kernel.h (grub_reboot): Removed redundant
|
||||||
|
proto.
|
||||||
|
* include/grub/mips/loongson/memory.h (GRUB_ARCH_LOWMEMVSTART): Moved
|
||||||
|
from here ...
|
||||||
|
* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMVSTART): ... here.
|
||||||
|
(GRUB_ARCH_LOWMEMPSTART): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMPSTART): ... here.
|
||||||
|
(GRUB_ARCH_LOWMEMMAXSIZE): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMMAXSIZE): ... here.
|
||||||
|
(GRUB_ARCH_HIGHMEMPSTART): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (GRUB_ARCH_HIGHMEMPSTART): ... here.
|
||||||
|
(grub_phys_addr_t): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_phys_addr_t): ... here.
|
||||||
|
(grub_vtop): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_vtop): ... here.
|
||||||
|
(grub_map_memory): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_map_memory): ... here.
|
||||||
|
(grub_unmap_memory): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_unmap_memory): ... here.
|
||||||
|
(grub_machine_mmap_iterate): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_machine_mmap_iterate): ... here.
|
||||||
|
(grub_mmap_get_lower): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_mmap_get_lower): ... here.
|
||||||
|
(grub_mmap_get_upper): Moved from here ...
|
||||||
|
* include/grub/mips/memory.h (grub_mmap_get_upper): ... here.
|
||||||
|
* include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from
|
||||||
|
here ...
|
||||||
|
* include/grub/mips/time.h (grub_arch_cpuclock): ... here.
|
||||||
|
* include/grub/mips/loongson/time.h (grub_get_rtc): Moved from
|
||||||
|
here ...
|
||||||
|
* include/grub/mips/time.h (grub_get_rtc): ... here.
|
||||||
|
* include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from
|
||||||
|
here ...
|
||||||
|
* include/grub/mips/time.h (grub_arch_cpuclock): ... here.
|
||||||
|
* include/grub/mips/loongson/time.h (grub_cpu_idle): Moved from
|
||||||
|
here ...
|
||||||
|
* include/grub/mips/time.h (grub_cpu_idle): ... here.
|
||||||
|
* include/grub/offsets.h (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): New
|
||||||
|
definition.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_LINK_ALIGN): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise.
|
||||||
|
(GRUB_KERNEL_MIPS_ARC_MOD_ALIGN): Likewise.
|
||||||
|
(GRUB_MACHINE_LINK_ADDR): Likewise.
|
||||||
|
* include/grub/terminfo.h (GRUB_TERMINFO_READKEY_MAX_LEN): Increased
|
||||||
|
to 6.
|
||||||
|
* util/grub-install.in: Run dvhtool on ARC.
|
||||||
|
* util/grub-mkimage.c (image_targets): Add mips-arc.
|
||||||
|
(generate_image): Handle ECOFF output for mips-arc.
|
||||||
|
|
||||||
|
2011-05-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/bus/pci.c (grub_memalign_dma32): Always allocate in 64-byte
|
||||||
|
blocks.
|
||||||
|
|
||||||
|
2011-05-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/bus/usb/usbhub.c (attach_root_port): Wait 10ms
|
||||||
|
after enabling port.
|
||||||
|
|
||||||
|
2011-05-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Skip incorrect USB devices.
|
||||||
|
|
||||||
|
* grub-core/bus/usb/usb.c (grub_usb_device_initialize): Fail if
|
||||||
|
configcnt == 0.
|
||||||
|
* include/grub/usb.h (grub_usb_err_t): New enum value
|
||||||
|
GRUB_USB_ERR_BADDEVICE.
|
||||||
|
|
||||||
|
2011-05-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fuloong video init support.
|
||||||
|
|
||||||
|
* include/grub/vga.h (grub_vga_write_arx): inb monochrome address as
|
||||||
|
well.
|
||||||
|
(grub_vga_read_arx): New function.
|
||||||
|
* grub-core/video/sis315pro.c (GRUB_SIS315PRO_MMIO_SPACE): New
|
||||||
|
definition.
|
||||||
|
(framebuffer): New members io, mmioptr and mmiobase.
|
||||||
|
(read_sis_cmd): New function.
|
||||||
|
(write_sis_cmd): Likewise.
|
||||||
|
(grub_video_sis315pro_setup): Do the initialisation. Use 640x480
|
||||||
|
rather than 640x400.
|
||||||
|
* grub-core/video/sis315_init.c: New file.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/bus/cs5536.c: Don't include grub/machine/kernel.h on
|
||||||
|
non-loongson.
|
||||||
|
* grub-core/kern/mips/dl.c (grub_arch_dl_init_linker): Fix argument
|
||||||
|
to grub_dl_register_symbol.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fix compilation errors.
|
||||||
|
|
||||||
|
* grub-core/term/ns8250.c (serial_get_divisor): Declare 'port' as
|
||||||
|
potentially unused.
|
||||||
|
* grub-core/loader/i386/linux.c (grub_linux_setup_video):
|
||||||
|
Handle GRUB_VIDEO_DRIVER_SIS315PRO.
|
||||||
|
* grub-core/bus/cs5536.c (grub_cs5536_init_geode): Restrict DIVIL init
|
||||||
|
to loongson machines.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Several FS mtime support.
|
||||||
|
|
||||||
|
* grub-core/fs/affs.c (grub_affs_time): New struct.
|
||||||
|
(grub_affs_file): New field mtime.
|
||||||
|
(grub_fshelp_node): Changed 'block' and 'parent' to more appropriate
|
||||||
|
type. Removed 'size'. New field 'di'. All users updated.
|
||||||
|
(grub_affs_mount): Simplify checsum checking.
|
||||||
|
(grub_affs_iterate_dir): New helper grub_affs_create_node.
|
||||||
|
(grub_affs_dir): Handle mtime.
|
||||||
|
* grub-core/fs/cpio.c (grub_cpio_find_file): Handle mtime.
|
||||||
|
(grub_cpio_dir): Likewise.
|
||||||
|
* grub-core/fs/hfs.c (grub_hfs_dirrec): New fields 'ctime' and 'mtime'.
|
||||||
|
(grub_hfs_filerec): New field mtime.
|
||||||
|
(grub_hfs_dir): Handle mtime.
|
||||||
|
(grub_hfs_mtime): New function.
|
||||||
|
(grub_hfs_fs): Register grub_hfs_mtime.
|
||||||
|
* grub-core/fs/iso9660.c (grub_iso9660_date2): New struct.
|
||||||
|
(grub_iso9660_dir): New field mtime.
|
||||||
|
(grub_fshelp_node): New field dirent.
|
||||||
|
(iso9660_to_unixtime): New function.
|
||||||
|
(iso9660_to_unixtime2): Likewise.
|
||||||
|
(grub_iso9660_read_symlink): Use node->dirent.
|
||||||
|
(grub_iso9660_iterate_dir): Likewise.
|
||||||
|
(grub_iso9660_dir): Set mtime.
|
||||||
|
(grub_iso9660_mtime): New function.
|
||||||
|
(grub_iso9660_fs): Register grub_iso9660_mtime.
|
||||||
|
* grub-core/fs/jfs.c (grub_jfs_time): New struct.
|
||||||
|
(grub_jfs_inode): New fields atime, ctime and mtime.
|
||||||
|
(grub_jfs_dir): Set mtime.
|
||||||
|
* grub-core/fs/minix.c (grub_minix_dir): Likewise.
|
||||||
|
* grub-core/fs/ntfs.c (list_file): Set mtime.
|
||||||
|
(grub_ntfs_dir): Likewise.
|
||||||
|
* grub-core/fs/reiserfs.c (grub_fshelp_node): New field 'mtime'.
|
||||||
|
(grub_reiserfs_iterate_dir): Set mtime.
|
||||||
|
(grub_reiserfs_dir): Likewise.
|
||||||
|
* grub-core/fs/sfs.c (grub_sfs_obj): New field mtime.
|
||||||
|
(grub_fshelp_node): Likewise.
|
||||||
|
(grub_sfs_iterate_dir): Set mtime.
|
||||||
|
(grub_sfs_dir): Likewise.
|
||||||
|
* grub-core/fs/udf.c (grub_udf_dir): Set mtime.
|
||||||
|
* grub-core/fs/xfs.c (grub_xfs_time): New struct.
|
||||||
|
(grub_xfs_inode): New fields atime, mtime, ctime.
|
||||||
|
(grub_xfs_dir): Set mtime.
|
||||||
|
* include/grub/datetime.h (grub_datetime2unixtime): New function.
|
||||||
|
* include/grub/hfs.h (grub_hfs_sblock): New fields ctime and mtime.
|
||||||
|
* include/grub/ntfs.h (grub_fshelp_node): New field mtime.
|
||||||
|
|
||||||
|
Support UDF symlinks.
|
||||||
|
|
||||||
|
* grub-core/fs/udf.c (grub_udf_iterate_dir): Handle symlinks.
|
||||||
|
(grub_ufs_read_symlink): New function. All users updated.
|
||||||
|
|
||||||
|
Check amiga partmap checksum.
|
||||||
|
|
||||||
|
* grub-core/partmap/amiga.c (grub_amiga_rdsk): Pad to 128 bytes.
|
||||||
|
(grub_amiga_partition): Likewise.
|
||||||
|
(amiga_partition_map_checksum): New function.
|
||||||
|
(amiga_partition_map_iterate): Check checksum.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
ROMFS support.
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrubmods.a): Add romfs.
|
||||||
|
* grub-core/Makefile.core.def (romfs): New module.
|
||||||
|
* grub-core/fs/romfs.c: New file.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Squashfs v4 support.
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrubmods.a): Add squash4.
|
||||||
|
* grub-core/Makefile.core.def (squash4): New module.
|
||||||
|
* grub-core/fs/squash4.c: New file.
|
||||||
|
* grub-core/io/gzio.c (grub_gzio): New members disk_input_off,
|
||||||
|
disk_input_start, disk_input.
|
||||||
|
(get_byte): Handle disk_input.
|
||||||
|
(grub_zlib_disk_read): New function.
|
||||||
|
* include/grub/deflate.h (grub_zlib_disk_read): New proto.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
2011-05-15 Feiran Zheng <famcool@gmail.com>
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrubmods.a): Add minix3.
|
||||||
|
* grub-core/Makefile.core.def (minix3): New module.
|
||||||
|
* grub-core/fs/minix.c (GRUB_MINIX_MAGIC) [MODE_MINIX3]: New value.
|
||||||
|
(GRUB_MINIX_BSIZE): Removed.
|
||||||
|
(GRUB_MINIX_INODE_DIR_BLOCKS): New definition. All users updated.
|
||||||
|
(grub_minix_ino_t): New type.
|
||||||
|
(grub_minix_le_to_cpu_ino): New macro.
|
||||||
|
(GRUB_MINIX_ZONE2SECT): New definition. All users updated.
|
||||||
|
(grub_minix_sblock) [MODE_MINIX3]: Change for minix3.
|
||||||
|
(grub_minix_data): New field block_size.
|
||||||
|
(grub_minix_read_file): Handle 64-bit correctly.
|
||||||
|
* grub-core/fs/minix3.c: New file.
|
||||||
|
|
||||||
|
2011-05-15 Tristan Gingold <gingold@free.fr>
|
||||||
|
2011-05-15 Robert Millan <rmh.grub@aybabtu.com>
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
IA64 support.
|
||||||
|
|
||||||
|
* Makefile.util.def (libgrubmods.a): Add grub-core/kern/ia64/dl_helper.c
|
||||||
|
* configure.ac: Add ia64-efi target.
|
||||||
|
Probe for __ia64_trampoline, __udivsi3, __umoddi3, __udivdi3,
|
||||||
|
__divsi3, __modsi3, __umodsi3, __moddi3 and __divdi3 symbols.
|
||||||
|
* gentpl.py: Add ia64_efi platform.
|
||||||
|
Rename x86_efi to efi and Add ia64-efi. All users updated.
|
||||||
|
* grub-core/Makefile.am: Set KERNEL_HEADER_FILES for ia64-efi.
|
||||||
|
* grub-core/Makefile.core.def (kernel.img): Add compile flags for ia64.
|
||||||
|
Remove kern/generic/rtc_get_time_ms.c on EFI.
|
||||||
|
Add kern/ia64/efi/startup.S, kern/ia64/efi/init.c, kern/ia64/dl.c,
|
||||||
|
kern/ia64/dl_helper.c on ia64-efi.
|
||||||
|
Add kern/emu/cache.c on emu.
|
||||||
|
(linux): Use on loader/ia64/efi/linux.c on ia64.
|
||||||
|
* grub-core/gensymlist.sh (grub_register_exported_symbols): Check
|
||||||
|
whether symbol is a function.
|
||||||
|
* grub-core/kern/dl.c [GRUB_MACHINE_EMU]: Include sys/mman.h.
|
||||||
|
(grub_symbol): New field 'isfunc'.
|
||||||
|
(grub_dl_resolve_symbol): Return whole symbol rather than just address.
|
||||||
|
(grub_dl_register_symbol): New argument 'isfunc'. All users updated.
|
||||||
|
(grub_dl_load_segments): Place all sections into the same region.
|
||||||
|
[__ia64__]: Create trampolines and got.
|
||||||
|
[GRUB_MACHINE_EMU]: Call mprotect.
|
||||||
|
(grub_dl_resolve_symbols): Resolve symbol type as well.
|
||||||
|
[__ia64__]: Create function descriptors.
|
||||||
|
* grub-core/kern/efi/efi.c (grub_get_rtc): Renamed to ...
|
||||||
|
(grub_rtc_get_time_ms): ... this. Expressions simplified.
|
||||||
|
(grub_get_rtc): New function.
|
||||||
|
* grub-core/kern/emu/cache.c [__ia64__]: New file.
|
||||||
|
* grub-core/kern/emu/cache.S: Renamed to ...
|
||||||
|
* grub-core/kern/emu/cache_s.S: ... this.
|
||||||
|
[__ia64__]: Add a nop.
|
||||||
|
* grub-core/kern/emu/full.c (grub_arch_dl_get_tramp_got_size)
|
||||||
|
[__ia64__]: New function.
|
||||||
|
* grub-core/kern/emu/lite.c [__ia64__]: Include ../ia64/dl.c.
|
||||||
|
* grub-core/kern/ia64/dl.c: New file.
|
||||||
|
* grub-core/kern/ia64/dl_helper.c: Likewise.
|
||||||
|
* grub-core/kern/ia64/efi/init.c: New file.
|
||||||
|
* grub-core/kern/ia64/efi/startup.S: Likewise.
|
||||||
|
* grub-core/lib/efi/halt.c [__ia64__]: Don't try acpi.
|
||||||
|
* grub-core/lib/ia64/longjmp.S: New file (from glibc).
|
||||||
|
* grub-core/lib/ia64/setjmp.S: Likewise (from glibc).
|
||||||
|
* grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/setjmp.S.
|
||||||
|
* grub-core/loader/ia64/efi/linux.c: New file.
|
||||||
|
* include/grub/dl.h (GRUB_MOD_NAME): Redefined using C rather than asm.
|
||||||
|
(GRUB_MOD_DEP): Likewise.
|
||||||
|
(grub_dl) [__ia64__]: New fields got and tramp.
|
||||||
|
(grub_dl): New field 'base'.
|
||||||
|
(grub_dl_register_symbol): New argument isfunc. All users updated.
|
||||||
|
(GRUB_IA64_DL_TRAMP_ALIGN): New definition.
|
||||||
|
(GRUB_IA64_DL_TRAMP_SIZE): Likewise.
|
||||||
|
(GRUB_IA64_DL_GOT_ALIGN): Likewise.
|
||||||
|
(grub_ia64_dl_get_tramp_got_size): New proto.
|
||||||
|
(GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Likewise
|
||||||
|
(GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Likewise
|
||||||
|
(grub_arch_dl_get_tramp_got_size) [__ia64__]: Likewise
|
||||||
|
* include/grub/efi/api.h: Skip call wrappers on ia64.
|
||||||
|
* include/grub/efi/pe32.h (GRUB_PE32_MACHINE_IA64): New definition.
|
||||||
|
* include/grub/efi/time.h (GRUB_TICKS_PER_SECOND): Change to 1000.
|
||||||
|
* include/grub/elf.h (ELF_ST_INFO): New definition.
|
||||||
|
* include/grub/ia64/efi/kernel.h: New file.
|
||||||
|
* include/grub/ia64/efi/memory.h: Likewise.
|
||||||
|
* include/grub/ia64/efi/time.h: Likewise.
|
||||||
|
* include/grub/ia64/kernel.h: Likewise.
|
||||||
|
* include/grub/ia64/setjmp.h: Likewise (from glibc).
|
||||||
|
* include/grub/ia64/time.h: New file.
|
||||||
|
* include/grub/ia64/types.h: Likewise.
|
||||||
|
* include/grub/libgcc.h (__udivsi3, __umodsi3, __umoddi3, __udivdi3,
|
||||||
|
__moddi3, __divdi3, __divsi3, __modsi3, __ia64_trampoline):
|
||||||
|
New protos.
|
||||||
|
* include/grub/offsets.h (GRUB_KERNEL_IA64_EFI_PREFIX): New definition.
|
||||||
|
(GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise.
|
||||||
|
* include/grub/types.h (PRIxGRUB_ADDR): Likewise.
|
||||||
|
* util/grub-mkimage.c (image_target_desc): New field pe_target.
|
||||||
|
All users updated.
|
||||||
|
(EFI64_HEADER_SIZE): New definition. All users updated.
|
||||||
|
(image_targets): Add ia64-efi.
|
||||||
|
* util/grub-mkimagexx.c (relocate_symbols): New arguments jumpers and
|
||||||
|
jumpers_addr. All users updated.
|
||||||
|
Create function descriptors.
|
||||||
|
(count_funcs): New function.
|
||||||
|
(unaligned_uint32): New struct.
|
||||||
|
(MASK20): New definition.
|
||||||
|
(MASK19): Likewise.
|
||||||
|
(MASKF21): Likewise.
|
||||||
|
(add_value_to_slot_20b): New function.
|
||||||
|
(add_value_to_slot_21_real): Likewise.
|
||||||
|
(add_value_to_slot_21): Likewise.
|
||||||
|
(ia64_kernel_trampoline): New struct.
|
||||||
|
(nopm): New variable.
|
||||||
|
(jump): Likewise.
|
||||||
|
(make_trampoline): New function.
|
||||||
|
(relocate_addresses): Handle ia64.
|
||||||
|
(make_reloc_section): Likewise.
|
||||||
|
(load_image): Likewise.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/fs/btrfs.c (grub_btrfs_read_logical): Silence spurious
|
||||||
|
warning. Move variables before code while on it.
|
||||||
|
|
||||||
|
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fuloong support.
|
||||||
|
|
||||||
|
* configure.ac: Rename yeeloong platform to loongson. All users updated.
|
||||||
|
* grub-core/Makefile.core.def (fwstart_fuloong): New image.
|
||||||
|
* grub-core/boot/mips/loongson/fuloong.S: New file.
|
||||||
|
* grub-core/boot/mips/loongson/fwstart.S: Wait for CS5536 to come up.
|
||||||
|
Explicitly init CS5536.
|
||||||
|
[FULOONG]: Don't use serial until CS5536 is available.
|
||||||
|
Set GPIO based on dumps.
|
||||||
|
(serial_hw_init) [FULOONG]: Handle CS5536 parts.
|
||||||
|
[FULOONG]: Handle GPIO and memory controller differences.
|
||||||
|
Parse machine type in $a2.
|
||||||
|
* grub-core/boot/mips/startup_raw.S: Determine and save the
|
||||||
|
architecture.
|
||||||
|
* grub-core/bus/cs5536.c (gpiodump): Move to fwstart.S.
|
||||||
|
(grub_cs5536_init_geode): Remove gpio part. Conditionalise DIVIL
|
||||||
|
init on architecture type.
|
||||||
|
* grub-core/kern/mips/loongson/init.c (grub_machine_init): Init
|
||||||
|
SIS315E. Don't init at_keyboard on fuloong.
|
||||||
|
(grub_halt): Support Fuloong.
|
||||||
|
* grub-core/kern/mips/startup.S [LOONGSON]: Save $s7.
|
||||||
|
* grub-core/loader/mips/linux.c (LOONGSON_MACHTYPE): Removed.
|
||||||
|
(loongson_machtypes): New array.
|
||||||
|
(grub_cmd_linux) [GRUB_MACHINE_MIPS_LOONGSON]: Pass the right machine
|
||||||
|
type.
|
||||||
|
* grub-core/term/ns8250.c (serial_get_divisor): New parameter port and
|
||||||
|
config. All users updated. Handle CS5536 serial.
|
||||||
|
* grub-core/term/serial.c (grub_serial_register): Conditionalise
|
||||||
|
default port on machine type. Register serial as inactive.
|
||||||
|
* grub-core/video/sis315pro.c: New file.
|
||||||
|
* include/grub/cs5536.h (GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED): New
|
||||||
|
definition.
|
||||||
|
(GRUB_CS5536_MSR_MAILBOX_CONFIG): Likewise.
|
||||||
|
(GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1): Likewise.
|
||||||
|
(GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3): Likewise.
|
||||||
|
(GRUB_CS5536_MSR_DIVIL_UART1_CONF): Likewise.
|
||||||
|
(GRUB_CS5536_MSR_DIVIL_UART2_CONF): Likewise.
|
||||||
|
* include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_SHUTDOWN_GPIO): Rename
|
||||||
|
to ...
|
||||||
|
(GRUB_CPU_YEELOONG_SHUTDOWN_GPIO): ... this.
|
||||||
|
* include/grub/mips/loongson/kernel.h (GRUB_ARCH_MACHINE_YEELOONG): New
|
||||||
|
definition.
|
||||||
|
(GRUB_ARCH_MACHINE_FULOONG): Likewise.
|
||||||
|
(grub_arch_machine): New extern var.
|
||||||
|
* include/grub/mips/loongson/serial.h
|
||||||
|
(GRUB_MACHINE_SERIAL_DIVISOR_115200): Renamed to ...
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200): ... this.
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT): Renamed to ...
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT0): ... this.
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200): New definition.
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT1): Likewise.
|
||||||
|
(GRUB_MACHINE_SERIAL_PORT2): Likewise.
|
||||||
|
(GRUB_MACHINE_SERIAL_PORTS): Include ports 1 and 2.
|
||||||
|
* include/grub/term.h (grub_term_register_input_inactive): New inline
|
||||||
|
function.
|
||||||
|
(grub_term_register_output_inactive): Likewise.
|
||||||
|
* include/grub/video.h (grub_video_driver_id): New value
|
||||||
|
GRUB_VIDEO_DRIVER_SIS315PRO.
|
||||||
|
* util/grub-mkimage.c (image_target_desc): Rename name to dirname.
|
||||||
|
New field "names". All users updated.
|
||||||
|
New field value IMAGE_FULOONG_FLASH.
|
||||||
|
(generate_image): USe separate fwstart hashes for yeeloong and fuloong.
|
||||||
|
|
||||||
|
2011-05-14 Jordan Uggla <jordan.uggla@gmail.com>
|
||||||
|
|
||||||
|
* docs/grub.texi (Invoking grub-install): Fix additional outdated claims
|
||||||
|
and add some clarification.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* util/grub.d/10_linux.in: Autoload gzio since it's needed on some
|
||||||
|
platforms if kernel is compressed.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/mm.c (grub_memalign): Disable auto-unloadding of
|
||||||
|
unused modules since currently referrence counter isn't reliable and
|
||||||
|
there isn't much memory to recover there anyway.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/dl.c (grub_dl_load_file): Decrease ref counter
|
||||||
|
rather than resetting it to allow modules to reference themselves
|
||||||
|
in init.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/dl.c (grub_dl_unload): Don't decrease reference
|
||||||
|
counter on dependencies since grub_dl_unref already handles this.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/font/font_cmd.c (loadfont_command): Set grub_errno
|
||||||
|
on error if not already done.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fix few potential memory misusage.
|
||||||
|
|
||||||
|
* grub-core/font/font.c (load_font_index): Don't free char_index to
|
||||||
|
avoid double free.
|
||||||
|
(grub_font_load): Zero-fill font at alloc for safety.
|
||||||
|
Close file on error.
|
||||||
|
(free_font): Free bmp_idx.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* docs/grub.texi (Installation): Fix several outdated claims.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Handle module_license on windows.
|
||||||
|
|
||||||
|
* util/grub-pe2elf.c (MODLICENSE_SECTION): New definition. All following
|
||||||
|
sections shifted.
|
||||||
|
(insert_string): Make argument const char * instead of char *.
|
||||||
|
(write_section_data): Handle long section names.
|
||||||
|
Handle module_license.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/commands/menuentry.c (grub_cmd_menuentry): Correctly
|
||||||
|
handle class-free menuentries.
|
||||||
|
(grub_normal_add_menu_entry): Add a check to be sure.
|
||||||
|
|
||||||
|
2011-05-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/term/at_keyboard.c (set1_e0_mapping): Fix swap between
|
||||||
|
PgUp and PgDown.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* configure.ac: Bump version to 1.99.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Give ATA device a bit more time on first try in order to allow disks
|
||||||
|
to spin up.
|
||||||
|
|
||||||
|
* grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT
|
||||||
|
if dev->present is 1. Reset dev->present on failure.
|
||||||
|
(grub_ata_device_initialize): Set dev->present to 1.
|
||||||
|
* include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value.
|
||||||
|
(grub_ata_device): New member 'present'.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* util/grub-mkimage.c (generate_image): Update hash.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Flush caches on DMA memory.
|
||||||
|
|
||||||
|
* grub-core/kern/mips/cache.S (grub_arch_sync_dma_caches): New function.
|
||||||
|
* grub-core/bus/pci.c (grub_memalign_dma32): Flush caches.
|
||||||
|
(grub_dma_free): Likewise.
|
||||||
|
* include/grub/cache.h (grub_arch_sync_dma_caches): New declaration.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/boot/mips/yeeloong/fwstart.S: Add explicit set mips3
|
||||||
|
to avoid asm treating ld and sd as macros.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/boot/mips/startup_raw.S: Flush cache after loading
|
||||||
|
decompressor.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/boot/mips/startup_raw.S: Use jalr rather than bal to call
|
||||||
|
grub_decompress_core since later would fail if grub_decompress_core
|
||||||
|
is too far.
|
||||||
|
|
||||||
|
2011-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/mips/dl.c (grub_arch_dl_relocate_symbols): Handle
|
||||||
|
R_MIPS_JALR since it's used by newer compiler.
|
||||||
|
|
||||||
|
2011-05-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* util/grub.d/10_linux.in: Correctly handle the Linux in root.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/loader/efi/chainloader.c (grub_chainloader_unload): Set
|
||||||
|
file_path to 0 for surety.
|
||||||
|
(grub_chainloader_boot): Set exit_data to NULL.
|
||||||
|
Unset the loader once done.
|
||||||
|
(grub_cmd_chainloader): Fix confusing error message if file is empty.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/term/at_keyboard.c (fetch_key): Make a printf on
|
||||||
|
unknown key into a dprintf.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/emu/hostdisk.c (linux_find_partition): Don't abort
|
||||||
|
on first non-existant partition.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/emu/hostdisk.c (open_device): Set data->fd to -1 if
|
||||||
|
openning fails.
|
||||||
|
Reported by: Mark Korenberg.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/kern/emu/hostdisk.c (linux_find_partition): Prevent possible
|
||||||
|
overflow.
|
||||||
|
|
||||||
|
2011-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* util/grub-mkimage.c (main): Explicitely flush and sync the output
|
||||||
|
before closing to ensure that it will be readable by grub-setup.
|
||||||
|
|
||||||
2011-05-05 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-05-05 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro.
|
* grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro.
|
||||||
|
@ -332,7 +1276,7 @@
|
||||||
(grub_util_biosdisk_open): Don't apply ioctl on non-disk devices.
|
(grub_util_biosdisk_open): Don't apply ioctl on non-disk devices.
|
||||||
(open_device) Likewise.
|
(open_device) Likewise.
|
||||||
(grub_util_biosdisk_close): Likewise.
|
(grub_util_biosdisk_close): Likewise.
|
||||||
Reported by: Mark Korenberger.
|
Reported by: Mark Korenberg.
|
||||||
|
|
||||||
2011-04-10 Alexander Kurtz <kurtz.alex@googlemail.com>
|
2011-04-10 Alexander Kurtz <kurtz.alex@googlemail.com>
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,14 @@ library = {
|
||||||
common = grub-core/fs/jfs.c;
|
common = grub-core/fs/jfs.c;
|
||||||
common = grub-core/fs/minix.c;
|
common = grub-core/fs/minix.c;
|
||||||
common = grub-core/fs/minix2.c;
|
common = grub-core/fs/minix2.c;
|
||||||
|
common = grub-core/fs/minix3.c;
|
||||||
common = grub-core/fs/nilfs2.c;
|
common = grub-core/fs/nilfs2.c;
|
||||||
common = grub-core/fs/ntfs.c;
|
common = grub-core/fs/ntfs.c;
|
||||||
common = grub-core/fs/ntfscomp.c;
|
common = grub-core/fs/ntfscomp.c;
|
||||||
common = grub-core/fs/reiserfs.c;
|
common = grub-core/fs/reiserfs.c;
|
||||||
|
common = grub-core/fs/romfs.c;
|
||||||
common = grub-core/fs/sfs.c;
|
common = grub-core/fs/sfs.c;
|
||||||
|
common = grub-core/fs/squash4.c;
|
||||||
common = grub-core/fs/tar.c;
|
common = grub-core/fs/tar.c;
|
||||||
common = grub-core/fs/udf.c;
|
common = grub-core/fs/udf.c;
|
||||||
common = grub-core/fs/ufs2.c;
|
common = grub-core/fs/ufs2.c;
|
||||||
|
@ -92,6 +95,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/dvh.c;
|
||||||
common = grub-core/partmap/sunpc.c;
|
common = grub-core/partmap/sunpc.c;
|
||||||
common = grub-core/partmap/bsdlabel.c;
|
common = grub-core/partmap/bsdlabel.c;
|
||||||
common = grub-core/script/function.c;
|
common = grub-core/script/function.c;
|
||||||
|
@ -100,6 +104,7 @@ library = {
|
||||||
common = grub-core/script/script.c;
|
common = grub-core/script/script.c;
|
||||||
common = grub-core/script/argv.c;
|
common = grub-core/script/argv.c;
|
||||||
common = grub-core/io/gzio.c;
|
common = grub-core/io/gzio.c;
|
||||||
|
common = grub-core/kern/ia64/dl_helper.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -109,7 +114,7 @@ program = {
|
||||||
ldadd = libgrubkern.a;
|
ldadd = libgrubkern.a;
|
||||||
ldadd = grub-core/gnulib/libgnu.a;
|
ldadd = grub-core/gnulib/libgnu.a;
|
||||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||||
mansection = 1;
|
installdir = noinst;
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
|
@ -283,6 +288,7 @@ program = {
|
||||||
program = {
|
program = {
|
||||||
name = grub-ofpathname;
|
name = grub-ofpathname;
|
||||||
installdir = sbin;
|
installdir = sbin;
|
||||||
|
mansection = 8;
|
||||||
ieee1275 = util/ieee1275/grub-ofpathname.c;
|
ieee1275 = util/ieee1275/grub-ofpathname.c;
|
||||||
ieee1275 = util/ieee1275/ofpath.c;
|
ieee1275 = util/ieee1275/ofpath.c;
|
||||||
|
|
||||||
|
@ -383,7 +389,8 @@ script = {
|
||||||
x86 = 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 = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
enable = i386_qemu;
|
enable = i386_qemu;
|
||||||
enable = i386_multiboot;
|
enable = i386_multiboot;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
|
|
|
@ -25,13 +25,13 @@ endif
|
||||||
if COND_i386_ieee1275
|
if COND_i386_ieee1275
|
||||||
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
||||||
endif
|
endif
|
||||||
if COND_mips_yeeloong
|
if COND_mips_loongson
|
||||||
CFLAGS_PLATFORM += -mexplicit-relocs
|
CFLAGS_PLATFORM += -mexplicit-relocs
|
||||||
CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK
|
CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK
|
||||||
CCASFLAGS_PLATFORM = -march=mips3
|
|
||||||
endif
|
endif
|
||||||
if COND_mips
|
if COND_mips
|
||||||
CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache
|
CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache
|
||||||
|
CCASFLAGS_PLATFORM = -march=mips3
|
||||||
endif
|
endif
|
||||||
if COND_sparc64_ieee1275
|
if COND_sparc64_ieee1275
|
||||||
CFLAGS_PLATFORM += -mno-app-regs
|
CFLAGS_PLATFORM += -mno-app-regs
|
||||||
|
|
60
configure.ac
60
configure.ac
|
@ -32,7 +32,7 @@ dnl type, so there is no conflict. Variables with the prefix "TARGET_"
|
||||||
dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
|
dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
|
||||||
dnl type.
|
dnl type.
|
||||||
|
|
||||||
AC_INIT([GRUB],[1.99~rc2],[bug-grub@gnu.org])
|
AC_INIT([GRUB],[1.99],[bug-grub@gnu.org])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ case "$target_cpu" in
|
||||||
amd64) target_cpu=x86_64 ;;
|
amd64) target_cpu=x86_64 ;;
|
||||||
sparc) target_cpu=sparc64 ;;
|
sparc) target_cpu=sparc64 ;;
|
||||||
mipsel|mips64el)
|
mipsel|mips64el)
|
||||||
target_cpu=mips;
|
target_cpu=mipsel;
|
||||||
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1";
|
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1";
|
||||||
;;
|
;;
|
||||||
mips|mips64)
|
mips|mips64)
|
||||||
|
@ -96,7 +96,9 @@ if test "x$with_platform" = x; then
|
||||||
powerpc-*) platform=ieee1275 ;;
|
powerpc-*) platform=ieee1275 ;;
|
||||||
powerpc64-*) platform=ieee1275 ;;
|
powerpc64-*) platform=ieee1275 ;;
|
||||||
sparc64-*) platform=ieee1275 ;;
|
sparc64-*) platform=ieee1275 ;;
|
||||||
mips-*) platform=yeeloong ;;
|
mipsel-*) platform=loongson ;;
|
||||||
|
mips-*) platform=arc ;;
|
||||||
|
ia64-*) platform=efi ;;
|
||||||
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
|
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
|
||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
|
@ -122,8 +124,15 @@ case "$target_cpu"-"$platform" in
|
||||||
i386-qemu) ;;
|
i386-qemu) ;;
|
||||||
powerpc-ieee1275) ;;
|
powerpc-ieee1275) ;;
|
||||||
sparc64-ieee1275) ;;
|
sparc64-ieee1275) ;;
|
||||||
mips-qemu-mips) ;;
|
ia64-efi) ;;
|
||||||
mips-yeeloong) ;;
|
mips-qemu_mips) ;;
|
||||||
|
mips-qemu-mips) platform=qemu_mips;;
|
||||||
|
mips-arc) ;;
|
||||||
|
mipsel-qemu_mips) ;;
|
||||||
|
mipsel-qemu-mips) platform=qemu_mips;;
|
||||||
|
mipsel-yeeloong) platform=loongson ;;
|
||||||
|
mipsel-fuloong) platform=loongson ;;
|
||||||
|
mipsel-loongson) ;;
|
||||||
*-emu) ;;
|
*-emu) ;;
|
||||||
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
|
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
|
||||||
esac
|
esac
|
||||||
|
@ -156,14 +165,19 @@ case "$platform" in
|
||||||
qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
|
qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
|
||||||
pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;;
|
pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;;
|
||||||
emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;;
|
emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;;
|
||||||
yeeloong) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
|
loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
|
||||||
qemu-mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
|
qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
|
||||||
|
arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;;
|
||||||
esac
|
esac
|
||||||
case "$target_cpu" in
|
case "$target_cpu" in
|
||||||
mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
|
mips |mipsel) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
|
||||||
sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
|
sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
|
||||||
esac
|
esac
|
||||||
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
|
if test x${target_cpu} = xmipsel ; then
|
||||||
|
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
|
||||||
|
else
|
||||||
|
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
|
||||||
|
fi
|
||||||
|
|
||||||
HOST_CPPFLAGS="$HOST_CPPFLAGS $machine_CPPFLAGS"
|
HOST_CPPFLAGS="$HOST_CPPFLAGS $machine_CPPFLAGS"
|
||||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS"
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS"
|
||||||
|
@ -219,8 +233,8 @@ for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then
|
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson ); then
|
||||||
AC_MSG_ERROR([qemu and yeeloong ports need unifont])
|
AC_MSG_ERROR([qemu and loongson ports need unifont])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST([FONT_SOURCE])
|
AC_SUBST([FONT_SOURCE])
|
||||||
|
@ -398,7 +412,7 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "${target_cpu}-${platform}" = mips-yeeloong; then
|
if test "${target_cpu}-${platform}" = mipsel-loongson; then
|
||||||
AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [
|
AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [
|
||||||
SAVE_CFLAGS="$CFLAGS"
|
SAVE_CFLAGS="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -march=loongson2f"
|
CFLAGS="$CFLAGS -march=loongson2f"
|
||||||
|
@ -590,7 +604,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for libgcc symbols
|
# Check for libgcc symbols
|
||||||
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x)
|
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3)
|
||||||
|
|
||||||
if test "x$TARGET_APPLE_CC" = x1 ; then
|
if test "x$TARGET_APPLE_CC" = x1 ; then
|
||||||
CFLAGS="$TARGET_CFLAGS -nostdlib"
|
CFLAGS="$TARGET_CFLAGS -nostdlib"
|
||||||
|
@ -945,16 +959,18 @@ AC_SUBST(NEED_REGISTER_FRAME_INFO)
|
||||||
AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
|
AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
|
||||||
AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
|
AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
|
||||||
AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
|
AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
|
||||||
|
AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi])
|
||||||
AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu])
|
AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu])
|
||||||
AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275])
|
AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275])
|
||||||
AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
|
AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
|
||||||
AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
|
AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
|
||||||
AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
|
AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
|
||||||
AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform = xyeeloong])
|
AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
|
||||||
AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips])
|
AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
|
||||||
|
AM_CONDITIONAL([COND_mips_arc], [test x$target_cpu = xmips -a x$platform = xarc])
|
||||||
AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
|
AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
|
||||||
AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
|
AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
|
||||||
AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips])
|
AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel])
|
||||||
|
|
||||||
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
|
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
|
||||||
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
|
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
|
||||||
|
@ -976,19 +992,23 @@ AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
|
||||||
AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin])
|
AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin])
|
||||||
|
|
||||||
# Output files.
|
# Output files.
|
||||||
|
cpudir="${target_cpu}"
|
||||||
|
if test x${cpudir} = xmipsel; then
|
||||||
|
cpudir=mips;
|
||||||
|
fi
|
||||||
grub_CHECK_LINK_DIR
|
grub_CHECK_LINK_DIR
|
||||||
if test x"$link_dir" = xyes ; then
|
if test x"$link_dir" = xyes ; then
|
||||||
AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu])
|
AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir])
|
||||||
if test "$platform" != emu ; then
|
if test "$platform" != emu ; then
|
||||||
AC_CONFIG_LINKS([include/grub/machine:include/grub/$target_cpu/$platform])
|
AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform])
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
mkdir -p include/grub 2>/dev/null
|
mkdir -p include/grub 2>/dev/null
|
||||||
rm -rf include/grub/cpu
|
rm -rf include/grub/cpu
|
||||||
cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null
|
cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null
|
||||||
if test "$platform" != emu ; then
|
if test "$platform" != emu ; then
|
||||||
rm -rf include/grub/machine
|
rm -rf include/grub/machine
|
||||||
cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
|
cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
103
docs/grub.texi
103
docs/grub.texi
|
@ -528,21 +528,15 @@ system (@pxref{Obtaining and Building GRUB}). You can do this either
|
||||||
from the source tarball, or as a package for your OS.
|
from the source tarball, or as a package for your OS.
|
||||||
|
|
||||||
After you have done that, you need to install the boot loader on a
|
After you have done that, you need to install the boot loader on a
|
||||||
drive (floppy or hard disk). There are two ways of doing that - either
|
drive (floppy or hard disk) by using the utility
|
||||||
using the utility @command{grub-install} (@pxref{Invoking
|
@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS.
|
||||||
grub-install}) on a UNIX-like OS, or by running GRUB itself from a
|
|
||||||
floppy. These are quite similar, however the utility might probe a
|
|
||||||
wrong BIOS drive, so you should be careful.
|
|
||||||
|
|
||||||
Also, if you install GRUB on a UNIX-like OS, please make sure that you
|
|
||||||
have an emergency boot disk ready, so that you can rescue your computer
|
|
||||||
if, by any chance, your hard drive becomes unusable (unbootable).
|
|
||||||
|
|
||||||
GRUB comes with boot images, which are normally put in the directory
|
GRUB comes with boot images, which are normally put in the directory
|
||||||
@file{/usr/lib/grub/i386-pc}. Hereafter, the directory where GRUB images are
|
@file{/usr/lib/grub/<cpu>-<platform>} (for BIOS-based machines
|
||||||
initially placed (normally @file{/usr/lib/grub/i386-pc}) will be
|
@file{/usr/lib/grub/i386-pc}). Hereafter, the directory where GRUB images are
|
||||||
|
initially placed (normally @file{/usr/lib/grub/<cpu>-<platform>}) will be
|
||||||
called the @dfn{image directory}, and the directory where the boot
|
called the @dfn{image directory}, and the directory where the boot
|
||||||
loader needs to find them (usually @file{/boot/grub}) will be called
|
loader needs to find them (usually @file{/boot}) will be called
|
||||||
the @dfn{boot directory}.
|
the @dfn{boot directory}.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
@ -556,27 +550,18 @@ the @dfn{boot directory}.
|
||||||
@node Installing GRUB using grub-install
|
@node Installing GRUB using grub-install
|
||||||
@section Installing GRUB using grub-install
|
@section Installing GRUB using grub-install
|
||||||
|
|
||||||
@strong{Caution:} This procedure is definitely less safe, because
|
|
||||||
there are several ways in which your computer can become
|
|
||||||
unbootable. For example, most operating systems don't tell GRUB how to
|
|
||||||
map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses}
|
|
||||||
the mapping. This will succeed in most cases, but not
|
|
||||||
always. Therefore, GRUB provides you with a map file called the
|
|
||||||
@dfn{device map}, which you must fix if it is wrong. @xref{Device
|
|
||||||
map}, for more details.
|
|
||||||
|
|
||||||
For information on where GRUB should be installed on PC BIOS platforms,
|
For information on where GRUB should be installed on PC BIOS platforms,
|
||||||
@pxref{BIOS installation}.
|
@pxref{BIOS installation}.
|
||||||
|
|
||||||
If you still do want to install GRUB under a UNIX-like OS (such
|
In order to install GRUB under a UNIX-like OS (such
|
||||||
as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking
|
as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking
|
||||||
grub-install}) as the superuser (@dfn{root}).
|
grub-install}) as the superuser (@dfn{root}).
|
||||||
|
|
||||||
The usage is basically very simple. You only need to specify one
|
The usage is basically very simple. You only need to specify one
|
||||||
argument to the program, namely, where to install the boot loader. The
|
argument to the program, namely, where to install the boot loader. The
|
||||||
argument can be either a device file (like @samp{/dev/hda}) or a
|
argument has to be either a device file (like @samp{/dev/hda}).
|
||||||
partition specified in GRUB's notation. For example, under Linux the
|
For example, under Linux the following will install GRUB into the MBR
|
||||||
following will install GRUB into the MBR of the first IDE disk:
|
of the first IDE disk:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
# @kbd{grub-install /dev/hda}
|
# @kbd{grub-install /dev/hda}
|
||||||
|
@ -588,37 +573,22 @@ Likewise, under GNU/Hurd, this has the same effect:
|
||||||
# @kbd{grub-install /dev/hd0}
|
# @kbd{grub-install /dev/hd0}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
But all the above examples assume that GRUB should use images under
|
But all the above examples assume that GRUB should put images under
|
||||||
the root directory. If you want GRUB to use images under a directory
|
the @file{/boot} directory. If you want GRUB to put images under a directory
|
||||||
other than the root directory, you need to specify the option
|
other than @file{/boot}, you need to specify the option
|
||||||
@option{--root-directory}. The typical usage is that you create a GRUB
|
@option{--boot-directory}. The typical usage is that you create a GRUB
|
||||||
boot floppy with a filesystem. Here is an example:
|
boot floppy with a filesystem. Here is an example:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
# @kbd{mke2fs /dev/fd0}
|
# @kbd{mke2fs /dev/fd0}
|
||||||
# @kbd{mount -t ext2 /dev/fd0 /mnt}
|
# @kbd{mount -t ext2 /dev/fd0 /mnt}
|
||||||
# @kbd{grub-install --root-directory=/mnt fd0}
|
# @kbd{mkdir /mnt/boot}
|
||||||
|
# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0}
|
||||||
# @kbd{umount /mnt}
|
# @kbd{umount /mnt}
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Another example is when you have a separate boot partition
|
|
||||||
which is mounted at @file{/boot}. Since GRUB is a boot loader, it
|
|
||||||
doesn't know anything about mountpoints at all. Thus, you need to run
|
|
||||||
@command{grub-install} like this:
|
|
||||||
|
|
||||||
@example
|
|
||||||
# @kbd{grub-install --root-directory=/boot /dev/hda}
|
|
||||||
@end example
|
|
||||||
|
|
||||||
By the way, as noted above, it is quite difficult to guess BIOS drives
|
|
||||||
correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt
|
|
||||||
you to check if it could really guess the correct mappings, after the
|
|
||||||
installation. The format is defined in @ref{Device map}. Please be
|
|
||||||
quite careful. If the output is wrong, it is unlikely that your
|
|
||||||
computer will be able to boot with no problem.
|
|
||||||
|
|
||||||
Some BIOSes have a bug of exposing the first partition of a USB drive as a
|
Some BIOSes have a bug of exposing the first partition of a USB drive as a
|
||||||
floppy instead of exposing the USB drive as a hard disk (they call it
|
floppy instead of exposing the USB drive as a hard disk (they call it
|
||||||
``USB-FDD'' boot). In such cases, you need to install like this:
|
``USB-FDD'' boot). In such cases, you need to install like this:
|
||||||
|
@ -1199,8 +1169,14 @@ NetBSD.
|
||||||
|
|
||||||
@item GRUB_CMDLINE_XEN
|
@item GRUB_CMDLINE_XEN
|
||||||
@itemx GRUB_CMDLINE_XEN_DEFAULT
|
@itemx GRUB_CMDLINE_XEN_DEFAULT
|
||||||
As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for
|
The values of these options are appended to the values of
|
||||||
Linux and Xen.
|
@samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux
|
||||||
|
and Xen menu entries.
|
||||||
|
|
||||||
|
@item GRUB_CMDLINE_LINUX_XEN_REPLACE
|
||||||
|
@item GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT
|
||||||
|
The values of these options replace the values of @samp{GRUB_CMDLINE_LINUX}
|
||||||
|
and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux and Xen menu entries.
|
||||||
|
|
||||||
@item GRUB_DISABLE_LINUX_UUID
|
@item GRUB_DISABLE_LINUX_UUID
|
||||||
Normally, @command{grub-mkconfig} will generate menu entries that use
|
Normally, @command{grub-mkconfig} will generate menu entries that use
|
||||||
|
@ -3966,6 +3942,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab BIOS @tab Coreboot
|
@item @tab BIOS @tab Coreboot
|
||||||
@item BIOS chainloading @tab yes @tab no (1)
|
@item BIOS chainloading @tab yes @tab no (1)
|
||||||
@item NTLDR @tab yes @tab no (1)
|
@item NTLDR @tab yes @tab no (1)
|
||||||
|
@item Freedos @tab yes @tab no (1)
|
||||||
@item FreeBSD bootloader @tab yes @tab crashes (1)
|
@item FreeBSD bootloader @tab yes @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
|
@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
|
||||||
@item 64-bit kFreeBSD @tab yes @tab crashes (2,6)
|
@item 64-bit kFreeBSD @tab yes @tab crashes (2,6)
|
||||||
|
@ -3990,6 +3967,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab Multiboot @tab Qemu
|
@item @tab Multiboot @tab Qemu
|
||||||
@item BIOS chainloading @tab no (1) @tab no (1)
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
@item NTLDR @tab no (1) @tab no (1)
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item FreeDOS @tab no (1) @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
||||||
@item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
@item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6)
|
||||||
|
@ -4014,6 +3992,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab 32-bit EFI @tab 64-bit EFI
|
@item @tab 32-bit EFI @tab 64-bit EFI
|
||||||
@item BIOS chainloading @tab no (1) @tab no (1)
|
@item BIOS chainloading @tab no (1) @tab no (1)
|
||||||
@item NTLDR @tab no (1) @tab no (1)
|
@item NTLDR @tab no (1) @tab no (1)
|
||||||
|
@item FreeDOS @tab no (1) @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab headless @tab headless
|
@item 32-bit kFreeBSD @tab headless @tab headless
|
||||||
@item 64-bit kFreeBSD @tab headless @tab headless
|
@item 64-bit kFreeBSD @tab headless @tab headless
|
||||||
|
@ -4038,6 +4017,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel
|
||||||
@item @tab IEEE1275
|
@item @tab IEEE1275
|
||||||
@item BIOS chainloading @tab no (1)
|
@item BIOS chainloading @tab no (1)
|
||||||
@item NTLDR @tab no (1)
|
@item NTLDR @tab no (1)
|
||||||
|
@item FreeDOS @tab no (1)
|
||||||
@item FreeBSD bootloader @tab crashes (1)
|
@item FreeBSD bootloader @tab crashes (1)
|
||||||
@item 32-bit kFreeBSD @tab crashes (6)
|
@item 32-bit kFreeBSD @tab crashes (6)
|
||||||
@item 64-bit kFreeBSD @tab crashes (6)
|
@item 64-bit kFreeBSD @tab crashes (6)
|
||||||
|
@ -4195,15 +4175,28 @@ Print a summary of the command-line options and exit.
|
||||||
@item --version
|
@item --version
|
||||||
Print the version number of GRUB and exit.
|
Print the version number of GRUB and exit.
|
||||||
|
|
||||||
@item --root-directory=@var{dir}
|
@item --boot-directory=@var{dir}
|
||||||
Install GRUB images under the directory @var{dir} instead of the root
|
Install GRUB images under the directory @file{@var{dir}/grub/}
|
||||||
directory. This option is useful when you want to install GRUB into a
|
This option is useful when you want to install GRUB into a
|
||||||
separate partition or a removable disk. Here is an example in which
|
separate partition or a removable disk.
|
||||||
you have a separate @dfn{boot} partition which is mounted on
|
If this option is not specified then it defaults to @file{/boot}, so
|
||||||
@file{/boot}:
|
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@kbd{grub-install --root-directory=/boot hd0}
|
@kbd{grub-install /dev/sda}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
is equivalent to
|
||||||
|
|
||||||
|
@example
|
||||||
|
@kbd{grub-install --boot-directory=/boot/ /dev/sda}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here is an example in which you have a separate @dfn{boot} partition which is
|
||||||
|
mounted on
|
||||||
|
@file{/mnt/boot}:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item --recheck
|
@item --recheck
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[NAME]
|
|
||||||
grub-bin2h \- convert a binary file to a C header
|
|
19
gentpl.py
19
gentpl.py
|
@ -6,8 +6,9 @@
|
||||||
|
|
||||||
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
|
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
|
||||||
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
|
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
|
||||||
"mips_yeeloong", "sparc64_ieee1275",
|
"mips_loongson", "sparc64_ieee1275",
|
||||||
"powerpc_ieee1275" ]
|
"powerpc_ieee1275", "mips_arc", "ia64_efi",
|
||||||
|
"mips_qemu_mips" ]
|
||||||
|
|
||||||
GROUPS = {}
|
GROUPS = {}
|
||||||
|
|
||||||
|
@ -17,29 +18,29 @@ GROUPS["common"] = GRUB_PLATFORMS[:]
|
||||||
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["mips"] = [ "mips_yeeloong" ]
|
GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
|
||||||
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
||||||
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
||||||
|
|
||||||
# Groups based on firmware
|
# Groups based on firmware
|
||||||
GROUPS["x86_efi"] = [ "i386_efi", "x86_64_efi" ]
|
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi" ]
|
||||||
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
|
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
|
||||||
|
|
||||||
# emu is a special case so many core functionality isn't needed on this platform
|
# 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 based on hardware features
|
# Groups based on hardware features
|
||||||
GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_yeeloong"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi")
|
GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi")
|
||||||
GROUPS["pci"] = GROUPS["x86"] + GROUPS["mips"]
|
GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
|
||||||
GROUPS["usb"] = GROUPS["pci"]
|
GROUPS["usb"] = GROUPS["pci"]
|
||||||
|
|
||||||
# If gfxterm is main output console integrate it into kernel
|
# If gfxterm is main output console integrate it into kernel
|
||||||
GROUPS["videoinkernel"] = ["mips_yeeloong"]
|
GROUPS["videoinkernel"] = ["mips_loongson"]
|
||||||
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
|
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
|
||||||
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
|
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
|
||||||
|
|
||||||
# Similar for terminfo
|
# Similar for terminfo
|
||||||
GROUPS["terminfoinkernel"] = ["mips_yeeloong"] + GROUPS["ieee1275"];
|
GROUPS["terminfoinkernel"] = ["mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"];
|
||||||
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
|
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
|
||||||
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
|
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ def foreach_enabled_platform(closure):
|
||||||
# noemu = bus/usb/usbhub.c;
|
# noemu = bus/usb/usbhub.c;
|
||||||
# enable = emu;
|
# enable = emu;
|
||||||
# enable = i386;
|
# enable = i386;
|
||||||
# enable = mips_yeeloong;
|
# enable = mips_loongson;
|
||||||
# emu_condition = COND_GRUB_EMU_USB;
|
# emu_condition = COND_GRUB_EMU_USB;
|
||||||
# };
|
# };
|
||||||
#
|
#
|
||||||
|
|
|
@ -127,7 +127,26 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.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_ia64_efi
|
||||||
|
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/disk.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_mips
|
||||||
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_mips_arc
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_mips_qemu_mips
|
||||||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
if COND_mips_loongson
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.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/cpu/cache.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h
|
||||||
|
@ -147,6 +166,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if COND_mips_qemu_mips
|
||||||
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||||
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||||
|
endif
|
||||||
|
|
||||||
if COND_powerpc_ieee1275
|
if COND_powerpc_ieee1275
|
||||||
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/ieee1275/ofnet.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h
|
||||||
|
@ -310,6 +334,7 @@ CLEANFILES += config.log syminfo.lst moddep.lst
|
||||||
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
|
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
|
||||||
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
|
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
|
||||||
platform_DATA += $(MOD_FILES)
|
platform_DATA += $(MOD_FILES)
|
||||||
|
platform_DATA += modinfo.sh
|
||||||
CLEANFILES += $(MOD_FILES)
|
CLEANFILES += $(MOD_FILES)
|
||||||
|
|
||||||
if COND_ENABLE_EFIEMU
|
if COND_ENABLE_EFIEMU
|
||||||
|
|
|
@ -12,14 +12,26 @@ script = {
|
||||||
common = genmod.sh.in;
|
common = genmod.sh.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script = {
|
||||||
|
installdir = noinst;
|
||||||
|
name = modinfo.sh;
|
||||||
|
common = modinfo.sh.in;
|
||||||
|
};
|
||||||
|
|
||||||
kernel = {
|
kernel = {
|
||||||
name = kernel;
|
name = kernel;
|
||||||
|
|
||||||
nostrip = emu;
|
nostrip = emu;
|
||||||
|
|
||||||
emu_ldflags = '-Wl,-r,-d';
|
emu_ldflags = '-Wl,-r,-d';
|
||||||
x86_efi_ldflags = '-Wl,-r,-d';
|
i386_efi_ldflags = '-Wl,-r,-d';
|
||||||
x86_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
i386_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
||||||
|
x86_64_efi_ldflags = '-Wl,-r,-d';
|
||||||
|
x86_64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
||||||
|
|
||||||
|
ia64_efi_cflags = '-fno-builtin -fpic -minline-int-divide-max-throughput';
|
||||||
|
ia64_efi_ldflags = '-Wl,-r,-d';
|
||||||
|
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
||||||
|
|
||||||
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
||||||
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
||||||
|
@ -32,11 +44,13 @@ kernel = {
|
||||||
i386_coreboot_ldflags = '-Wl,-Ttext=0x8200';
|
i386_coreboot_ldflags = '-Wl,-Ttext=0x8200';
|
||||||
i386_multiboot_ldflags = '-Wl,-Ttext=0x8200';
|
i386_multiboot_ldflags = '-Wl,-Ttext=0x8200';
|
||||||
i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000';
|
i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000';
|
||||||
mips_yeeloong_ldflags = '-Wl,-Ttext,0x80200000';
|
mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
|
||||||
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
|
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
|
||||||
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
|
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
|
||||||
|
mips_arc_ldflags = '-Wl,-Ttext,0x8bd00000';
|
||||||
|
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
|
||||||
|
|
||||||
mips_yeeloong_cppflags = '-DUSE_ASCII_FAILBACK';
|
mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK';
|
||||||
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
|
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
|
||||||
emu_cflags = '$(CFLAGS_GNULIB)';
|
emu_cflags = '$(CFLAGS_GNULIB)';
|
||||||
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
||||||
|
@ -48,7 +62,7 @@ kernel = {
|
||||||
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
|
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
|
||||||
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
i386_coreboot_startup = kern/i386/coreboot/startup.S;
|
||||||
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
i386_multiboot_startup = kern/i386/coreboot/startup.S;
|
||||||
mips_yeeloong_startup = kern/mips/startup.S;
|
mips_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;
|
||||||
|
|
||||||
|
@ -77,11 +91,10 @@ kernel = {
|
||||||
noemu_nodist = symlist.c;
|
noemu_nodist = symlist.c;
|
||||||
|
|
||||||
i386_pc = 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_qemu = kern/generic/rtc_get_time_ms.c;
|
||||||
i386_coreboot = 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;
|
i386_multiboot = kern/generic/rtc_get_time_ms.c;
|
||||||
mips_yeeloong = kern/generic/rtc_get_time_ms.c;
|
mips = 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;
|
||||||
|
@ -105,18 +118,24 @@ kernel = {
|
||||||
|
|
||||||
x86 = kern/i386/pit.c;
|
x86 = kern/i386/pit.c;
|
||||||
|
|
||||||
x86_efi = disk/efi/efidisk.c;
|
efi = disk/efi/efidisk.c;
|
||||||
x86_efi = kern/efi/efi.c;
|
efi = kern/efi/efi.c;
|
||||||
x86_efi = kern/efi/init.c;
|
efi = kern/efi/init.c;
|
||||||
x86_efi = kern/efi/mm.c;
|
efi = kern/efi/mm.c;
|
||||||
x86_efi = kern/i386/efi/init.c;
|
efi = term/efi/console.c;
|
||||||
x86_efi = term/efi/console.c;
|
|
||||||
|
|
||||||
i386_efi = kern/i386/tsc.c;
|
i386_efi = kern/i386/tsc.c;
|
||||||
|
i386_efi = kern/i386/efi/init.c;
|
||||||
|
|
||||||
x86_64_efi = kern/i386/tsc.c;
|
x86_64_efi = kern/i386/tsc.c;
|
||||||
x86_64_efi = kern/x86_64/dl.c;
|
x86_64_efi = kern/x86_64/dl.c;
|
||||||
x86_64_efi = kern/x86_64/efi/callwrap.S;
|
x86_64_efi = kern/x86_64/efi/callwrap.S;
|
||||||
|
x86_64_efi = kern/i386/efi/init.c;
|
||||||
|
|
||||||
|
ia64_efi = kern/ia64/efi/startup.S;
|
||||||
|
ia64_efi = kern/ia64/efi/init.c;
|
||||||
|
ia64_efi = kern/ia64/dl.c;
|
||||||
|
ia64_efi = kern/ia64/dl_helper.c;
|
||||||
|
|
||||||
i386_pc = kern/i386/pc/init.c;
|
i386_pc = kern/i386/pc/init.c;
|
||||||
i386_pc = kern/i386/pc/mmap.c;
|
i386_pc = kern/i386/pc/mmap.c;
|
||||||
|
@ -136,19 +155,29 @@ kernel = {
|
||||||
|
|
||||||
i386_ieee1275 = kern/ieee1275/init.c;
|
i386_ieee1275 = kern/ieee1275/init.c;
|
||||||
|
|
||||||
mips_yeeloong = term/ns8250.c;
|
mips = kern/mips/cache.S;
|
||||||
mips_yeeloong = bus/bonito.c;
|
mips = kern/mips/dl.c;
|
||||||
mips_yeeloong = bus/cs5536.c;
|
mips = kern/mips/init.c;
|
||||||
mips_yeeloong = bus/pci.c;
|
|
||||||
mips_yeeloong = kern/mips/cache.S;
|
mips_qemu_mips = kern/mips/qemu_mips/init.c;
|
||||||
mips_yeeloong = kern/mips/dl.c;
|
mips_qemu_mips = term/ns8250.c;
|
||||||
mips_yeeloong = kern/mips/init.c;
|
mips_qemu_mips = term/serial.c;
|
||||||
mips_yeeloong = kern/mips/yeeloong/init.c;
|
|
||||||
mips_yeeloong = term/at_keyboard.c;
|
mips_arc = kern/mips/arc/init.c;
|
||||||
mips_yeeloong = term/serial.c;
|
mips_arc = term/arc/console.c;
|
||||||
mips_yeeloong = video/sm712.c;
|
mips_arc = disk/arc/arcdisk.c;
|
||||||
|
|
||||||
|
mips_loongson = term/ns8250.c;
|
||||||
|
mips_loongson = bus/bonito.c;
|
||||||
|
mips_loongson = bus/cs5536.c;
|
||||||
|
mips_loongson = bus/pci.c;
|
||||||
|
mips_loongson = kern/mips/loongson/init.c;
|
||||||
|
mips_loongson = term/at_keyboard.c;
|
||||||
|
mips_loongson = term/serial.c;
|
||||||
|
mips_loongson = video/sm712.c;
|
||||||
|
mips_loongson = video/sis315pro.c;
|
||||||
extra_dist = video/sm712_init.c;
|
extra_dist = video/sm712_init.c;
|
||||||
mips_yeeloong = commands/keylayouts.c;
|
mips_loongson = commands/keylayouts.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;
|
||||||
|
@ -162,7 +191,7 @@ kernel = {
|
||||||
emu = disk/host.c;
|
emu = disk/host.c;
|
||||||
emu = gnulib/progname.c;
|
emu = gnulib/progname.c;
|
||||||
emu = gnulib/error.c;
|
emu = gnulib/error.c;
|
||||||
emu = kern/emu/cache.S;
|
emu = kern/emu/cache_s.S;
|
||||||
emu = kern/emu/console.c;
|
emu = kern/emu/console.c;
|
||||||
emu = kern/emu/getroot.c;
|
emu = kern/emu/getroot.c;
|
||||||
emu = kern/emu/hostdisk.c;
|
emu = kern/emu/hostdisk.c;
|
||||||
|
@ -171,6 +200,7 @@ kernel = {
|
||||||
emu = kern/emu/misc.c;
|
emu = kern/emu/misc.c;
|
||||||
emu = kern/emu/mm.c;
|
emu = kern/emu/mm.c;
|
||||||
emu = kern/emu/time.c;
|
emu = kern/emu/time.c;
|
||||||
|
emu = kern/emu/cache.c;
|
||||||
|
|
||||||
videoinkernel = term/gfxterm.c;
|
videoinkernel = term/gfxterm.c;
|
||||||
videoinkernel = font/font.c;
|
videoinkernel = font/font.c;
|
||||||
|
@ -178,6 +208,7 @@ kernel = {
|
||||||
videoinkernel = io/bufio.c;
|
videoinkernel = io/bufio.c;
|
||||||
videoinkernel = video/bitmap.c;
|
videoinkernel = video/bitmap.c;
|
||||||
videoinkernel = video/bitmap_scale.c;
|
videoinkernel = video/bitmap_scale.c;
|
||||||
|
videoinkernel = video/colors.c;
|
||||||
videoinkernel = video/fb/fbblit.c;
|
videoinkernel = video/fb/fbblit.c;
|
||||||
videoinkernel = video/fb/fbfill.c;
|
videoinkernel = video/fb/fbfill.c;
|
||||||
videoinkernel = video/fb/fbutil.c;
|
videoinkernel = video/fb/fbutil.c;
|
||||||
|
@ -295,12 +326,12 @@ image = {
|
||||||
common = lib/xzembed/xz_dec_lzma2.c;
|
common = lib/xzembed/xz_dec_lzma2.c;
|
||||||
common = lib/xzembed/xz_dec_stream.c;
|
common = lib/xzembed/xz_dec_stream.c;
|
||||||
|
|
||||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
|
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1';
|
||||||
|
|
||||||
mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
|
|
||||||
|
|
||||||
objcopyflags = '-O binary';
|
objcopyflags = '-O binary';
|
||||||
ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
||||||
|
mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
||||||
|
mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
|
||||||
ldadd = '-lgcc';
|
ldadd = '-lgcc';
|
||||||
cflags = '-static-libgcc';
|
cflags = '-static-libgcc';
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
@ -311,10 +342,12 @@ image = {
|
||||||
mips = boot/mips/startup_raw.S;
|
mips = boot/mips/startup_raw.S;
|
||||||
common = boot/decompressor/none.c;
|
common = boot/decompressor/none.c;
|
||||||
|
|
||||||
mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000';
|
cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1';
|
||||||
|
|
||||||
objcopyflags = '-O binary';
|
objcopyflags = '-O binary';
|
||||||
ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
||||||
|
mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000';
|
||||||
|
mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000';
|
||||||
ldadd = '-lgcc';
|
ldadd = '-lgcc';
|
||||||
cflags = '-static-libgcc';
|
cflags = '-static-libgcc';
|
||||||
enable = mips;
|
enable = mips;
|
||||||
|
@ -322,10 +355,18 @@ image = {
|
||||||
|
|
||||||
image = {
|
image = {
|
||||||
name = fwstart;
|
name = fwstart;
|
||||||
mips_yeeloong = boot/mips/yeeloong/fwstart.S;
|
mips_loongson = boot/mips/loongson/fwstart.S;
|
||||||
objcopyflags = '-O binary';
|
objcopyflags = '-O binary';
|
||||||
ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
|
ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
|
||||||
enable = mips_yeeloong;
|
enable = mips_loongson;
|
||||||
|
};
|
||||||
|
|
||||||
|
image = {
|
||||||
|
name = fwstart_fuloong;
|
||||||
|
mips_loongson = boot/mips/loongson/fuloong.S;
|
||||||
|
objcopyflags = '-O binary';
|
||||||
|
ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
|
||||||
|
enable = mips_loongson;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -349,8 +390,8 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = lsspd;
|
name = lsspd;
|
||||||
mips_yeeloong = commands/mips/yeeloong/lsspd.c;
|
mips_loongson = commands/mips/loongson/lsspd.c;
|
||||||
enable = mips_yeeloong;
|
enable = mips_loongson;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -401,13 +442,21 @@ module = {
|
||||||
|
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = x86_efi;
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
enable = i386_ieee1275;
|
enable = i386_ieee1275;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
enable = i386_multiboot;
|
enable = i386_multiboot;
|
||||||
emu_condition = COND_GRUB_EMU_PCI;
|
emu_condition = COND_GRUB_EMU_PCI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = lsdev;
|
||||||
|
common = commands/arc/lsdev.c;
|
||||||
|
|
||||||
|
enable = mips_arc;
|
||||||
|
};
|
||||||
|
|
||||||
library = {
|
library = {
|
||||||
name = libgnulib.a;
|
name = libgnulib.a;
|
||||||
common = gnulib/regex.c;
|
common = gnulib/regex.c;
|
||||||
|
@ -440,12 +489,12 @@ module = {
|
||||||
name = acpi;
|
name = acpi;
|
||||||
|
|
||||||
common = commands/acpi.c;
|
common = commands/acpi.c;
|
||||||
x86_efi = commands/efi/acpi.c;
|
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_coreboot = commands/i386/pc/acpi.c;
|
||||||
i386_multiboot = commands/i386/pc/acpi.c;
|
i386_multiboot = commands/i386/pc/acpi.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
enable = i386_multiboot;
|
enable = i386_multiboot;
|
||||||
|
@ -456,7 +505,7 @@ module = {
|
||||||
|
|
||||||
common = commands/lsacpi.c;
|
common = commands/lsacpi.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = i386_coreboot;
|
enable = i386_coreboot;
|
||||||
enable = i386_multiboot;
|
enable = i386_multiboot;
|
||||||
|
@ -467,7 +516,7 @@ module = {
|
||||||
|
|
||||||
common = commands/efi/lsefisystab.c;
|
common = commands/efi/lsefisystab.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -475,7 +524,7 @@ module = {
|
||||||
|
|
||||||
common = commands/efi/lssal.c;
|
common = commands/efi/lssal.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -483,7 +532,7 @@ module = {
|
||||||
|
|
||||||
common = commands/efi/lsefimmap.c;
|
common = commands/efi/lsefimmap.c;
|
||||||
|
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -546,8 +595,9 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = fixvideo;
|
name = fixvideo;
|
||||||
x86_efi = commands/efi/fixvideo.c;
|
common = commands/efi/fixvideo.c;
|
||||||
enable = x86_efi;
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -562,11 +612,12 @@ module = {
|
||||||
i386_pc = commands/acpihalt.c;
|
i386_pc = commands/acpihalt.c;
|
||||||
i386_coreboot = commands/acpihalt.c;
|
i386_coreboot = commands/acpihalt.c;
|
||||||
i386_multiboot = commands/acpihalt.c;
|
i386_multiboot = commands/acpihalt.c;
|
||||||
x86_efi = commands/acpihalt.c;
|
i386_efi = commands/acpihalt.c;
|
||||||
|
x86_64_efi = commands/acpihalt.c;
|
||||||
i386_multiboot = lib/i386/halt.c;
|
i386_multiboot = lib/i386/halt.c;
|
||||||
i386_coreboot = lib/i386/halt.c;
|
i386_coreboot = lib/i386/halt.c;
|
||||||
i386_qemu = lib/i386/halt.c;
|
i386_qemu = lib/i386/halt.c;
|
||||||
x86_efi = lib/efi/halt.c;
|
efi = lib/efi/halt.c;
|
||||||
ieee1275 = lib/ieee1275/halt.c;
|
ieee1275 = lib/ieee1275/halt.c;
|
||||||
emu = lib/emu/halt.c;
|
emu = lib/emu/halt.c;
|
||||||
};
|
};
|
||||||
|
@ -581,6 +632,7 @@ module = {
|
||||||
common = commands/hdparm.c;
|
common = commands/hdparm.c;
|
||||||
common = lib/hexdump.c;
|
common = lib/hexdump.c;
|
||||||
enable = pci;
|
enable = pci;
|
||||||
|
enable = mips_qemu_mips;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -601,8 +653,9 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = loadbios;
|
name = loadbios;
|
||||||
x86_efi = commands/efi/loadbios.c;
|
common = commands/efi/loadbios.c;
|
||||||
enable = x86_efi;
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -811,12 +864,14 @@ module = {
|
||||||
name = ata;
|
name = ata;
|
||||||
common = disk/ata.c;
|
common = disk/ata.c;
|
||||||
enable = pci;
|
enable = pci;
|
||||||
|
enable = mips_qemu_mips;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = ata_pthru;
|
name = ata_pthru;
|
||||||
common = disk/ata_pthru.c;
|
common = disk/ata_pthru.c;
|
||||||
enable = pci;
|
enable = pci;
|
||||||
|
enable = mips_qemu_mips;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -959,6 +1014,11 @@ module = {
|
||||||
common = fs/minix2.c;
|
common = fs/minix2.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = minix3;
|
||||||
|
common = fs/minix3.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = nilfs2;
|
name = nilfs2;
|
||||||
common = fs/nilfs2.c;
|
common = fs/nilfs2.c;
|
||||||
|
@ -979,11 +1039,21 @@ module = {
|
||||||
common = fs/reiserfs.c;
|
common = fs/reiserfs.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = romfs;
|
||||||
|
common = fs/romfs.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = sfs;
|
name = sfs;
|
||||||
common = fs/sfs.c;
|
common = fs/sfs.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = squash4;
|
||||||
|
common = fs/squash4.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = tar;
|
name = tar;
|
||||||
common = fs/tar.c;
|
common = fs/tar.c;
|
||||||
|
@ -1051,7 +1121,6 @@ module = {
|
||||||
common = gfxmenu/gui_progress_bar.c;
|
common = gfxmenu/gui_progress_bar.c;
|
||||||
common = gfxmenu/gui_util.c;
|
common = gfxmenu/gui_util.c;
|
||||||
common = gfxmenu/gui_string_util.c;
|
common = gfxmenu/gui_string_util.c;
|
||||||
common = gfxmenu/named_colors.c;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1097,7 +1166,7 @@ module = {
|
||||||
x86_64 = lib/x86_64/relocator_asm.S;
|
x86_64 = lib/x86_64/relocator_asm.S;
|
||||||
x86 = lib/i386/relocator.c;
|
x86 = lib/i386/relocator.c;
|
||||||
ieee1275 = lib/ieee1275/relocator.c;
|
ieee1275 = lib/ieee1275/relocator.c;
|
||||||
x86_efi = lib/efi/relocator.c;
|
efi = lib/efi/relocator.c;
|
||||||
mips = lib/mips/relocator_asm.S;
|
mips = lib/mips/relocator_asm.S;
|
||||||
mips = lib/mips/relocator.c;
|
mips = lib/mips/relocator.c;
|
||||||
powerpc = lib/powerpc/relocator_asm.S;
|
powerpc = lib/powerpc/relocator_asm.S;
|
||||||
|
@ -1114,9 +1183,10 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = datetime;
|
name = datetime;
|
||||||
cmos = lib/cmos_datetime.c;
|
cmos = lib/cmos_datetime.c;
|
||||||
x86_efi = lib/efi/datetime.c;
|
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;
|
||||||
|
mips_arc = lib/arc/datetime.c;
|
||||||
enable = noemu;
|
enable = noemu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1128,6 +1198,7 @@ module = {
|
||||||
extra_dist = lib/x86_64/setjmp.S;
|
extra_dist = lib/x86_64/setjmp.S;
|
||||||
extra_dist = lib/sparc64/setjmp.S;
|
extra_dist = lib/sparc64/setjmp.S;
|
||||||
extra_dist = lib/powerpc/setjmp.S;
|
extra_dist = lib/powerpc/setjmp.S;
|
||||||
|
extra_dist = lib/ia64/setjmp.S;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1161,6 +1232,12 @@ module = {
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = freedos;
|
||||||
|
i386_pc = loader/i386/pc/freedos.c;
|
||||||
|
enable = i386_pc;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = multiboot2;
|
name = multiboot2;
|
||||||
cppflags = "-DGRUB_USE_MULTIBOOT2";
|
cppflags = "-DGRUB_USE_MULTIBOOT2";
|
||||||
|
@ -1186,6 +1263,7 @@ module = {
|
||||||
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;
|
||||||
|
ia64_efi = loader/ia64/efi/linux.c;
|
||||||
common = lib/cmdline.c;
|
common = lib/cmdline.c;
|
||||||
enable = noemu;
|
enable = noemu;
|
||||||
};
|
};
|
||||||
|
@ -1205,16 +1283,17 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = appleldr;
|
name = appleldr;
|
||||||
x86_efi = loader/efi/appleloader.c;
|
common = loader/efi/appleloader.c;
|
||||||
enable = x86_efi;
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = chain;
|
name = chain;
|
||||||
x86_efi = loader/efi/chainloader.c;
|
efi = loader/efi/chainloader.c;
|
||||||
i386_pc = loader/i386/pc/chainloader.c;
|
i386_pc = loader/i386/pc/chainloader.c;
|
||||||
enable = i386_pc;
|
enable = i386_pc;
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1226,12 +1305,13 @@ module = {
|
||||||
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/efi/mmap.c;
|
efi = mmap/efi/mmap.c;
|
||||||
|
|
||||||
mips_yeeloong = mmap/mips/yeeloong/uppermem.c;
|
mips = mmap/mips/uppermem.c;
|
||||||
|
|
||||||
enable = x86;
|
enable = x86;
|
||||||
enable = mips_yeeloong;
|
enable = ia64_efi;
|
||||||
|
enable = mips;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1305,6 +1385,11 @@ module = {
|
||||||
common = partmap/sun.c;
|
common = partmap/sun.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = part_dvh;
|
||||||
|
common = partmap/dvh.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = part_bsd;
|
name = part_bsd;
|
||||||
common = partmap/bsdlabel.c;
|
common = partmap/bsdlabel.c;
|
||||||
|
@ -1338,8 +1423,7 @@ module = {
|
||||||
x86 = term/ns8250.c;
|
x86 = term/ns8250.c;
|
||||||
|
|
||||||
enable = emu;
|
enable = emu;
|
||||||
enable = i386;
|
enable = x86;
|
||||||
enable = x86_64_efi;
|
|
||||||
emu_condition = COND_GRUB_EMU_USB;
|
emu_condition = COND_GRUB_EMU_USB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1415,14 +1499,15 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = efi_gop;
|
name = efi_gop;
|
||||||
x86_efi = video/efi_gop.c;
|
efi = video/efi_gop.c;
|
||||||
enable = x86_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = efi_uga;
|
name = efi_uga;
|
||||||
x86_efi = video/efi_uga.c;
|
efi = video/efi_uga.c;
|
||||||
enable = x86_efi;
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1458,13 +1543,14 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = video;
|
name = video;
|
||||||
common = video/video.c;
|
common = video/video.c;
|
||||||
|
common = video/colors.c;
|
||||||
enable = videomodules;
|
enable = videomodules;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = ieee1275_fb;
|
name = ieee1275_fb;
|
||||||
ieee1275 = video/ieee1275.c;
|
ieee1275 = video/ieee1275.c;
|
||||||
enable = powerpc;
|
enable = powerpc_ieee1275;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
|
|
@ -25,6 +25,9 @@ grub_decompress_core (void *src, void *dest, unsigned long n,
|
||||||
char *d = (char *) dest;
|
char *d = (char *) dest;
|
||||||
const char *s = (const char *) src;
|
const char *s = (const char *) src;
|
||||||
|
|
||||||
|
if (d == s)
|
||||||
|
return;
|
||||||
|
|
||||||
if (d < s)
|
if (d < s)
|
||||||
while (n--)
|
while (n--)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
|
|
2
grub-core/boot/mips/loongson/fuloong.S
Normal file
2
grub-core/boot/mips/loongson/fuloong.S
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define FULOONG 1
|
||||||
|
#include "fwstart.S"
|
|
@ -16,51 +16,73 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/mips/yeeloong/serial.h>
|
#include <grub/mips/loongson/serial.h>
|
||||||
#include <grub/mips/yeeloong/pci.h>
|
#include <grub/mips/loongson/pci.h>
|
||||||
#include <grub/mips/loongson.h>
|
#include <grub/mips/loongson.h>
|
||||||
#include <grub/pci.h>
|
#include <grub/pci.h>
|
||||||
#include <grub/machine/serial.h>
|
#include <grub/machine/serial.h>
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/ns8250.h>
|
#include <grub/ns8250.h>
|
||||||
#include <grub/cs5536.h>
|
#include <grub/cs5536.h>
|
||||||
#include <grub/smbus.h>
|
#include <grub/smbus.h>
|
||||||
|
|
||||||
|
#ifdef FULOONG
|
||||||
|
#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2
|
||||||
|
#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200
|
||||||
|
#else
|
||||||
|
#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT0
|
||||||
|
#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200
|
||||||
|
#endif
|
||||||
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set noat
|
.set noat
|
||||||
.set nomacro
|
.set nomacro
|
||||||
|
.set mips3
|
||||||
|
|
||||||
.global start,_start,__start
|
.global start,_start,__start
|
||||||
start:
|
start:
|
||||||
_start:
|
_start:
|
||||||
__start:
|
__start:
|
||||||
|
/* Put serial init as soon as possible. But on Fuloong serial is past
|
||||||
|
Geode, so on Fuloong we need Geode first.
|
||||||
|
*/
|
||||||
|
#ifndef FULOONG
|
||||||
bal serial_hw_init
|
bal serial_hw_init
|
||||||
nop
|
nop
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Find CS5536 controller. */
|
/* Find CS5536 controller. */
|
||||||
/* $t4 chooses device in priority encoding. */
|
/* $t4 chooses device in priority encoding. */
|
||||||
/* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
|
/* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
|
||||||
This way we don't need to sacrifice a register for it. */
|
This way we don't need to sacrifice a register for it. */
|
||||||
|
retry_cs5536:
|
||||||
/* We have only one bus (0). Function is 0. */
|
/* We have only one bus (0). Function is 0. */
|
||||||
lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
|
lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
|
||||||
lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
|
lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
|
||||||
lui $t3, %hi(GRUB_CS5536_PCIID)
|
lui $t3, %hi(GRUB_CS5536_PCIID)
|
||||||
addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
|
addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
|
||||||
ori $t4, $zero, 1
|
ori $t4, $zero, 1
|
||||||
lui $a0, %hi(no_cs5536)
|
|
||||||
1:
|
1:
|
||||||
andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
|
andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
|
||||||
beql $t4, $zero, fatal
|
/* In case of failure try again. CS5536 may be slow to come up. */
|
||||||
addiu $a0, $a0, %lo(no_cs5536)
|
beql $t4, $zero, retry_cs5536
|
||||||
|
nop
|
||||||
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
|
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
|
||||||
lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
|
lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
|
||||||
bnel $t2, $t3, 1b
|
bnel $t2, $t3, 1b
|
||||||
sll $t4, $t4, 1
|
sll $t4, $t4, 1
|
||||||
|
|
||||||
|
#ifndef FULOONG
|
||||||
bal message
|
bal message
|
||||||
addiu $a0, $a0, %lo(cs5536_found)
|
addiu $a0, $a0, %lo(cs5536_found)
|
||||||
bal printhex
|
bal printhex
|
||||||
move $a0, $t4
|
move $a0, $t4
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialise SMBus controller. */
|
lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE)
|
||||||
|
li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED
|
||||||
|
sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0)
|
||||||
|
|
||||||
/* Set GPIO LBAR. */
|
/* Set GPIO LBAR. */
|
||||||
lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
|
lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
|
||||||
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
|
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
|
||||||
|
@ -70,6 +92,15 @@ __start:
|
||||||
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
|
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
|
||||||
| GRUB_CS5536_LBAR_ENABLE) >> 32)
|
| GRUB_CS5536_LBAR_ENABLE) >> 32)
|
||||||
|
|
||||||
|
bal gpio_init
|
||||||
|
nop
|
||||||
|
|
||||||
|
#ifdef FULOONG
|
||||||
|
bal serial_hw_init
|
||||||
|
nop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialise SMBus controller. */
|
||||||
/* Set SMBUS LBAR. */
|
/* Set SMBUS LBAR. */
|
||||||
lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
|
lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
|
||||||
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
|
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
|
||||||
|
@ -83,14 +114,6 @@ __start:
|
||||||
bal message
|
bal message
|
||||||
addiu $a0, $a0, %lo(smbus_enabled)
|
addiu $a0, $a0, %lo(smbus_enabled)
|
||||||
|
|
||||||
/* Enable SMBus controller pins. */
|
|
||||||
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
|
|
||||||
ori $t1, $zero, GRUB_GPIO_SMBUS_PINS
|
|
||||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0)
|
|
||||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0)
|
|
||||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0)
|
|
||||||
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0)
|
|
||||||
|
|
||||||
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
|
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
|
||||||
|
|
||||||
/* Disable SMB. */
|
/* Disable SMB. */
|
||||||
|
@ -107,7 +130,7 @@ __start:
|
||||||
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
|
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
|
||||||
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
|
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
|
||||||
|
|
||||||
/* Yeeloong has only one memory slot. */
|
/* Yeeloong and Fuloong have only one memory slot. */
|
||||||
/* Output first byte on serial for debugging. */
|
/* Output first byte on serial for debugging. */
|
||||||
ori $a1, $zero, GRUB_SMB_RAM_START_ADDR
|
ori $a1, $zero, GRUB_SMB_RAM_START_ADDR
|
||||||
bal read_spd
|
bal read_spd
|
||||||
|
@ -206,10 +229,54 @@ other_exception:
|
||||||
b fatal
|
b fatal
|
||||||
addiu $a0, $a0, %lo(unhandled_exception)
|
addiu $a0, $a0, %lo(unhandled_exception)
|
||||||
|
|
||||||
|
gpio_init:
|
||||||
|
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
|
||||||
|
addiu $t0, $t0, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
|
||||||
|
lui $t1, %hi (gpio_dump)
|
||||||
|
addiu $t1, $t1, %lo (gpio_dump)
|
||||||
|
|
||||||
|
1:
|
||||||
|
lw $t2, 0($t1)
|
||||||
|
sw $t2, 0($t0)
|
||||||
|
addiu $t0, $t0, 4
|
||||||
|
addiu $t1, $t1, 4
|
||||||
|
lui $t2, %hi (gpio_dump_end)
|
||||||
|
addiu $t2, $t2, %lo (gpio_dump_end)
|
||||||
|
bne $t1, $t2, 1b
|
||||||
|
nop
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
|
|
||||||
/* Same as similarly named C function but in asm since
|
/* Same as similarly named C function but in asm since
|
||||||
we need it early. */
|
we need it early. */
|
||||||
/* In: none. Out: none. Clobbered: $t0, $t1, $a0. */
|
/* In: none. Out: none. Clobbered: $t0, $t1, $t2, $a0, $a1, $a2. */
|
||||||
serial_hw_init:
|
serial_hw_init:
|
||||||
|
move $t2, $ra
|
||||||
|
#ifdef FULOONG
|
||||||
|
lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_LEG_IO)
|
||||||
|
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_LEG_IO)
|
||||||
|
lui $a1, %hi (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 \
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP \
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 \
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1)
|
||||||
|
ori $a1, $a1, (GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 \
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1)
|
||||||
|
bal wrmsr
|
||||||
|
move $a2, $zero
|
||||||
|
|
||||||
|
lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART1_CONF)
|
||||||
|
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART1_CONF)
|
||||||
|
li $a1, 2
|
||||||
|
bal wrmsr
|
||||||
|
move $a2, $zero
|
||||||
|
|
||||||
|
lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART2_CONF)
|
||||||
|
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART2_CONF)
|
||||||
|
li $a1, 2
|
||||||
|
bal wrmsr
|
||||||
|
move $a2, $zero
|
||||||
|
#endif
|
||||||
|
|
||||||
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
|
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
|
||||||
|
|
||||||
/* Turn off the interrupt. */
|
/* Turn off the interrupt. */
|
||||||
|
@ -239,6 +306,7 @@ serial_hw_init:
|
||||||
/* Let message return to original caller. */
|
/* Let message return to original caller. */
|
||||||
lui $a0, %hi(notification_string)
|
lui $a0, %hi(notification_string)
|
||||||
addiu $a0, $a0, %lo(notification_string)
|
addiu $a0, $a0, %lo(notification_string)
|
||||||
|
move $ra, $t2
|
||||||
|
|
||||||
/* Print message on serial console. */
|
/* Print message on serial console. */
|
||||||
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
|
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
|
||||||
|
@ -379,7 +447,6 @@ read_spd_fail:
|
||||||
ori $v0, $v0, 0x100
|
ori $v0, $v0, 0x100
|
||||||
|
|
||||||
notification_string: .asciz "GRUB "
|
notification_string: .asciz "GRUB "
|
||||||
no_cs5536: .asciz "No CS5536 found.\n\r"
|
|
||||||
cs5536_found: .asciz "CS5536 at "
|
cs5536_found: .asciz "CS5536 at "
|
||||||
sm_failed: .asciz "SM transaction failed.\n\r"
|
sm_failed: .asciz "SM transaction failed.\n\r"
|
||||||
unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r"
|
unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r"
|
||||||
|
@ -404,14 +471,22 @@ regdump:
|
||||||
.quad 0x0100020200010101 /* 4 */
|
.quad 0x0100020200010101 /* 4 */
|
||||||
.quad 0x0a04030603050203 /* 6 */
|
.quad 0x0a04030603050203 /* 6 */
|
||||||
.quad 0x0f0e040000010a0b /* 7 */
|
.quad 0x0f0e040000010a0b /* 7 */
|
||||||
|
#ifdef FULOONG
|
||||||
|
.quad 0x0000000100000001 /* 8 */
|
||||||
|
#else
|
||||||
.quad 0x0000010200000102 /* 8 */
|
.quad 0x0000010200000102 /* 8 */
|
||||||
|
#endif
|
||||||
.quad 0x0000060c00000000 /* 9 */
|
.quad 0x0000060c00000000 /* 9 */
|
||||||
.quad 0x2323233f3f1f0200 /* a */
|
.quad 0x2323233f3f1f0200 /* a */
|
||||||
.quad 0x5f7f232323232323 /* b */
|
.quad 0x5f7f232323232323 /* b */
|
||||||
.quad 0x002a3c0615000000 /* c */
|
.quad 0x002a3c0615000000 /* c */
|
||||||
.quad 0x002a002a002a002a /* d */
|
.quad 0x002a002a002a002a /* d */
|
||||||
.quad 0x002a002a002a002a /* e */
|
.quad 0x002a002a002a002a /* e */
|
||||||
|
#ifdef FULOONG
|
||||||
|
.quad 0x00b40020005b0004 /* f */
|
||||||
|
#else
|
||||||
.quad 0x00b40020006d0004 /* f */
|
.quad 0x00b40020006d0004 /* f */
|
||||||
|
#endif
|
||||||
.quad 0x070007ff00000087 /* 10 */
|
.quad 0x070007ff00000087 /* 10 */
|
||||||
.quad 0x000000000016101f /* 11 */
|
.quad 0x000000000016101f /* 11 */
|
||||||
.quad 0x001c000000000000 /* 12 */
|
.quad 0x001c000000000000 /* 12 */
|
||||||
|
@ -426,6 +501,45 @@ regdump:
|
||||||
.quad 0 /* 1b */
|
.quad 0 /* 1b */
|
||||||
.quad 0 /* 1c */
|
.quad 0 /* 1c */
|
||||||
|
|
||||||
|
/* Dump of GPIO connections. FIXME: Remove useless and macroify. */
|
||||||
|
gpio_dump:
|
||||||
|
#ifdef FULOONG
|
||||||
|
.long 0xffff0000, 0x2eefd110, 0xffff0000, 0xffff0000
|
||||||
|
.long 0x2eefd110, 0xffff0000, 0x1000efff, 0xefff1000
|
||||||
|
.long 0x3df3c20c, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0x7df3820c, 0x3df3c20c, 0xffff0000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0x3de3c21c, 0x3d83c27c
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000
|
||||||
|
.long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0xefff1000, 0xefff1000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
#else
|
||||||
|
.long 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000
|
||||||
|
.long 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000
|
||||||
|
.long 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000
|
||||||
|
.long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||||
|
.long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000
|
||||||
|
.long 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
.long 0x00000000, 0x50000000, 0x00000000, 0x00000000
|
||||||
|
#endif
|
||||||
|
gpio_dump_end:
|
||||||
|
|
||||||
.p2align
|
.p2align
|
||||||
|
|
||||||
write_dumpreg:
|
write_dumpreg:
|
||||||
|
@ -626,6 +740,10 @@ continue:
|
||||||
lui $t0, %hi(cached_continue - 0x20000000)
|
lui $t0, %hi(cached_continue - 0x20000000)
|
||||||
addiu $t0, $t0, %lo(cached_continue - 0x20000000)
|
addiu $t0, $t0, %lo(cached_continue - 0x20000000)
|
||||||
jr $t0
|
jr $t0
|
||||||
addiu $a2, $zero, -1
|
#ifdef FULOONG
|
||||||
|
addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_FULOONG)
|
||||||
|
#else
|
||||||
|
addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
#endif
|
||||||
|
|
||||||
cached_continue:
|
cached_continue:
|
|
@ -20,6 +20,7 @@
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
#define BASE_ADDR 8
|
#define BASE_ADDR 8
|
||||||
|
@ -43,21 +44,31 @@ compressed_size:
|
||||||
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
|
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
|
||||||
uncompressed_size:
|
uncompressed_size:
|
||||||
.long 0
|
.long 0
|
||||||
|
. = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR
|
||||||
|
uncompressed_addr:
|
||||||
|
.long 0
|
||||||
codestart:
|
codestart:
|
||||||
/* Save our base. */
|
/* Save our base. */
|
||||||
move $s0, $ra
|
move $s0, $ra
|
||||||
|
|
||||||
/* Parse arguments. Has to be done before relocation.
|
/* Parse arguments. Has to be done before relocation.
|
||||||
So need to do it in asm. */
|
So need to do it in asm. */
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
lui $t0, %hi (((16 << 20) - 264) | 0x80000000)
|
||||||
|
lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
move $s2, $zero
|
move $s2, $zero
|
||||||
move $s3, $zero
|
move $s3, $zero
|
||||||
move $s4, $zero
|
move $s4, $zero
|
||||||
move $s5, $zero
|
move $s5, $zero
|
||||||
|
move $s7, $zero
|
||||||
|
|
||||||
/* $a2 has the environment. */
|
/* $a2 has the environment. */
|
||||||
addiu $t0, $a2, 1
|
addiu $t0, $zero, -0x10
|
||||||
beq $t0, $zero, argdone
|
and $t1, $a2, $t0
|
||||||
|
beq $t0, $t1, argfw
|
||||||
nop
|
nop
|
||||||
move $t0, $a2
|
move $t0, $a2
|
||||||
argcont:
|
argcont:
|
||||||
|
@ -72,11 +83,19 @@ argcont:
|
||||||
nop ;\
|
nop ;\
|
||||||
b 2f;\
|
b 2f;\
|
||||||
move reg, $v0; \
|
move reg, $v0; \
|
||||||
1:
|
1:
|
||||||
|
#define DO_CHECKT1(str, val) \
|
||||||
|
move $t6, $t1 ;\
|
||||||
|
addiu $t7, $s0, (str - base);\
|
||||||
|
bal do_check ;\
|
||||||
|
li $t2, val
|
||||||
|
|
||||||
DO_PARSE (busclockstr, $s2)
|
DO_PARSE (busclockstr, $s2)
|
||||||
DO_PARSE (cpuclockstr, $s3)
|
DO_PARSE (cpuclockstr, $s3)
|
||||||
DO_PARSE (memsizestr, $s4)
|
DO_PARSE (memsizestr, $s4)
|
||||||
DO_PARSE (highmemsizestr, $s5)
|
DO_PARSE (highmemsizestr, $s5)
|
||||||
|
DO_CHECKT1 (pmon_yeeloong_verstr, GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
DO_CHECKT1 (pmon_fuloong_verstr, GRUB_ARCH_MACHINE_FULOONG)
|
||||||
2:
|
2:
|
||||||
b argcont
|
b argcont
|
||||||
addiu $t0, $t0, 4
|
addiu $t0, $t0, 4
|
||||||
|
@ -120,8 +139,47 @@ busclockstr: .asciiz "busclock="
|
||||||
cpuclockstr: .asciiz "cpuclock="
|
cpuclockstr: .asciiz "cpuclock="
|
||||||
memsizestr: .asciiz "memsize="
|
memsizestr: .asciiz "memsize="
|
||||||
highmemsizestr: .asciiz "highmemsize="
|
highmemsizestr: .asciiz "highmemsize="
|
||||||
|
machtype_yeeloong_str1: .asciiz "machtype=8.9"
|
||||||
|
machtype_yeeloong_str2: .asciiz "machtype=lemote-yeeloong-"
|
||||||
|
machtype_fuloong_str: .asciiz "machtype=lemote-fuloong-"
|
||||||
|
pmon_yeeloong_str: .asciiz "PMON_VER=LM8"
|
||||||
|
pmon_fuloong_str: .asciiz "PMON_VER=LM6"
|
||||||
|
pmon_yeeloong_verstr: .asciiz "Version=LM8"
|
||||||
|
pmon_fuloong_verstr: .asciiz "Version=LM6"
|
||||||
.p2align 2
|
.p2align 2
|
||||||
|
|
||||||
argdone:
|
argdone:
|
||||||
|
beq $a0, $zero, cmdlinedone
|
||||||
|
nop
|
||||||
|
#define DO_CHECKA1(str, val) \
|
||||||
|
lw $t6, 0($a1) ;\
|
||||||
|
addiu $t7, $s0, (str - base);\
|
||||||
|
bal do_check ;\
|
||||||
|
li $t2, val
|
||||||
|
DO_CHECKA1 (machtype_yeeloong_str1, GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
DO_CHECKA1 (machtype_yeeloong_str2, GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
DO_CHECKA1 (pmon_yeeloong_str, GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
DO_CHECKA1 (machtype_fuloong_str, GRUB_ARCH_MACHINE_FULOONG)
|
||||||
|
DO_CHECKA1 (pmon_fuloong_str, GRUB_ARCH_MACHINE_FULOONG)
|
||||||
|
addiu $a0, $a0, -1
|
||||||
|
b argdone
|
||||||
|
addiu $a1, $a1, 4
|
||||||
|
do_check:
|
||||||
|
lb $t4, 0($t7)
|
||||||
|
beq $t4, $zero, 1f
|
||||||
|
lb $t3, 0($t6)
|
||||||
|
bne $t3, $t4, 2f
|
||||||
|
addiu $t6, $t6, 1
|
||||||
|
b do_check
|
||||||
|
addiu $t7, $t7, 1
|
||||||
|
1:
|
||||||
|
move $s7, $t2
|
||||||
|
2:
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
|
argfw:
|
||||||
|
not $s7, $a2
|
||||||
|
cmdlinedone:
|
||||||
#endif
|
#endif
|
||||||
/* Copy the decompressor. */
|
/* Copy the decompressor. */
|
||||||
lui $t1, %hi(base)
|
lui $t1, %hi(base)
|
||||||
|
@ -150,6 +208,13 @@ argdone:
|
||||||
b 1b
|
b 1b
|
||||||
addiu $t1, $t1, 1
|
addiu $t1, $t1, 1
|
||||||
2:
|
2:
|
||||||
|
lui $a0, %hi(base)
|
||||||
|
addiu $a0, $a0, %lo(base)
|
||||||
|
lui $a1, %hi(_end)
|
||||||
|
addiu $a1, %lo(_end)
|
||||||
|
subu $a1,$a1,$a0
|
||||||
|
|
||||||
|
#include "../../kern/mips/cache_flush.S"
|
||||||
|
|
||||||
/* Decompress the payload. */
|
/* Decompress the payload. */
|
||||||
lui $a0, %hi(__bss_start)
|
lui $a0, %hi(__bss_start)
|
||||||
|
@ -159,8 +224,7 @@ argdone:
|
||||||
subu $a0, $a0, $t0
|
subu $a0, $a0, $t0
|
||||||
addu $a0, $a0, $s0
|
addu $a0, $a0, $s0
|
||||||
|
|
||||||
lui $a1, %hi(GRUB_MACHINE_LINK_ADDR)
|
lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
|
||||||
addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR)
|
|
||||||
lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
|
lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||||
lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
|
lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||||
move $s1, $a1
|
move $s1, $a1
|
||||||
|
@ -170,9 +234,11 @@ argdone:
|
||||||
*/
|
*/
|
||||||
move $s6, $a3
|
move $s6, $a3
|
||||||
|
|
||||||
lui $sp, %hi(_start - 256)
|
lui $t0, %hi(EXT_C(grub_decompress_core))
|
||||||
|
addiu $t0, $t0, %lo(EXT_C(grub_decompress_core))
|
||||||
|
|
||||||
bal EXT_C(grub_decompress_core)
|
lui $sp, %hi(_start - 256)
|
||||||
|
jalr $t0
|
||||||
addiu $sp, $sp, %lo(_start - 256)
|
addiu $sp, $sp, %lo(_start - 256)
|
||||||
|
|
||||||
move $a0, $s1
|
move $a0, $s1
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include <grub/pci.h>
|
#include <grub/pci.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/ata.h>
|
#include <grub/ata.h>
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
|
||||||
|
@ -217,26 +220,6 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev,
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump of GPIO connections. FIXME: Remove useless and macroify. */
|
|
||||||
static grub_uint32_t gpiodump[] = {
|
|
||||||
0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000,
|
|
||||||
0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000,
|
|
||||||
0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000,
|
|
||||||
0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000,
|
|
||||||
0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
|
|
||||||
0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000,
|
|
||||||
0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000,
|
|
||||||
0xefff1000, 0xefff1000, 0xffff0000, 0x00000000,
|
|
||||||
0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x50000000, 0x00000000, 0x00000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start,
|
set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start,
|
||||||
grub_uint16_t len)
|
grub_uint16_t len)
|
||||||
|
@ -277,17 +260,6 @@ set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start)
|
||||||
void
|
void
|
||||||
grub_cs5536_init_geode (grub_pci_device_t dev)
|
grub_cs5536_init_geode (grub_pci_device_t dev)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Make sure GPIO is where we expect it to be. */
|
|
||||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR,
|
|
||||||
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO);
|
|
||||||
|
|
||||||
/* Setup GPIO. */
|
|
||||||
for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++)
|
|
||||||
((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE
|
|
||||||
+ GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i];
|
|
||||||
|
|
||||||
/* Enable more BARs. */
|
/* Enable more BARs. */
|
||||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR,
|
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR,
|
||||||
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP);
|
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP);
|
||||||
|
@ -299,11 +271,27 @@ grub_cs5536_init_geode (grub_pci_device_t dev)
|
||||||
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM);
|
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM);
|
||||||
|
|
||||||
/* Setup DIVIL. */
|
/* Setup DIVIL. */
|
||||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO,
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
|
switch (grub_arch_machine)
|
||||||
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
|
{
|
||||||
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
|
case GRUB_ARCH_MACHINE_YEELOONG:
|
||||||
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
|
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO,
|
||||||
|
GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
|
||||||
|
break;
|
||||||
|
case GRUB_ARCH_MACHINE_FULOONG:
|
||||||
|
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO,
|
||||||
|
GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
|
||||||
|
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK,
|
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK,
|
||||||
(~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff);
|
(~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff);
|
||||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK,
|
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK,
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/pci.h>
|
#include <grub/pci.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm_private.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -28,17 +31,28 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
struct grub_pci_dma_chunk *
|
struct grub_pci_dma_chunk *
|
||||||
grub_memalign_dma32 (grub_size_t align, grub_size_t size)
|
grub_memalign_dma32 (grub_size_t align, grub_size_t size)
|
||||||
{
|
{
|
||||||
return grub_memalign (align, size);
|
void *ret;
|
||||||
|
if (align < 64)
|
||||||
|
align = 64;
|
||||||
|
size = ALIGN_UP (size, align);
|
||||||
|
ret = grub_memalign (align, size);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
grub_arch_sync_dma_caches (ret, size);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: evil. */
|
||||||
void
|
void
|
||||||
grub_dma_free (struct grub_pci_dma_chunk *ch)
|
grub_dma_free (struct grub_pci_dma_chunk *ch)
|
||||||
{
|
{
|
||||||
|
grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN;
|
||||||
|
grub_arch_sync_dma_caches (ch, size);
|
||||||
grub_free (ch);
|
grub_free (ch);
|
||||||
}
|
}
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
volatile void *
|
volatile void *
|
||||||
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
|
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
|
||||||
{
|
{
|
||||||
|
@ -101,13 +115,13 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
/* Skip ghosts. */
|
/* Skip ghosts. */
|
||||||
if (id == GRUB_YEELOONG_OHCI_PCIID
|
if (id == GRUB_LOONGSON_OHCI_PCIID
|
||||||
&& dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION)
|
&& dev.function == GRUB_LOONGSON_OHCI_GHOST_FUNCTION)
|
||||||
continue;
|
continue;
|
||||||
if (id == GRUB_YEELOONG_EHCI_PCIID
|
if (id == GRUB_LOONGSON_EHCI_PCIID
|
||||||
&& dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION)
|
&& dev.function == GRUB_LOONGSON_EHCI_GHOST_FUNCTION)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,12 @@ grub_usb_device_initialize (grub_usb_device_t dev)
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
dev->config[i].descconf = NULL;
|
dev->config[i].descconf = NULL;
|
||||||
|
|
||||||
|
if (descdev->configcnt == 0)
|
||||||
|
{
|
||||||
|
err = GRUB_USB_ERR_BADDEVICE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < descdev->configcnt; i++)
|
for (i = 0; i < descdev->configcnt; i++)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
|
|
|
@ -215,6 +215,8 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
|
||||||
return;
|
return;
|
||||||
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
|
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
|
||||||
|
|
||||||
|
grub_millisleep (10);
|
||||||
|
|
||||||
/* Enable the port and create a device. */
|
/* Enable the port and create a device. */
|
||||||
dev = grub_usb_hub_add_dev (hub->controller, speed);
|
dev = grub_usb_hub_add_dev (hub->controller, speed);
|
||||||
hub->controller->dev->pending_reset = 0;
|
hub->controller->dev->pending_reset = 0;
|
||||||
|
@ -350,8 +352,8 @@ poll_nonroot_hub (grub_usb_device_t dev)
|
||||||
GRUB_USB_REQ_GET_STATUS,
|
GRUB_USB_REQ_GET_STATUS,
|
||||||
0, i, sizeof (status), (char *) &status);
|
0, i, sizeof (status), (char *) &status);
|
||||||
|
|
||||||
grub_printf ("dev = %p, i = %d, status = %08x\n",
|
grub_dprintf ("usb", "dev = %p, i = %d, status = %08x\n",
|
||||||
dev, i, status);
|
dev, i, status);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
continue;
|
continue;
|
||||||
|
|
53
grub-core/commands/arc/lsdev.c
Normal file
53
grub-core/commands/arc/lsdev.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2011 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/dl.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/arc/arc.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc __attribute__ ((unused)),
|
||||||
|
char **args __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
auto int hook (const char *name, const struct grub_arc_component *comp);
|
||||||
|
int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
grub_printf ("%s\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
grub_arc_iterate_devs (hook, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_command_t cmd;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(lsdev)
|
||||||
|
{
|
||||||
|
cmd = grub_register_command ("lsdev", grub_cmd_lsdev, "",
|
||||||
|
N_("List devices."));
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(lsdev)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd);
|
||||||
|
}
|
|
@ -151,11 +151,12 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||||
|
|
||||||
if (units)
|
if (units)
|
||||||
{
|
{
|
||||||
grub_uint32_t whole, fraction;
|
grub_uint64_t whole, fraction;
|
||||||
|
|
||||||
whole = grub_divmod64 (fsize, 100, &fraction);
|
whole = grub_divmod64 (fsize, 100, &fraction);
|
||||||
grub_snprintf (buf, sizeof (buf),
|
grub_snprintf (buf, sizeof (buf),
|
||||||
"%u.%02u%c", whole, fraction,
|
"%" PRIuGRUB_UINT64_T
|
||||||
|
".%02" PRIuGRUB_UINT64_T "%c", whole, fraction,
|
||||||
grub_human_sizes[units]);
|
grub_human_sizes[units]);
|
||||||
grub_printf ("%-12s", buf);
|
grub_printf ("%-12s", buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
|
||||||
if (! menu_sourcecode)
|
if (! menu_sourcecode)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (classes)
|
if (classes && classes[0])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; classes[i]; i++); /* count # of menuentry classes */
|
for (i = 0; classes[i]; i++); /* count # of menuentry classes */
|
||||||
|
@ -255,7 +255,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
|
||||||
if (! ctxt->script)
|
if (! ctxt->script)
|
||||||
return grub_normal_add_menu_entry (argc, (const char **) args,
|
return grub_normal_add_menu_entry (argc, (const char **) args,
|
||||||
ctxt->state[0].args, ctxt->state[1].arg,
|
(ctxt->state[0].set ? ctxt->state[0].args
|
||||||
|
: NULL), ctxt->state[1].arg,
|
||||||
ctxt->state[2].arg, 0,
|
ctxt->state[2].arg, 0,
|
||||||
ctxt->state[3].arg,
|
ctxt->state[3].arg,
|
||||||
ctxt->extcmd->cmd->name[0] == 's');
|
ctxt->extcmd->cmd->name[0] == 's');
|
||||||
|
|
295
grub-core/disk/arc/arcdisk.c
Normal file
295
grub-core/disk/arc/arcdisk.c
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
/* ofdisk.c - Open Firmware disk access. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2004,2006,2007,2008,2009,2011 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/misc.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/arc/arc.h>
|
||||||
|
|
||||||
|
static grub_arc_fileno_t last_handle = 0;
|
||||||
|
static char *last_path = NULL;
|
||||||
|
|
||||||
|
static int lnum = 0;
|
||||||
|
|
||||||
|
struct arcdisk_hash_ent
|
||||||
|
{
|
||||||
|
char *devpath;
|
||||||
|
int num;
|
||||||
|
struct arcdisk_hash_ent *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ARCDISK_HASH_SZ 8
|
||||||
|
static struct arcdisk_hash_ent *arcdisk_hash[ARCDISK_HASH_SZ];
|
||||||
|
|
||||||
|
static int
|
||||||
|
arcdisk_hash_fn (const char *devpath)
|
||||||
|
{
|
||||||
|
int hash = 0;
|
||||||
|
while (*devpath)
|
||||||
|
hash ^= *devpath++;
|
||||||
|
return (hash & (ARCDISK_HASH_SZ - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct arcdisk_hash_ent *
|
||||||
|
arcdisk_hash_find (const char *devpath)
|
||||||
|
{
|
||||||
|
struct arcdisk_hash_ent *p = arcdisk_hash[arcdisk_hash_fn (devpath)];
|
||||||
|
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
if (!grub_strcmp (p->devpath, devpath))
|
||||||
|
break;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct arcdisk_hash_ent *
|
||||||
|
arcdisk_hash_add (char *devpath)
|
||||||
|
{
|
||||||
|
struct arcdisk_hash_ent *p;
|
||||||
|
struct arcdisk_hash_ent **head = &arcdisk_hash[arcdisk_hash_fn(devpath)];
|
||||||
|
|
||||||
|
p = grub_malloc (sizeof (*p));
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p->devpath = devpath;
|
||||||
|
p->next = *head;
|
||||||
|
p->num = lnum++;
|
||||||
|
*head = p;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_arcdisk_iterate (int (*hook_in) (const char *name))
|
||||||
|
{
|
||||||
|
auto int hook (const char *name, const struct grub_arc_component *comp);
|
||||||
|
int hook (const char *name, const struct grub_arc_component *comp)
|
||||||
|
{
|
||||||
|
if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|
||||||
|
|| comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
|
||||||
|
|| comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
|
||||||
|
return 0;
|
||||||
|
return hook_in (name);
|
||||||
|
}
|
||||||
|
return grub_arc_iterate_devs (hook, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RAW_SUFFIX "partition(10)"
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
reopen (const char *name)
|
||||||
|
{
|
||||||
|
grub_arc_fileno_t handle;
|
||||||
|
|
||||||
|
if (last_path && grub_strcmp (last_path, name) == 0)
|
||||||
|
{
|
||||||
|
grub_dprintf ("arcdisk", "using already opened %s\n", name);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
if (last_path)
|
||||||
|
{
|
||||||
|
GRUB_ARC_FIRMWARE_VECTOR->close (last_handle);
|
||||||
|
grub_free (last_path);
|
||||||
|
last_path = NULL;
|
||||||
|
last_handle = 0;
|
||||||
|
}
|
||||||
|
if (GRUB_ARC_FIRMWARE_VECTOR->open (name, 0, &handle))
|
||||||
|
{
|
||||||
|
grub_dprintf ("arcdisk", "couldn't open %s\n", name);
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't open %s", name);
|
||||||
|
}
|
||||||
|
last_path = grub_strdup (name);
|
||||||
|
if (!last_path)
|
||||||
|
return grub_errno;
|
||||||
|
last_handle = handle;
|
||||||
|
grub_dprintf ("arcdisk", "opened %s\n", name);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_arcdisk_open (const char *name, grub_disk_t disk)
|
||||||
|
{
|
||||||
|
char *fullname, *optr;
|
||||||
|
const char *iptr;
|
||||||
|
int state = 0;
|
||||||
|
grub_err_t err;
|
||||||
|
grub_arc_err_t r;
|
||||||
|
struct grub_arc_fileinfo info;
|
||||||
|
struct arcdisk_hash_ent *hash;
|
||||||
|
|
||||||
|
if (grub_memcmp (name, "arc/", 4) != 0)
|
||||||
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device");
|
||||||
|
fullname = grub_malloc (2 * grub_strlen (name) + sizeof (RAW_SUFFIX));
|
||||||
|
if (!fullname)
|
||||||
|
return grub_errno;
|
||||||
|
optr = fullname;
|
||||||
|
for (iptr = name + 4; *iptr; iptr++)
|
||||||
|
if (state == 0)
|
||||||
|
{
|
||||||
|
if (!grub_isdigit (*iptr))
|
||||||
|
*optr++ = *iptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*optr++ = '(';
|
||||||
|
*optr++ = *iptr;
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (grub_isdigit (*iptr))
|
||||||
|
*optr++ = *iptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*optr++ = ')';
|
||||||
|
state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state)
|
||||||
|
*optr++ = ')';
|
||||||
|
grub_memcpy (optr, RAW_SUFFIX, sizeof (RAW_SUFFIX));
|
||||||
|
disk->data = fullname;
|
||||||
|
grub_dprintf ("arcdisk", "opening %s\n", fullname);
|
||||||
|
|
||||||
|
hash = arcdisk_hash_find (fullname);
|
||||||
|
if (!hash)
|
||||||
|
hash = arcdisk_hash_add (fullname);
|
||||||
|
if (!hash)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
err = reopen (fullname);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (last_handle, &info);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
grub_uint64_t res = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
grub_dprintf ("arcdisk", "couldn't retrieve size: %ld\n", r);
|
||||||
|
for (i = 40; i >= 9; i--)
|
||||||
|
{
|
||||||
|
grub_uint64_t pos = res | (1ULL << i);
|
||||||
|
char buf[512];
|
||||||
|
long unsigned count = 0;
|
||||||
|
grub_dprintf ("arcdisk",
|
||||||
|
"seek to 0x%" PRIxGRUB_UINT64_T "\n", pos);
|
||||||
|
if (GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0))
|
||||||
|
continue;
|
||||||
|
if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf,
|
||||||
|
0x200, &count))
|
||||||
|
continue;
|
||||||
|
if (count == 0)
|
||||||
|
continue;
|
||||||
|
res |= (1ULL << i);
|
||||||
|
}
|
||||||
|
grub_dprintf ("arcdisk",
|
||||||
|
"determined disk size 0x%" PRIxGRUB_UINT64_T "\n", res);
|
||||||
|
disk->total_sectors = (res + 0x200) >> 9;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
disk->total_sectors = (info.end >> 9);
|
||||||
|
|
||||||
|
disk->id = hash->num;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_arcdisk_close (grub_disk_t disk)
|
||||||
|
{
|
||||||
|
grub_free (disk->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_size_t size, char *buf)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_uint64_t pos = sector << 9;
|
||||||
|
unsigned long count;
|
||||||
|
grub_uint64_t totl = size << 9;
|
||||||
|
grub_arc_err_t r;
|
||||||
|
|
||||||
|
err = reopen (disk->data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %ld\n",
|
||||||
|
pos, r);
|
||||||
|
return grub_error (GRUB_ERR_IO, "couldn't seek");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (totl)
|
||||||
|
{
|
||||||
|
if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf,
|
||||||
|
totl, &count))
|
||||||
|
return grub_error (GRUB_ERR_READ_ERROR, "read failed");
|
||||||
|
totl -= count;
|
||||||
|
buf += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_arcdisk_write (grub_disk_t disk __attribute ((unused)),
|
||||||
|
grub_disk_addr_t sector __attribute ((unused)),
|
||||||
|
grub_size_t size __attribute ((unused)),
|
||||||
|
const char *buf __attribute ((unused)))
|
||||||
|
{
|
||||||
|
return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_disk_dev grub_arcdisk_dev =
|
||||||
|
{
|
||||||
|
.name = "arcdisk",
|
||||||
|
.id = GRUB_DISK_DEVICE_ARCDISK_ID,
|
||||||
|
.iterate = grub_arcdisk_iterate,
|
||||||
|
.open = grub_arcdisk_open,
|
||||||
|
.close = grub_arcdisk_close,
|
||||||
|
.read = grub_arcdisk_read,
|
||||||
|
.write = grub_arcdisk_write,
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_arcdisk_init (void)
|
||||||
|
{
|
||||||
|
grub_disk_dev_register (&grub_arcdisk_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_arcdisk_fini (void)
|
||||||
|
{
|
||||||
|
if (last_path)
|
||||||
|
{
|
||||||
|
GRUB_ARC_FIRMWARE_VECTOR->close (last_handle);
|
||||||
|
grub_free (last_path);
|
||||||
|
last_path = NULL;
|
||||||
|
last_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_disk_dev_unregister (&grub_arcdisk_dev);
|
||||||
|
}
|
|
@ -22,9 +22,13 @@
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
#include <grub/pci.h>
|
#include <grub/pci.h>
|
||||||
#include <grub/scsi.h>
|
|
||||||
#include <grub/cs5536.h>
|
#include <grub/cs5536.h>
|
||||||
|
#else
|
||||||
|
#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000
|
||||||
|
#endif
|
||||||
|
#include <grub/scsi.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -160,18 +164,23 @@ grub_atapi_identify (struct grub_ata_device *dev)
|
||||||
|
|
||||||
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
|
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
|
||||||
grub_ata_wait ();
|
grub_ata_wait ();
|
||||||
if (grub_ata_check_ready (dev))
|
if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
|
||||||
|
&& grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT
|
||||||
|
: GRUB_ATA_TOUT_STD))
|
||||||
{
|
{
|
||||||
grub_free (info);
|
grub_free (info);
|
||||||
|
dev->present = 0;
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
|
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
|
||||||
grub_ata_wait ();
|
grub_ata_wait ();
|
||||||
|
|
||||||
if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
|
if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT
|
||||||
|
: GRUB_ATA_TOUT_STD))
|
||||||
{
|
{
|
||||||
grub_free (info);
|
grub_free (info);
|
||||||
|
dev->present = 0;
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
|
grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
|
||||||
|
@ -258,8 +267,11 @@ grub_ata_identify (struct grub_ata_device *dev)
|
||||||
|
|
||||||
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
|
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
|
||||||
grub_ata_wait ();
|
grub_ata_wait ();
|
||||||
if (grub_ata_check_ready (dev))
|
if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
|
||||||
|
&& grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT
|
||||||
|
: GRUB_ATA_TOUT_STD))
|
||||||
{
|
{
|
||||||
|
dev->present = 0;
|
||||||
grub_free (info);
|
grub_free (info);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +279,8 @@ grub_ata_identify (struct grub_ata_device *dev)
|
||||||
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
|
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
|
||||||
grub_ata_wait ();
|
grub_ata_wait ();
|
||||||
|
|
||||||
if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
|
if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT
|
||||||
|
: GRUB_ATA_TOUT_STD))
|
||||||
{
|
{
|
||||||
grub_free (info);
|
grub_free (info);
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -280,13 +293,18 @@ grub_ata_identify (struct grub_ata_device *dev)
|
||||||
return grub_atapi_identify (dev);
|
return grub_atapi_identify (dev);
|
||||||
|
|
||||||
else if (sts == 0x00)
|
else if (sts == 0x00)
|
||||||
/* No device, return error but don't print message. */
|
{
|
||||||
return GRUB_ERR_UNKNOWN_DEVICE;
|
dev->present = 0;
|
||||||
|
/* No device, return error but don't print message. */
|
||||||
|
return GRUB_ERR_UNKNOWN_DEVICE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* Other Error. */
|
{
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
dev->present = 0;
|
||||||
"device cannot be identified");
|
/* Other Error. */
|
||||||
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||||
|
"device cannot be identified");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
|
grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
|
||||||
|
@ -381,6 +399,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
|
||||||
dev->device = device;
|
dev->device = device;
|
||||||
dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
|
dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
|
||||||
dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
|
dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
|
||||||
|
dev->present = 1;
|
||||||
dev->next = NULL;
|
dev->next = NULL;
|
||||||
|
|
||||||
/* Register the device. */
|
/* Register the device. */
|
||||||
|
@ -394,6 +413,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
static int NESTED_FUNC_ATTR
|
static int NESTED_FUNC_ATTR
|
||||||
grub_ata_pciinit (grub_pci_device_t dev,
|
grub_ata_pciinit (grub_pci_device_t dev,
|
||||||
grub_pci_id_t pciid)
|
grub_pci_id_t pciid)
|
||||||
|
@ -509,6 +529,21 @@ grub_ata_initialize (void)
|
||||||
grub_pci_iterate (grub_ata_pciinit);
|
grub_pci_iterate (grub_ata_pciinit);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static grub_err_t
|
||||||
|
grub_ata_initialize (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
grub_ata_device_initialize (i, 0, grub_ata_ioaddress[i],
|
||||||
|
grub_ata_ioaddress2[i]);
|
||||||
|
grub_ata_device_initialize (i, 1, grub_ata_ioaddress[i],
|
||||||
|
grub_ata_ioaddress2[i]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
|
grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
|
||||||
|
|
|
@ -506,7 +506,7 @@ static grub_size_t
|
||||||
get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
|
get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
|
||||||
{
|
{
|
||||||
grub_size_t size;
|
grub_size_t size;
|
||||||
grub_uint32_t offset;
|
grub_uint64_t offset;
|
||||||
|
|
||||||
/* OFFSET = SECTOR % SECTORS */
|
/* OFFSET = SECTOR % SECTORS */
|
||||||
grub_divmod64 (sector, sectors, &offset);
|
grub_divmod64 (sector, sectors, &offset);
|
||||||
|
|
|
@ -247,9 +247,9 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector,
|
||||||
/* This is a striped segment. We have to find the right PV
|
/* This is a striped segment. We have to find the right PV
|
||||||
similar to RAID0. */
|
similar to RAID0. */
|
||||||
struct grub_lvm_node *stripe = seg->nodes;
|
struct grub_lvm_node *stripe = seg->nodes;
|
||||||
grub_uint32_t a, b;
|
grub_uint64_t a, b;
|
||||||
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */
|
grub_uint64_t seg_offset; /* Offset of the segment in PV device. */
|
||||||
unsigned int stripenr;
|
grub_uint64_t stripenr;
|
||||||
|
|
||||||
offset = sector - ((grub_uint64_t) seg->start_extent
|
offset = sector - ((grub_uint64_t) seg->start_extent
|
||||||
* (grub_uint64_t) vg->extent_size);
|
* (grub_uint64_t) vg->extent_size);
|
||||||
|
|
|
@ -245,7 +245,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
case 10:
|
case 10:
|
||||||
{
|
{
|
||||||
grub_disk_addr_t read_sector, far_ofs;
|
grub_disk_addr_t read_sector, far_ofs;
|
||||||
grub_uint32_t disknr, b, near, far, ofs;
|
grub_uint64_t disknr, b, near, far, ofs;
|
||||||
|
|
||||||
read_sector = grub_divmod64 (sector, array->chunk_size, &b);
|
read_sector = grub_divmod64 (sector, array->chunk_size, &b);
|
||||||
far = ofs = near = 1;
|
far = ofs = near = 1;
|
||||||
|
@ -351,7 +351,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
case 6:
|
case 6:
|
||||||
{
|
{
|
||||||
grub_disk_addr_t read_sector;
|
grub_disk_addr_t read_sector;
|
||||||
grub_uint32_t b, p, n, disknr, e;
|
grub_uint64_t b, p, n, disknr, e;
|
||||||
|
|
||||||
/* n = 1 for level 4 and 5, 2 for level 6. */
|
/* n = 1 for level 4 and 5, 2 for level 6. */
|
||||||
n = array->level / 3;
|
n = array->level / 3;
|
||||||
|
|
|
@ -512,7 +512,7 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
"unsupported SCSI block size");
|
"unsupported SCSI block size");
|
||||||
|
|
||||||
grub_uint32_t sector_mod = 0;
|
grub_uint64_t sector_mod = 0;
|
||||||
sector = grub_divmod64 (sector, spb, §or_mod);
|
sector = grub_divmod64 (sector, spb, §or_mod);
|
||||||
|
|
||||||
if (! (sector_mod == 0 && size % spb == 0))
|
if (! (sector_mod == 0 && size % spb == 0))
|
||||||
|
|
|
@ -316,10 +316,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
||||||
return 1;
|
return 1;
|
||||||
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
||||||
if (!font->bmp_idx)
|
if (!font->bmp_idx)
|
||||||
{
|
return 1;
|
||||||
grub_free (font->char_index);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
|
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
|
||||||
|
|
||||||
|
|
||||||
|
@ -494,7 +491,7 @@ grub_font_load (const char *filename)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate the font object. */
|
/* Allocate the font object. */
|
||||||
font = (grub_font_t) grub_malloc (sizeof (struct grub_font));
|
font = (grub_font_t) grub_zalloc (sizeof (struct grub_font));
|
||||||
if (!font)
|
if (!font)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -640,6 +637,11 @@ grub_font_load (const char *filename)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
if (font)
|
||||||
|
font->file = 0;
|
||||||
|
|
||||||
free_font (font);
|
free_font (font);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -799,6 +801,7 @@ free_font (grub_font_t font)
|
||||||
grub_free (font->name);
|
grub_free (font->name);
|
||||||
grub_free (font->family);
|
grub_free (font->family);
|
||||||
grub_free (font->char_index);
|
grub_free (font->char_index);
|
||||||
|
grub_free (font->bmp_idx);
|
||||||
grub_free (font);
|
grub_free (font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,11 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
while (argc--)
|
while (argc--)
|
||||||
if (grub_font_load (*args++) != 0)
|
if (grub_font_load (*args++) != 0)
|
||||||
return GRUB_ERR_BAD_FONT;
|
{
|
||||||
|
if (!grub_errno)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FONT, "invalid font");
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,12 +52,20 @@ struct grub_affs_rblock
|
||||||
grub_uint32_t hashtable[1];
|
grub_uint32_t hashtable[1];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_affs_time
|
||||||
|
{
|
||||||
|
grub_int32_t day;
|
||||||
|
grub_uint32_t min;
|
||||||
|
grub_uint32_t hz;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* The second part of a file header block. */
|
/* The second part of a file header block. */
|
||||||
struct grub_affs_file
|
struct grub_affs_file
|
||||||
{
|
{
|
||||||
grub_uint8_t unused1[12];
|
grub_uint8_t unused1[12];
|
||||||
grub_uint32_t size;
|
grub_uint32_t size;
|
||||||
grub_uint8_t unused2[104];
|
grub_uint8_t unused2[92];
|
||||||
|
struct grub_affs_time mtime;
|
||||||
grub_uint8_t namelen;
|
grub_uint8_t namelen;
|
||||||
grub_uint8_t name[30];
|
grub_uint8_t name[30];
|
||||||
grub_uint8_t unused3[33];
|
grub_uint8_t unused3[33];
|
||||||
|
@ -87,9 +95,9 @@ struct grub_affs_file
|
||||||
struct grub_fshelp_node
|
struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_affs_data *data;
|
struct grub_affs_data *data;
|
||||||
int block;
|
grub_disk_addr_t block;
|
||||||
int size;
|
struct grub_fshelp_node *parent;
|
||||||
int parent;
|
struct grub_affs_file di;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about a "mounted" affs filesystem. */
|
/* Information about a "mounted" affs filesystem. */
|
||||||
|
@ -117,7 +125,7 @@ grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
int block = node->block;
|
int block = node->block;
|
||||||
struct grub_affs_file file;
|
struct grub_affs_file file;
|
||||||
struct grub_affs_data *data = node->data;
|
struct grub_affs_data *data = node->data;
|
||||||
grub_uint32_t mod;
|
grub_uint64_t mod;
|
||||||
|
|
||||||
/* Find the block that points to the fileblock we are looking up by
|
/* Find the block that points to the fileblock we are looking up by
|
||||||
following the chain until the right table is reached. */
|
following the chain until the right table is reached. */
|
||||||
|
@ -156,7 +164,7 @@ grub_affs_read_file (grub_fshelp_node_t node,
|
||||||
{
|
{
|
||||||
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
return grub_fshelp_read_file (node->data->disk, node, read_hook,
|
||||||
pos, len, buf, grub_affs_read_block,
|
pos, len, buf, grub_affs_read_block,
|
||||||
node->size, 0);
|
grub_be_to_cpu32 (node->di.size), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,7 +176,6 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
struct grub_affs_rblock *rblock;
|
struct grub_affs_rblock *rblock;
|
||||||
|
|
||||||
int checksum = 0;
|
int checksum = 0;
|
||||||
int checksumr = 0;
|
|
||||||
int blocksize = 0;
|
int blocksize = 0;
|
||||||
|
|
||||||
data = grub_malloc (sizeof (struct grub_affs_data));
|
data = grub_malloc (sizeof (struct grub_affs_data));
|
||||||
|
@ -218,8 +225,6 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
/* The filesystem blocksize is not stored anywhere in the filesystem
|
/* The filesystem blocksize is not stored anywhere in the filesystem
|
||||||
itself. One way to determine it is reading blocks for the
|
itself. One way to determine it is reading blocks for the
|
||||||
rootblock until the checksum is correct. */
|
rootblock until the checksum is correct. */
|
||||||
checksumr = grub_be_to_cpu32 (rblock->checksum);
|
|
||||||
rblock->checksum = 0;
|
|
||||||
for (blocksize = 0; blocksize < 8; blocksize++)
|
for (blocksize = 0; blocksize < 8; blocksize++)
|
||||||
{
|
{
|
||||||
grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
|
grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
|
||||||
|
@ -228,10 +233,10 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
|
for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
|
||||||
checksum += grub_be_to_cpu32 (currblock[i]);
|
checksum += grub_be_to_cpu32 (currblock[i]);
|
||||||
|
|
||||||
if (checksumr == -checksum)
|
if (checksum == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (-checksum != checksumr)
|
if (checksum != 0)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
|
grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -243,6 +248,8 @@ grub_affs_mount (grub_disk_t disk)
|
||||||
data->htsize = grub_be_to_cpu32 (rblock->htsize);
|
data->htsize = grub_be_to_cpu32 (rblock->htsize);
|
||||||
data->diropen.data = data;
|
data->diropen.data = data;
|
||||||
data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
|
data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
|
||||||
|
data->diropen.parent = NULL;
|
||||||
|
grub_memcpy (&data->diropen.di, rootblock, sizeof (data->diropen.di));
|
||||||
|
|
||||||
grub_free (rootblock);
|
grub_free (rootblock);
|
||||||
|
|
||||||
|
@ -293,12 +300,15 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
struct grub_affs_data *data = dir->data;
|
struct grub_affs_data *data = dir->data;
|
||||||
grub_uint32_t *hashtable;
|
grub_uint32_t *hashtable;
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
|
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
|
||||||
int size, int type);
|
grub_disk_addr_t block,
|
||||||
|
const struct grub_affs_file *fil);
|
||||||
|
|
||||||
int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
|
int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
|
||||||
int size, int type)
|
grub_disk_addr_t block,
|
||||||
|
const struct grub_affs_file *fil)
|
||||||
{
|
{
|
||||||
|
int type;
|
||||||
node = grub_malloc (sizeof (*node));
|
node = grub_malloc (sizeof (*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
|
@ -306,10 +316,19 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR)
|
||||||
|
type = GRUB_FSHELP_REG;
|
||||||
|
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG)
|
||||||
|
type = GRUB_FSHELP_DIR;
|
||||||
|
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK)
|
||||||
|
type = GRUB_FSHELP_SYMLINK;
|
||||||
|
else
|
||||||
|
type = GRUB_FSHELP_UNKNOWN;
|
||||||
|
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->size = size;
|
|
||||||
node->block = block;
|
node->block = block;
|
||||||
node->parent = grub_be_to_cpu32 (file.parent);
|
node->di = *fil;
|
||||||
|
node->parent = dir;
|
||||||
|
|
||||||
if (hook (name, type, node))
|
if (hook (name, type, node))
|
||||||
{
|
{
|
||||||
|
@ -319,6 +338,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create the directory entries for `.' and `..'. */
|
||||||
|
node = grub_malloc (sizeof (*node));
|
||||||
|
if (!node)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
*node = *dir;
|
||||||
|
if (hook (".", GRUB_FSHELP_DIR, node))
|
||||||
|
return 1;
|
||||||
|
if (dir->parent)
|
||||||
|
{
|
||||||
|
node = grub_malloc (sizeof (*node));
|
||||||
|
if (!node)
|
||||||
|
return 1;
|
||||||
|
*node = *dir->parent;
|
||||||
|
if (hook ("..", GRUB_FSHELP_DIR, node))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
|
hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
|
||||||
if (!hashtable)
|
if (!hashtable)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -328,16 +365,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Create the directory entries for `.' and `..'. */
|
|
||||||
if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
|
|
||||||
return 1;
|
|
||||||
if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
|
|
||||||
dir->size, GRUB_FSHELP_DIR))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (i = 0; i < data->htsize; i++)
|
for (i = 0; i < data->htsize; i++)
|
||||||
{
|
{
|
||||||
enum grub_fshelp_filetype type;
|
|
||||||
grub_uint64_t next;
|
grub_uint64_t next;
|
||||||
|
|
||||||
if (!hashtable[i])
|
if (!hashtable[i])
|
||||||
|
@ -358,17 +387,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
file.name[file.namelen] = '\0';
|
file.name[file.namelen] = '\0';
|
||||||
|
|
||||||
if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
|
if (grub_affs_create_node ((char *) (file.name), next, &file))
|
||||||
type = GRUB_FSHELP_REG;
|
|
||||||
else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
|
|
||||||
type = GRUB_FSHELP_DIR;
|
|
||||||
else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
|
|
||||||
type = GRUB_FSHELP_SYMLINK;
|
|
||||||
else
|
|
||||||
type = GRUB_FSHELP_UNKNOWN;
|
|
||||||
|
|
||||||
if (grub_affs_create_node ((char *) (file.name), next,
|
|
||||||
grub_be_to_cpu32 (file.size), type))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
next = grub_be_to_cpu32 (file.next);
|
next = grub_be_to_cpu32 (file.next);
|
||||||
|
@ -403,7 +422,7 @@ grub_affs_open (struct grub_file *file, const char *name)
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
file->size = fdiro->size;
|
file->size = grub_be_to_cpu32 (fdiro->di.size);
|
||||||
data->diropen = *fdiro;
|
data->diropen = *fdiro;
|
||||||
grub_free (fdiro);
|
grub_free (fdiro);
|
||||||
|
|
||||||
|
@ -467,6 +486,11 @@ grub_affs_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_be_to_cpu32 (node->di.mtime.day) * 86400
|
||||||
|
+ grub_be_to_cpu32 (node->di.mtime.min) * 60
|
||||||
|
+ grub_be_to_cpu32 (node->di.mtime.hz) / 50
|
||||||
|
+ 8 * 365 * 86400 + 86400 * 2;
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -589,10 +589,14 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
struct grub_btrfs_key *key;
|
struct grub_btrfs_key *key;
|
||||||
struct grub_btrfs_chunk_item *chunk;
|
struct grub_btrfs_chunk_item *chunk;
|
||||||
grub_uint64_t csize;
|
grub_uint64_t csize;
|
||||||
grub_err_t err;
|
grub_err_t err = 0;
|
||||||
struct grub_btrfs_key key_out;
|
struct grub_btrfs_key key_out;
|
||||||
int challoc = 0;
|
int challoc = 0;
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
struct grub_btrfs_key key_in;
|
||||||
|
grub_size_t chsize;
|
||||||
|
grub_disk_addr_t chaddr;
|
||||||
|
|
||||||
grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n",
|
grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n",
|
||||||
addr);
|
addr);
|
||||||
for (ptr = data->sblock.bootstrap_mapping;
|
for (ptr = data->sblock.bootstrap_mapping;
|
||||||
|
@ -616,9 +620,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
+ sizeof (struct grub_btrfs_chunk_stripe)
|
+ sizeof (struct grub_btrfs_chunk_stripe)
|
||||||
* grub_le_to_cpu16 (chunk->nstripes);
|
* grub_le_to_cpu16 (chunk->nstripes);
|
||||||
}
|
}
|
||||||
struct grub_btrfs_key key_in;
|
|
||||||
grub_size_t chsize;
|
|
||||||
grub_disk_addr_t chaddr;
|
|
||||||
key_in.object_id = GRUB_BTRFS_OBJECT_ID_CHUNK;
|
key_in.object_id = GRUB_BTRFS_OBJECT_ID_CHUNK;
|
||||||
key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK;
|
key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK;
|
||||||
key_in.offset = addr;
|
key_in.offset = addr;
|
||||||
|
@ -647,7 +649,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
chunk_found:
|
chunk_found:
|
||||||
{
|
{
|
||||||
grub_uint32_t stripen;
|
grub_uint64_t stripen;
|
||||||
grub_uint64_t stripe_offset;
|
grub_uint64_t stripe_offset;
|
||||||
grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset);
|
grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset);
|
||||||
unsigned redundancy = 1;
|
unsigned redundancy = 1;
|
||||||
|
@ -677,10 +679,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
{
|
{
|
||||||
grub_uint64_t stripe_length;
|
grub_uint64_t stripe_length;
|
||||||
grub_dprintf ("btrfs", "single\n");
|
grub_dprintf ("btrfs", "single\n");
|
||||||
stripe_length = grub_divmod64_full (grub_le_to_cpu64 (chunk->size),
|
stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size),
|
||||||
grub_le_to_cpu16 (chunk->nstripes),
|
grub_le_to_cpu16 (chunk->nstripes),
|
||||||
NULL);
|
NULL);
|
||||||
stripen = grub_divmod64_full (off, stripe_length, &stripe_offset);
|
stripen = grub_divmod64 (off, stripe_length, &stripe_offset);
|
||||||
csize = (stripen + 1) * stripe_length - off;
|
csize = (stripen + 1) * stripe_length - off;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -697,7 +699,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
case GRUB_BTRFS_CHUNK_TYPE_RAID0:
|
case GRUB_BTRFS_CHUNK_TYPE_RAID0:
|
||||||
{
|
{
|
||||||
grub_uint64_t middle, high;
|
grub_uint64_t middle, high;
|
||||||
grub_uint32_t low;
|
grub_uint64_t low;
|
||||||
grub_dprintf ("btrfs", "RAID0\n");
|
grub_dprintf ("btrfs", "RAID0\n");
|
||||||
middle = grub_divmod64 (off,
|
middle = grub_divmod64 (off,
|
||||||
grub_le_to_cpu64 (chunk->stripe_length),
|
grub_le_to_cpu64 (chunk->stripe_length),
|
||||||
|
@ -713,7 +715,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
case GRUB_BTRFS_CHUNK_TYPE_RAID10:
|
case GRUB_BTRFS_CHUNK_TYPE_RAID10:
|
||||||
{
|
{
|
||||||
grub_uint64_t middle, high;
|
grub_uint64_t middle, high;
|
||||||
grub_uint32_t low;
|
grub_uint64_t low;
|
||||||
middle = grub_divmod64 (off,
|
middle = grub_divmod64 (off,
|
||||||
grub_le_to_cpu64 (chunk->stripe_length),
|
grub_le_to_cpu64 (chunk->stripe_length),
|
||||||
&low);
|
&low);
|
||||||
|
@ -758,7 +760,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||||
|
|
||||||
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
|
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
|
||||||
"+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %"
|
"+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %"
|
||||||
PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT32_T
|
PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T
|
||||||
" maps to 0x%" PRIxGRUB_UINT64_T "\n",
|
" maps to 0x%" PRIxGRUB_UINT64_T "\n",
|
||||||
grub_le_to_cpu64 (key->offset),
|
grub_le_to_cpu64 (key->offset),
|
||||||
grub_le_to_cpu64 (chunk->size),
|
grub_le_to_cpu64 (chunk->size),
|
||||||
|
|
|
@ -80,7 +80,7 @@ static grub_dl_t my_mod;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
||||||
grub_uint32_t * ofs)
|
grub_int32_t *mtime, grub_uint32_t * ofs)
|
||||||
{
|
{
|
||||||
#ifndef MODE_USTAR
|
#ifndef MODE_USTAR
|
||||||
struct head hd;
|
struct head hd;
|
||||||
|
@ -93,6 +93,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
|
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
|
||||||
|
|
||||||
data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
|
data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
|
||||||
|
if (mtime)
|
||||||
|
*mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2;
|
||||||
|
|
||||||
if (hd.namesize & 1)
|
if (hd.namesize & 1)
|
||||||
hd.namesize++;
|
hd.namesize++;
|
||||||
|
@ -141,6 +143,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
|
||||||
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
|
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
|
||||||
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
|
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
|
||||||
~(GRUB_DISK_SECTOR_SIZE - 1));
|
~(GRUB_DISK_SECTOR_SIZE - 1));
|
||||||
|
if (mtime)
|
||||||
|
*mtime = grub_strtoul (hd.mtime, NULL, 8);
|
||||||
#endif
|
#endif
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +210,9 @@ grub_cpio_dir (grub_device_t device, const char *path,
|
||||||
data->hofs = 0;
|
data->hofs = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (grub_cpio_find_file (data, &name, &ofs))
|
grub_int32_t mtime;
|
||||||
|
|
||||||
|
if (grub_cpio_find_file (data, &name, &mtime, &ofs))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!ofs)
|
if (!ofs)
|
||||||
|
@ -229,6 +235,8 @@ grub_cpio_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = (p != NULL);
|
info.dir = (p != NULL);
|
||||||
|
info.mtime = mtime;
|
||||||
|
info.mtimeset = 1;
|
||||||
|
|
||||||
hook (name + len, &info);
|
hook (name + len, &info);
|
||||||
if (prev)
|
if (prev)
|
||||||
|
@ -271,7 +279,7 @@ grub_cpio_open (grub_file_t file, const char *name)
|
||||||
data->hofs = 0;
|
data->hofs = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (grub_cpio_find_file (data, &fn, &ofs))
|
if (grub_cpio_find_file (data, &fn, NULL, &ofs))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!ofs)
|
if (!ofs)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/fat.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -51,52 +52,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
| GRUB_FAT_ATTR_ARCHIVE \
|
| GRUB_FAT_ATTR_ARCHIVE \
|
||||||
| GRUB_FAT_ATTR_VOLUME_ID)
|
| GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
|
|
||||||
struct grub_fat_bpb
|
|
||||||
{
|
|
||||||
grub_uint8_t jmp_boot[3];
|
|
||||||
grub_uint8_t oem_name[8];
|
|
||||||
grub_uint16_t bytes_per_sector;
|
|
||||||
grub_uint8_t sectors_per_cluster;
|
|
||||||
grub_uint16_t num_reserved_sectors;
|
|
||||||
grub_uint8_t num_fats;
|
|
||||||
grub_uint16_t num_root_entries;
|
|
||||||
grub_uint16_t num_total_sectors_16;
|
|
||||||
grub_uint8_t media;
|
|
||||||
grub_uint16_t sectors_per_fat_16;
|
|
||||||
grub_uint16_t sectors_per_track;
|
|
||||||
grub_uint16_t num_heads;
|
|
||||||
grub_uint32_t num_hidden_sectors;
|
|
||||||
grub_uint32_t num_total_sectors_32;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
grub_uint8_t num_ph_drive;
|
|
||||||
grub_uint8_t reserved;
|
|
||||||
grub_uint8_t boot_sig;
|
|
||||||
grub_uint32_t num_serial;
|
|
||||||
grub_uint8_t label[11];
|
|
||||||
grub_uint8_t fstype[8];
|
|
||||||
} __attribute__ ((packed)) fat12_or_fat16;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
grub_uint32_t sectors_per_fat_32;
|
|
||||||
grub_uint16_t extended_flags;
|
|
||||||
grub_uint16_t fs_version;
|
|
||||||
grub_uint32_t root_cluster;
|
|
||||||
grub_uint16_t fs_info;
|
|
||||||
grub_uint16_t backup_boot_sector;
|
|
||||||
grub_uint8_t reserved[12];
|
|
||||||
grub_uint8_t num_ph_drive;
|
|
||||||
grub_uint8_t reserved1;
|
|
||||||
grub_uint8_t boot_sig;
|
|
||||||
grub_uint32_t num_serial;
|
|
||||||
grub_uint8_t label[11];
|
|
||||||
grub_uint8_t fstype[8];
|
|
||||||
} __attribute__ ((packed)) fat32;
|
|
||||||
} __attribute__ ((packed)) version_specific;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct grub_fat_dir_entry
|
struct grub_fat_dir_entry
|
||||||
{
|
{
|
||||||
grub_uint8_t name[11];
|
grub_uint8_t name[11];
|
||||||
|
|
|
@ -133,6 +133,8 @@ struct grub_hfs_dirrec
|
||||||
grub_uint8_t type;
|
grub_uint8_t type;
|
||||||
grub_uint8_t unused[5];
|
grub_uint8_t unused[5];
|
||||||
grub_uint32_t dirid;
|
grub_uint32_t dirid;
|
||||||
|
grub_uint32_t ctime;
|
||||||
|
grub_uint32_t mtime;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Information about a file. */
|
/* Information about a file. */
|
||||||
|
@ -144,7 +146,9 @@ struct grub_hfs_filerec
|
||||||
grub_uint32_t fileid;
|
grub_uint32_t fileid;
|
||||||
grub_uint8_t unused2[2];
|
grub_uint8_t unused2[2];
|
||||||
grub_uint32_t size;
|
grub_uint32_t size;
|
||||||
grub_uint8_t unused3[44];
|
grub_uint8_t unused3[18];
|
||||||
|
grub_uint32_t mtime;
|
||||||
|
grub_uint8_t unused4[22];
|
||||||
|
|
||||||
/* The first 3 extents of the file. The other extents can be found
|
/* The first 3 extents of the file. The other extents can be found
|
||||||
in the extent overflow file. */
|
in the extent overflow file. */
|
||||||
|
@ -953,19 +957,29 @@ grub_hfs_dir (grub_device_t device, const char *path,
|
||||||
int dir_hook (struct grub_hfs_record *rec)
|
int dir_hook (struct grub_hfs_record *rec)
|
||||||
{
|
{
|
||||||
char fname[32] = { 0 };
|
char fname[32] = { 0 };
|
||||||
char *filetype = rec->data;
|
struct grub_hfs_dirrec *drec = rec->data;
|
||||||
|
struct grub_hfs_filerec *frec = rec->data;
|
||||||
struct grub_hfs_catalog_key *ckey = rec->key;
|
struct grub_hfs_catalog_key *ckey = rec->key;
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
|
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
|
||||||
|
|
||||||
if (*filetype == GRUB_HFS_FILETYPE_DIR
|
if (drec->type == GRUB_HFS_FILETYPE_DIR)
|
||||||
|| *filetype == GRUB_HFS_FILETYPE_FILE)
|
|
||||||
{
|
{
|
||||||
info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
|
info.dir = 1;
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
|
||||||
return hook (fname, &info);
|
return hook (fname, &info);
|
||||||
}
|
}
|
||||||
|
if (frec->type == GRUB_HFS_FILETYPE_FILE)
|
||||||
|
{
|
||||||
|
info.dir = 0;
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
|
||||||
|
return hook (fname, &info);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,6 +1088,22 @@ grub_hfs_label (grub_device_t device, char **label)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
|
||||||
|
{
|
||||||
|
struct grub_hfs_data *data;
|
||||||
|
|
||||||
|
data = grub_hfs_mount (device->disk);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800;
|
||||||
|
else
|
||||||
|
*tm = 0;
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfs_uuid (grub_device_t device, char **uuid)
|
grub_hfs_uuid (grub_device_t device, char **uuid)
|
||||||
{
|
{
|
||||||
|
@ -1109,6 +1139,7 @@ static struct grub_fs grub_hfs_fs =
|
||||||
.close = grub_hfs_close,
|
.close = grub_hfs_close,
|
||||||
.label = grub_hfs_label,
|
.label = grub_hfs_label,
|
||||||
.uuid = grub_hfs_uuid,
|
.uuid = grub_hfs_uuid,
|
||||||
|
.mtime = grub_hfs_mtime,
|
||||||
.next = 0
|
.next = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/datetime.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -55,6 +56,17 @@ struct grub_iso9660_voldesc
|
||||||
grub_uint8_t version;
|
grub_uint8_t version;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_iso9660_date2
|
||||||
|
{
|
||||||
|
grub_uint8_t year;
|
||||||
|
grub_uint8_t month;
|
||||||
|
grub_uint8_t day;
|
||||||
|
grub_uint8_t hour;
|
||||||
|
grub_uint8_t minute;
|
||||||
|
grub_uint8_t second;
|
||||||
|
grub_uint8_t offset;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* A directory entry. */
|
/* A directory entry. */
|
||||||
struct grub_iso9660_dir
|
struct grub_iso9660_dir
|
||||||
{
|
{
|
||||||
|
@ -64,7 +76,7 @@ struct grub_iso9660_dir
|
||||||
grub_uint32_t first_sector_be;
|
grub_uint32_t first_sector_be;
|
||||||
grub_uint32_t size;
|
grub_uint32_t size;
|
||||||
grub_uint32_t size_be;
|
grub_uint32_t size_be;
|
||||||
grub_uint8_t unused1[7];
|
struct grub_iso9660_date2 mtime;
|
||||||
grub_uint8_t flags;
|
grub_uint8_t flags;
|
||||||
grub_uint8_t unused2[6];
|
grub_uint8_t unused2[6];
|
||||||
grub_uint8_t namelen;
|
grub_uint8_t namelen;
|
||||||
|
@ -146,6 +158,7 @@ struct grub_iso9660_data
|
||||||
struct grub_fshelp_node
|
struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_iso9660_data *data;
|
struct grub_iso9660_data *data;
|
||||||
|
struct grub_iso9660_dir dirent;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
unsigned int blk;
|
unsigned int blk;
|
||||||
unsigned int dir_blk;
|
unsigned int dir_blk;
|
||||||
|
@ -155,6 +168,52 @@ struct grub_fshelp_node
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
|
||||||
|
{
|
||||||
|
struct grub_datetime datetime;
|
||||||
|
|
||||||
|
if (! i->year[0] && ! i->year[1]
|
||||||
|
&& ! i->year[2] && ! i->year[3]
|
||||||
|
&& ! i->month[0] && ! i->month[1]
|
||||||
|
&& ! i->day[0] && ! i->day[1]
|
||||||
|
&& ! i->hour[0] && ! i->hour[1]
|
||||||
|
&& ! i->minute[0] && ! i->minute[1]
|
||||||
|
&& ! i->second[0] && ! i->second[1]
|
||||||
|
&& ! i->hundredth[0] && ! i->hundredth[1])
|
||||||
|
return grub_error (GRUB_ERR_BAD_NUMBER, "empty date");
|
||||||
|
datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100
|
||||||
|
+ (i->year[2] - '0') * 10 + (i->year[3] - '0');
|
||||||
|
datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0');
|
||||||
|
datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0');
|
||||||
|
datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0');
|
||||||
|
datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0');
|
||||||
|
datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0');
|
||||||
|
|
||||||
|
if (!grub_datetime2unixtime (&datetime, nix))
|
||||||
|
return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date");
|
||||||
|
*nix -= i->offset * 60 * 15;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
|
||||||
|
{
|
||||||
|
struct grub_datetime datetime;
|
||||||
|
|
||||||
|
datetime.year = i->year + 1900;
|
||||||
|
datetime.month = i->month;
|
||||||
|
datetime.day = i->day;
|
||||||
|
datetime.hour = i->hour;
|
||||||
|
datetime.minute = i->minute;
|
||||||
|
datetime.second = i->second;
|
||||||
|
|
||||||
|
if (!grub_datetime2unixtime (&datetime, nix))
|
||||||
|
return 0;
|
||||||
|
*nix -= i->offset * 60 * 15;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
|
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
|
||||||
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
|
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
|
||||||
every entry. */
|
every entry. */
|
||||||
|
@ -366,7 +425,6 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
static char *
|
static char *
|
||||||
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
struct grub_iso9660_dir dirent;
|
|
||||||
int sua_off;
|
int sua_off;
|
||||||
int sua_size;
|
int sua_size;
|
||||||
char *symlink = 0;
|
char *symlink = 0;
|
||||||
|
@ -444,13 +502,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
|
sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1
|
||||||
sizeof (dirent), (char *) &dirent))
|
- (node->dirent.namelen % 2)
|
||||||
return 0;
|
|
||||||
|
|
||||||
sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
|
|
||||||
+ node->data->susp_skip);
|
+ node->data->susp_skip);
|
||||||
sua_size = dirent.len - sua_off;
|
sua_size = node->dirent.len - sua_off;
|
||||||
|
|
||||||
symlink = grub_malloc (1);
|
symlink = grub_malloc (1);
|
||||||
if (!symlink)
|
if (!symlink)
|
||||||
|
@ -647,6 +702,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
filename_alloc = 1;
|
filename_alloc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node->dirent = dirent;
|
||||||
if (hook (filename, type, node))
|
if (hook (filename, type, node))
|
||||||
{
|
{
|
||||||
if (filename_alloc)
|
if (filename_alloc)
|
||||||
|
@ -685,6 +741,8 @@ grub_iso9660_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime);
|
||||||
|
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
@ -882,6 +940,32 @@ grub_iso9660_uuid (grub_device_t device, char **uuid)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get writing time of filesystem. */
|
||||||
|
static grub_err_t
|
||||||
|
grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
|
||||||
|
{
|
||||||
|
struct grub_iso9660_data *data;
|
||||||
|
grub_disk_t disk = device->disk;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
data = grub_iso9660_mount (disk);
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
err = iso9660_to_unixtime (&data->voldesc.modified, timebuf);
|
||||||
|
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct grub_fs grub_iso9660_fs =
|
static struct grub_fs grub_iso9660_fs =
|
||||||
|
@ -893,6 +977,7 @@ static struct grub_fs grub_iso9660_fs =
|
||||||
.close = grub_iso9660_close,
|
.close = grub_iso9660_close,
|
||||||
.label = grub_iso9660_label,
|
.label = grub_iso9660_label,
|
||||||
.uuid = grub_iso9660_uuid,
|
.uuid = grub_iso9660_uuid,
|
||||||
|
.mtime = grub_iso9660_mtime,
|
||||||
.next = 0
|
.next = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,12 @@ struct grub_jfs_leaf_next_dirent
|
||||||
grub_uint16_t namepart[15];
|
grub_uint16_t namepart[15];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_jfs_time
|
||||||
|
{
|
||||||
|
grub_int32_t sec;
|
||||||
|
grub_int32_t nanosec;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_jfs_inode
|
struct grub_jfs_inode
|
||||||
{
|
{
|
||||||
grub_uint32_t stamp;
|
grub_uint32_t stamp;
|
||||||
|
@ -164,7 +170,10 @@ struct grub_jfs_inode
|
||||||
grub_uint64_t size;
|
grub_uint64_t size;
|
||||||
grub_uint8_t unused2[20];
|
grub_uint8_t unused2[20];
|
||||||
grub_uint32_t mode;
|
grub_uint32_t mode;
|
||||||
grub_uint8_t unused3[72];
|
struct grub_jfs_time atime;
|
||||||
|
struct grub_jfs_time ctime;
|
||||||
|
struct grub_jfs_time mtime;
|
||||||
|
grub_uint8_t unused3[48];
|
||||||
grub_uint8_t unused4[96];
|
grub_uint8_t unused4[96];
|
||||||
|
|
||||||
union
|
union
|
||||||
|
@ -760,6 +769,8 @@ grub_jfs_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
info.dir = (grub_le_to_cpu32 (inode.mode)
|
info.dir = (grub_le_to_cpu32 (inode.mode)
|
||||||
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
|
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_le_to_cpu32 (inode.mtime.sec);
|
||||||
if (hook (diro->name, &info))
|
if (hook (diro->name, &info))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,14 +27,17 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#ifdef MODE_MINIX2
|
#ifdef MODE_MINIX3
|
||||||
|
#define GRUB_MINIX_MAGIC 0x4D5A
|
||||||
|
#elif defined(MODE_MINIX2)
|
||||||
#define GRUB_MINIX_MAGIC 0x2468
|
#define GRUB_MINIX_MAGIC 0x2468
|
||||||
#define GRUB_MINIX_MAGIC_30 0x2478
|
#define GRUB_MINIX_MAGIC_30 0x2478
|
||||||
#else
|
#else
|
||||||
#define GRUB_MINIX_MAGIC 0x137F
|
#define GRUB_MINIX_MAGIC 0x137F
|
||||||
#define GRUB_MINIX_MAGIC_30 0x138F
|
#define GRUB_MINIX_MAGIC_30 0x138F
|
||||||
#endif
|
#endif
|
||||||
#define GRUB_MINIX_BSIZE 1024U
|
|
||||||
|
#define GRUB_MINIX_INODE_DIR_BLOCKS 7
|
||||||
#define GRUB_MINIX_LOG2_BSIZE 1
|
#define GRUB_MINIX_LOG2_BSIZE 1
|
||||||
#define GRUB_MINIX_ROOT_INODE 1
|
#define GRUB_MINIX_ROOT_INODE 1
|
||||||
#define GRUB_MINIX_MAX_SYMLNK_CNT 8
|
#define GRUB_MINIX_MAX_SYMLNK_CNT 8
|
||||||
|
@ -43,7 +46,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
#define GRUB_MINIX_IFDIR 0040000U
|
#define GRUB_MINIX_IFDIR 0040000U
|
||||||
#define GRUB_MINIX_IFLNK 0120000U
|
#define GRUB_MINIX_IFLNK 0120000U
|
||||||
|
|
||||||
#ifdef MODE_MINIX2
|
#if defined(MODE_MINIX2) || defined(MODE_MINIX3)
|
||||||
typedef grub_uint32_t grub_minix_uintn_t;
|
typedef grub_uint32_t grub_minix_uintn_t;
|
||||||
#define grub_minix_le_to_cpu_n grub_le_to_cpu32
|
#define grub_minix_le_to_cpu_n grub_le_to_cpu32
|
||||||
#else
|
#else
|
||||||
|
@ -52,6 +55,13 @@ typedef grub_uint16_t grub_minix_uintn_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
|
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
|
||||||
|
#ifdef MODE_MINIX3
|
||||||
|
typedef grub_uint32_t grub_minix_ino_t;
|
||||||
|
#define grub_minix_le_to_cpu_ino grub_le_to_cpu32
|
||||||
|
#else
|
||||||
|
typedef grub_uint16_t grub_minix_ino_t;
|
||||||
|
#define grub_minix_le_to_cpu_ino grub_le_to_cpu16
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
|
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
|
||||||
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
||||||
|
@ -62,11 +72,39 @@ typedef grub_uint16_t grub_minix_uintn_t;
|
||||||
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
||||||
(data->inode.double_indir_zone))
|
(data->inode.double_indir_zone))
|
||||||
|
|
||||||
|
#ifndef MODE_MINIX3
|
||||||
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
||||||
+ grub_le_to_cpu16 (sblock->log2_zone_size))
|
+ grub_le_to_cpu16 (data->sblock.log2_zone_size))
|
||||||
#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \
|
#endif
|
||||||
<< grub_le_to_cpu16 (sblock->log2_zone_size))
|
#define GRUB_MINIX_ZONESZ (data->block_size \
|
||||||
|
<< grub_le_to_cpu16 (data->sblock.log2_zone_size))
|
||||||
|
|
||||||
|
#ifdef MODE_MINIX3
|
||||||
|
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * (data->block_size / GRUB_DISK_SECTOR_SIZE))
|
||||||
|
#else
|
||||||
|
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MODE_MINIX3
|
||||||
|
struct grub_minix_sblock
|
||||||
|
{
|
||||||
|
grub_uint32_t inode_cnt;
|
||||||
|
grub_uint16_t zone_cnt;
|
||||||
|
grub_uint16_t inode_bmap_size;
|
||||||
|
grub_uint16_t zone_bmap_size;
|
||||||
|
grub_uint16_t first_data_zone;
|
||||||
|
grub_uint16_t log2_zone_size;
|
||||||
|
grub_uint16_t pad;
|
||||||
|
grub_uint32_t max_file_size;
|
||||||
|
grub_uint32_t zones;
|
||||||
|
grub_uint16_t magic;
|
||||||
|
|
||||||
|
grub_uint16_t pad2;
|
||||||
|
grub_uint16_t block_size;
|
||||||
|
grub_uint8_t disk_version;
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct grub_minix_sblock
|
struct grub_minix_sblock
|
||||||
{
|
{
|
||||||
grub_uint16_t inode_cnt;
|
grub_uint16_t inode_cnt;
|
||||||
|
@ -78,23 +116,9 @@ struct grub_minix_sblock
|
||||||
grub_uint32_t max_file_size;
|
grub_uint32_t max_file_size;
|
||||||
grub_uint16_t magic;
|
grub_uint16_t magic;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MODE_MINIX2
|
#if defined(MODE_MINIX3) || defined(MODE_MINIX2)
|
||||||
struct grub_minix_inode
|
|
||||||
{
|
|
||||||
grub_uint16_t mode;
|
|
||||||
grub_uint16_t uid;
|
|
||||||
grub_uint16_t size;
|
|
||||||
grub_uint32_t ctime;
|
|
||||||
grub_uint8_t gid;
|
|
||||||
grub_uint8_t nlinks;
|
|
||||||
grub_uint16_t dir_zones[7];
|
|
||||||
grub_uint16_t indir_zone;
|
|
||||||
grub_uint16_t double_indir_zone;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct grub_minix_inode
|
struct grub_minix_inode
|
||||||
{
|
{
|
||||||
grub_uint16_t mode;
|
grub_uint16_t mode;
|
||||||
|
@ -111,6 +135,19 @@ struct grub_minix_inode
|
||||||
grub_uint32_t unused;
|
grub_uint32_t unused;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct grub_minix_inode
|
||||||
|
{
|
||||||
|
grub_uint16_t mode;
|
||||||
|
grub_uint16_t uid;
|
||||||
|
grub_uint16_t size;
|
||||||
|
grub_uint32_t ctime;
|
||||||
|
grub_uint8_t gid;
|
||||||
|
grub_uint8_t nlinks;
|
||||||
|
grub_uint16_t dir_zones[7];
|
||||||
|
grub_uint16_t indir_zone;
|
||||||
|
grub_uint16_t double_indir_zone;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -123,6 +160,7 @@ struct grub_minix_data
|
||||||
int linknest;
|
int linknest;
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
int filename_size;
|
int filename_size;
|
||||||
|
grub_size_t block_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
@ -133,7 +171,6 @@ static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
|
||||||
static int
|
static int
|
||||||
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
||||||
{
|
{
|
||||||
struct grub_minix_sblock *sblock = &data->sblock;
|
|
||||||
int indir;
|
int indir;
|
||||||
|
|
||||||
auto int grub_get_indir (int, int);
|
auto int grub_get_indir (int, int);
|
||||||
|
@ -143,18 +180,18 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
||||||
{
|
{
|
||||||
grub_minix_uintn_t indirn;
|
grub_minix_uintn_t indirn;
|
||||||
grub_disk_read (data->disk,
|
grub_disk_read (data->disk,
|
||||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
GRUB_MINIX_ZONE2SECT(zone),
|
||||||
sizeof (grub_minix_uintn_t) * num,
|
sizeof (grub_minix_uintn_t) * num,
|
||||||
sizeof (grub_minix_uintn_t), (char *) &indirn);
|
sizeof (grub_minix_uintn_t), (char *) &indirn);
|
||||||
return grub_minix_le_to_cpu_n (indirn);
|
return grub_minix_le_to_cpu_n (indirn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Direct block. */
|
/* Direct block. */
|
||||||
if (blk < 7)
|
if (blk < GRUB_MINIX_INODE_DIR_BLOCKS)
|
||||||
return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
|
return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
|
||||||
|
|
||||||
/* Indirect block. */
|
/* Indirect block. */
|
||||||
blk -= 7;
|
blk -= GRUB_MINIX_INODE_DIR_BLOCKS;
|
||||||
if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
|
if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
|
||||||
{
|
{
|
||||||
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
|
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
|
||||||
|
@ -187,25 +224,26 @@ static grub_ssize_t
|
||||||
grub_minix_read_file (struct grub_minix_data *data,
|
grub_minix_read_file (struct grub_minix_data *data,
|
||||||
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
|
||||||
unsigned offset, unsigned length),
|
unsigned offset, unsigned length),
|
||||||
int pos, grub_disk_addr_t len, char *buf)
|
grub_off_t pos, grub_disk_addr_t len, char *buf)
|
||||||
{
|
{
|
||||||
struct grub_minix_sblock *sblock = &data->sblock;
|
grub_disk_addr_t i;
|
||||||
int i;
|
grub_disk_addr_t blockcnt;
|
||||||
int blockcnt;
|
grub_uint64_t posblock;
|
||||||
|
grub_uint64_t blockoff;
|
||||||
|
|
||||||
/* Adjust len so it we can't read past the end of the file. */
|
/* Adjust len so it we can't read past the end of the file. */
|
||||||
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
|
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
|
||||||
len = GRUB_MINIX_INODE_SIZE (data) - pos;
|
len = GRUB_MINIX_INODE_SIZE (data) - pos;
|
||||||
|
|
||||||
blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
|
blockcnt = grub_divmod64 ((len + pos + data->block_size - 1),
|
||||||
|
data->block_size, 0);
|
||||||
|
posblock = grub_divmod64 (pos, data->block_size, &blockoff);
|
||||||
|
|
||||||
for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
|
for (i = posblock; i < blockcnt; i++)
|
||||||
{
|
{
|
||||||
int blknr;
|
grub_disk_addr_t blknr;
|
||||||
int blockoff = pos % GRUB_MINIX_BSIZE;
|
grub_uint64_t blockend = data->block_size;
|
||||||
int blockend = GRUB_MINIX_BSIZE;
|
grub_off_t skipfirst = 0;
|
||||||
|
|
||||||
int skipfirst = 0;
|
|
||||||
|
|
||||||
blknr = grub_minix_get_file_block (data, i);
|
blknr = grub_minix_get_file_block (data, i);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
|
@ -214,28 +252,28 @@ grub_minix_read_file (struct grub_minix_data *data,
|
||||||
/* Last block. */
|
/* Last block. */
|
||||||
if (i == blockcnt - 1)
|
if (i == blockcnt - 1)
|
||||||
{
|
{
|
||||||
blockend = (len + pos) % GRUB_MINIX_BSIZE;
|
grub_divmod64 (len + pos, data->block_size, &blockend);
|
||||||
|
|
||||||
if (!blockend)
|
if (!blockend)
|
||||||
blockend = GRUB_MINIX_BSIZE;
|
blockend = data->block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First block. */
|
/* First block. */
|
||||||
if (i == (pos / (int) GRUB_MINIX_BSIZE))
|
if (i == posblock)
|
||||||
{
|
{
|
||||||
skipfirst = blockoff;
|
skipfirst = blockoff;
|
||||||
blockend -= skipfirst;
|
blockend -= skipfirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->disk->read_hook = read_hook;
|
data->disk->read_hook = read_hook;
|
||||||
grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
|
grub_disk_read (data->disk,
|
||||||
|
GRUB_MINIX_ZONE2SECT(blknr),
|
||||||
skipfirst, blockend, buf);
|
skipfirst, blockend, buf);
|
||||||
|
|
||||||
data->disk->read_hook = 0;
|
data->disk->read_hook = 0;
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buf += GRUB_MINIX_BSIZE - skipfirst;
|
buf += data->block_size - skipfirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -250,16 +288,13 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino)
|
||||||
struct grub_minix_sblock *sblock = &data->sblock;
|
struct grub_minix_sblock *sblock = &data->sblock;
|
||||||
|
|
||||||
/* Block in which the inode is stored. */
|
/* Block in which the inode is stored. */
|
||||||
int block;
|
grub_disk_addr_t block;
|
||||||
data->ino = ino;
|
data->ino = ino;
|
||||||
|
|
||||||
/* The first inode in minix is inode 1. */
|
/* The first inode in minix is inode 1. */
|
||||||
ino--;
|
ino--;
|
||||||
|
block = GRUB_MINIX_ZONE2SECT (2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
|
||||||
block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
|
+ grub_le_to_cpu16 (sblock->zone_bmap_size));
|
||||||
+ grub_le_to_cpu16 (sblock->zone_bmap_size))
|
|
||||||
<< GRUB_MINIX_LOG2_BSIZE);
|
|
||||||
|
|
||||||
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
||||||
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
||||||
/ sizeof (struct grub_minix_inode))
|
/ sizeof (struct grub_minix_inode))
|
||||||
|
@ -335,7 +370,7 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
grub_uint16_t ino;
|
grub_minix_ino_t ino;
|
||||||
char filename[data->filename_size + 1];
|
char filename[data->filename_size + 1];
|
||||||
|
|
||||||
if (grub_strlen (name) == 0)
|
if (grub_strlen (name) == 0)
|
||||||
|
@ -355,7 +390,7 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path)
|
||||||
if (!grub_strcmp (name, filename))
|
if (!grub_strcmp (name, filename))
|
||||||
{
|
{
|
||||||
dirino = data->ino;
|
dirino = data->ino;
|
||||||
grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
|
grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino));
|
||||||
|
|
||||||
/* Follow the symlink. */
|
/* Follow the symlink. */
|
||||||
if ((GRUB_MINIX_INODE_MODE (data)
|
if ((GRUB_MINIX_INODE_MODE (data)
|
||||||
|
@ -411,20 +446,35 @@ grub_minix_mount (grub_disk_t disk)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
|
if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
|
||||||
|
{
|
||||||
|
#if !defined(MODE_MINIX3)
|
||||||
data->filename_size = 14;
|
data->filename_size = 14;
|
||||||
|
#else
|
||||||
|
data->filename_size = 60;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if !defined(MODE_MINIX3)
|
||||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
|
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
|
||||||
data->filename_size = 30;
|
data->filename_size = 30;
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->disk = disk;
|
data->disk = disk;
|
||||||
data->linknest = 0;
|
data->linknest = 0;
|
||||||
|
#ifdef MODE_MINIX3
|
||||||
|
data->block_size = grub_le_to_cpu16 (data->sblock.block_size);
|
||||||
|
#else
|
||||||
|
data->block_size = 1024U;
|
||||||
|
#endif
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
grub_free (data);
|
grub_free (data);
|
||||||
#ifdef MODE_MINIX2
|
#if defined(MODE_MINIX3)
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not a minix3 filesystem");
|
||||||
|
#elif defined(MODE_MINIX2)
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem");
|
grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem");
|
||||||
#else
|
#else
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
|
grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
|
||||||
|
@ -460,7 +510,7 @@ grub_minix_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
while (pos < GRUB_MINIX_INODE_SIZE (data))
|
while (pos < GRUB_MINIX_INODE_SIZE (data))
|
||||||
{
|
{
|
||||||
grub_uint16_t ino;
|
grub_minix_ino_t ino;
|
||||||
char filename[data->filename_size + 1];
|
char filename[data->filename_size + 1];
|
||||||
int dirino = data->ino;
|
int dirino = data->ino;
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
|
@ -476,12 +526,22 @@ grub_minix_dir (grub_device_t device, const char *path,
|
||||||
(char *) filename) < 0)
|
(char *) filename) < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
filename[data->filename_size] = '\0';
|
filename[data->filename_size] = '\0';
|
||||||
|
if (!ino)
|
||||||
|
{
|
||||||
|
pos += sizeof (ino) + data->filename_size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* The filetype is not stored in the dirent. Read the inode to
|
grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino));
|
||||||
find out the filetype. This *REALLY* sucks. */
|
|
||||||
grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
|
|
||||||
info.dir = ((GRUB_MINIX_INODE_MODE (data)
|
info.dir = ((GRUB_MINIX_INODE_MODE (data)
|
||||||
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
|
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
|
||||||
|
info.mtimeset = 1;
|
||||||
|
#ifndef MODE_MINIX2
|
||||||
|
info.mtime = grub_le_to_cpu32 (data->inode.ctime);
|
||||||
|
#else
|
||||||
|
info.mtime = grub_le_to_cpu32 (data->inode.mtime);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (hook (filename, &info) ? 1 : 0)
|
if (hook (filename, &info) ? 1 : 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -558,7 +618,9 @@ grub_minix_close (grub_file_t file)
|
||||||
|
|
||||||
static struct grub_fs grub_minix_fs =
|
static struct grub_fs grub_minix_fs =
|
||||||
{
|
{
|
||||||
#ifdef MODE_MINIX2
|
#if defined(MODE_MINIX3)
|
||||||
|
.name = "minix3",
|
||||||
|
#elif defined(MODE_MINIX2)
|
||||||
.name = "minix2",
|
.name = "minix2",
|
||||||
#else
|
#else
|
||||||
.name = "minix",
|
.name = "minix",
|
||||||
|
@ -570,7 +632,9 @@ static struct grub_fs grub_minix_fs =
|
||||||
.next = 0
|
.next = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MODE_MINIX2
|
#if defined(MODE_MINIX3)
|
||||||
|
GRUB_MOD_INIT(minix3)
|
||||||
|
#elif defined(MODE_MINIX2)
|
||||||
GRUB_MOD_INIT(minix2)
|
GRUB_MOD_INIT(minix2)
|
||||||
#else
|
#else
|
||||||
GRUB_MOD_INIT(minix)
|
GRUB_MOD_INIT(minix)
|
||||||
|
@ -580,7 +644,9 @@ GRUB_MOD_INIT(minix)
|
||||||
my_mod = mod;
|
my_mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODE_MINIX2
|
#if defined(MODE_MINIX3)
|
||||||
|
GRUB_MOD_FINI(minix3)
|
||||||
|
#elif defined(MODE_MINIX2)
|
||||||
GRUB_MOD_FINI(minix2)
|
GRUB_MOD_FINI(minix2)
|
||||||
#else
|
#else
|
||||||
GRUB_MOD_FINI(minix)
|
GRUB_MOD_FINI(minix)
|
||||||
|
|
2
grub-core/fs/minix3.c
Normal file
2
grub-core/fs/minix3.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define MODE_MINIX3 1
|
||||||
|
#include "minix.c"
|
|
@ -303,7 +303,7 @@ grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data)
|
||||||
|
|
||||||
static inline grub_uint64_t
|
static inline grub_uint64_t
|
||||||
grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
|
grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t nr, grub_uint32_t * offset)
|
grub_uint64_t nr, grub_uint64_t * offset)
|
||||||
{
|
{
|
||||||
return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data),
|
return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data),
|
||||||
offset);
|
offset);
|
||||||
|
@ -368,13 +368,15 @@ grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t nr, unsigned long entry_size)
|
grub_uint64_t nr, unsigned long entry_size)
|
||||||
{
|
{
|
||||||
unsigned long group;
|
unsigned long group;
|
||||||
grub_uint32_t group_offset;
|
grub_uint64_t group_offset;
|
||||||
|
|
||||||
group = grub_nilfs2_palloc_group (data, nr, &group_offset);
|
group = grub_nilfs2_palloc_group (data, nr, &group_offset);
|
||||||
|
|
||||||
return grub_nilfs2_palloc_bitmap_block_offset (data, group,
|
return grub_nilfs2_palloc_bitmap_block_offset (data, group,
|
||||||
entry_size) + 1 +
|
entry_size) + 1 +
|
||||||
group_offset / grub_nilfs2_entries_per_block (data, entry_size);
|
grub_divmod64 (group_offset, grub_nilfs2_entries_per_block (data,
|
||||||
|
entry_size),
|
||||||
|
NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +579,7 @@ grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key)
|
||||||
struct grub_nilfs2_dat_entry entry;
|
struct grub_nilfs2_dat_entry entry;
|
||||||
grub_disk_t disk = data->disk;
|
grub_disk_t disk = data->disk;
|
||||||
grub_uint64_t pptr;
|
grub_uint64_t pptr;
|
||||||
grub_uint32_t blockno, offset;
|
grub_uint64_t blockno, offset;
|
||||||
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
|
||||||
blockno = grub_nilfs2_palloc_entry_offset (data, key,
|
blockno = grub_nilfs2_palloc_entry_offset (data, key,
|
||||||
|
@ -641,7 +643,7 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data,
|
||||||
struct grub_nilfs2_checkpoint *cpp)
|
struct grub_nilfs2_checkpoint *cpp)
|
||||||
{
|
{
|
||||||
grub_uint64_t blockno;
|
grub_uint64_t blockno;
|
||||||
grub_uint32_t offset;
|
grub_uint64_t offset;
|
||||||
grub_uint64_t pptr;
|
grub_uint64_t pptr;
|
||||||
grub_disk_t disk = data->disk;
|
grub_disk_t disk = data->disk;
|
||||||
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
@ -679,7 +681,7 @@ grub_nilfs2_read_inode (struct grub_nilfs2_data *data,
|
||||||
grub_uint64_t ino, struct grub_nilfs2_inode *inodep)
|
grub_uint64_t ino, struct grub_nilfs2_inode *inodep)
|
||||||
{
|
{
|
||||||
grub_uint64_t blockno;
|
grub_uint64_t blockno;
|
||||||
unsigned int offset;
|
grub_uint64_t offset;
|
||||||
grub_uint64_t pptr;
|
grub_uint64_t pptr;
|
||||||
grub_disk_t disk = data->disk;
|
grub_disk_t disk = data->disk;
|
||||||
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
|
|
@ -431,7 +431,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
|
||||||
if (at->flags & AF_GPOS)
|
if (at->flags & AF_GPOS)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t st0, st1;
|
grub_disk_addr_t st0, st1;
|
||||||
grub_uint32_t m;
|
grub_uint64_t m;
|
||||||
|
|
||||||
grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
|
grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
|
||||||
|
|
||||||
|
@ -612,6 +612,10 @@ list_file (struct grub_ntfs_file *diro, char *pos,
|
||||||
|
|
||||||
fdiro->data = diro->data;
|
fdiro->data = diro->data;
|
||||||
fdiro->ino = u32at (pos, 0);
|
fdiro->ino = u32at (pos, 0);
|
||||||
|
if (u64at (pos, 0x20) > u64at (pos, 0x28))
|
||||||
|
fdiro->mtime = u64at (pos, 0x20);
|
||||||
|
else
|
||||||
|
fdiro->mtime = u64at (pos, 0x28);
|
||||||
|
|
||||||
ustr = grub_malloc (ns * 4 + 1);
|
ustr = grub_malloc (ns * 4 + 1);
|
||||||
if (ustr == NULL)
|
if (ustr == NULL)
|
||||||
|
@ -882,6 +886,10 @@ grub_ntfs_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_divmod64 (node->mtime, 10000000, 0)
|
||||||
|
- 86400ULL * 365 * (1970 - 1601)
|
||||||
|
- 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,7 @@ struct grub_fshelp_node
|
||||||
grub_uint32_t block_number; /* 0 if node is not found. */
|
grub_uint32_t block_number; /* 0 if node is not found. */
|
||||||
grub_uint16_t block_position;
|
grub_uint16_t block_position;
|
||||||
grub_uint64_t next_offset;
|
grub_uint64_t next_offset;
|
||||||
|
grub_int32_t mtime;
|
||||||
enum grub_reiserfs_item_type type; /* To know how to read the header. */
|
enum grub_reiserfs_item_type type; /* To know how to read the header. */
|
||||||
struct grub_reiserfs_item_header header;
|
struct grub_reiserfs_item_header header;
|
||||||
};
|
};
|
||||||
|
@ -870,6 +871,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
||||||
entry_v1_stat.rdev,
|
entry_v1_stat.rdev,
|
||||||
entry_v1_stat.first_direct_byte);
|
entry_v1_stat.first_direct_byte);
|
||||||
#endif
|
#endif
|
||||||
|
entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime);
|
||||||
if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
|
if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
|
||||||
== S_IFLNK)
|
== S_IFLNK)
|
||||||
entry_type = GRUB_FSHELP_SYMLINK;
|
entry_type = GRUB_FSHELP_SYMLINK;
|
||||||
|
@ -916,6 +918,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
|
||||||
entry_v2_stat.blocks,
|
entry_v2_stat.blocks,
|
||||||
entry_v2_stat.first_direct_byte);
|
entry_v2_stat.first_direct_byte);
|
||||||
#endif
|
#endif
|
||||||
|
entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
|
||||||
if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
|
if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
|
||||||
== S_IFLNK)
|
== S_IFLNK)
|
||||||
entry_type = GRUB_FSHELP_SYMLINK;
|
entry_type = GRUB_FSHELP_SYMLINK;
|
||||||
|
@ -1278,6 +1281,8 @@ grub_reiserfs_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = node->mtime;
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
|
458
grub-core/fs/romfs.c
Normal file
458
grub-core/fs/romfs.c
Normal file
|
@ -0,0 +1,458 @@
|
||||||
|
/*
|
||||||
|
* 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/file.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/fs.h>
|
||||||
|
#include <grub/fshelp.h>
|
||||||
|
|
||||||
|
struct grub_romfs_superblock
|
||||||
|
{
|
||||||
|
char magic[8];
|
||||||
|
#define GRUB_ROMFS_MAGIC "-rom1fs-"
|
||||||
|
grub_uint32_t total_size;
|
||||||
|
grub_uint32_t chksum;
|
||||||
|
char label[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_romfs_file_header
|
||||||
|
{
|
||||||
|
grub_uint32_t next_file;
|
||||||
|
grub_uint32_t spec;
|
||||||
|
grub_uint32_t size;
|
||||||
|
grub_uint32_t chksum;
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_romfs_data
|
||||||
|
{
|
||||||
|
grub_disk_addr_t first_file;
|
||||||
|
grub_disk_t disk;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_fshelp_node
|
||||||
|
{
|
||||||
|
grub_disk_addr_t addr;
|
||||||
|
struct grub_romfs_data *data;
|
||||||
|
grub_disk_addr_t data_addr;
|
||||||
|
/* Not filled for root. */
|
||||||
|
struct grub_romfs_file_header file;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GRUB_ROMFS_ALIGN 16
|
||||||
|
#define GRUB_ROMFS_TYPE_MASK 7
|
||||||
|
#define GRUB_ROMFS_TYPE_HARDLINK 0
|
||||||
|
#define GRUB_ROMFS_TYPE_DIRECTORY 1
|
||||||
|
#define GRUB_ROMFS_TYPE_REGULAR 2
|
||||||
|
#define GRUB_ROMFS_TYPE_SYMLINK 3
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
do_checksum (void *in, grub_size_t insize)
|
||||||
|
{
|
||||||
|
grub_uint32_t *a = in;
|
||||||
|
grub_size_t sz = insize / 4;
|
||||||
|
grub_uint32_t *b = a + sz;
|
||||||
|
grub_uint32_t csum = 0;
|
||||||
|
|
||||||
|
while (a < b)
|
||||||
|
csum += grub_be_to_cpu32 (*a++);
|
||||||
|
if (csum)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "invalid checksum");
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_romfs_data *
|
||||||
|
grub_romfs_mount (grub_device_t dev)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct grub_romfs_superblock sb;
|
||||||
|
char d[512];
|
||||||
|
} sb;
|
||||||
|
grub_err_t err;
|
||||||
|
char *ptr;
|
||||||
|
grub_disk_addr_t sec = 0;
|
||||||
|
struct grub_romfs_data *data;
|
||||||
|
if (!dev->disk)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not a disk");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
err = grub_disk_read (dev->disk, 0, 0, sizeof (sb), &sb);
|
||||||
|
if (err == GRUB_ERR_OUT_OF_RANGE)
|
||||||
|
err = grub_errno = GRUB_ERR_BAD_FS;
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
if (grub_be_to_cpu32 (sb.sb.total_size) < sizeof (sb))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "too short filesystem");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
err = do_checksum (&sb, sizeof (sb) < grub_be_to_cpu32 (sb.sb.total_size) ?
|
||||||
|
sizeof (sb) : grub_be_to_cpu32 (sb.sb.total_size));
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1)
|
||||||
|
&& ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
||||||
|
if (!*ptr)
|
||||||
|
break;
|
||||||
|
if ((void *) ptr == &sb + 1)
|
||||||
|
for (sec++; ; sec++)
|
||||||
|
{
|
||||||
|
err = grub_disk_read (dev->disk, sec, 0, sizeof (sb), &sb);
|
||||||
|
if (err == GRUB_ERR_OUT_OF_RANGE)
|
||||||
|
err = grub_errno = GRUB_ERR_BAD_FS;
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1)
|
||||||
|
&& ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++)
|
||||||
|
if (!*ptr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data = grub_malloc (sizeof (*data));
|
||||||
|
if (!data)
|
||||||
|
return NULL;
|
||||||
|
data->first_file = ALIGN_UP (ptr - sb.d, GRUB_ROMFS_ALIGN) + sec * 512;
|
||||||
|
data->disk = dev->disk;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
grub_romfs_read_symlink (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
grub_err_t err;
|
||||||
|
ret = grub_malloc (grub_be_to_cpu32 (node->file.size) + 1);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
err = grub_disk_read (node->data->disk,
|
||||||
|
(node->data_addr) >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
(node->data_addr) & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
grub_be_to_cpu32 (node->file.size), ret);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret[grub_be_to_cpu32 (node->file.size)] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_romfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
int NESTED_FUNC_ATTR
|
||||||
|
(*hook) (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node))
|
||||||
|
{
|
||||||
|
grub_disk_addr_t caddr;
|
||||||
|
struct grub_romfs_file_header hdr;
|
||||||
|
grub_size_t a = 0;
|
||||||
|
char *name = NULL;
|
||||||
|
unsigned nptr;
|
||||||
|
unsigned i, j;
|
||||||
|
for (caddr = dir->data_addr; caddr;
|
||||||
|
caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1))
|
||||||
|
{
|
||||||
|
grub_disk_addr_t naddr = caddr + sizeof (hdr);
|
||||||
|
grub_uint32_t csum = 0;
|
||||||
|
enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN;
|
||||||
|
struct grub_fshelp_node *node;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
caddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
sizeof (hdr), &hdr);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (nptr = 0; ; nptr++, naddr += 16)
|
||||||
|
{
|
||||||
|
if (a >= nptr)
|
||||||
|
{
|
||||||
|
char *on;
|
||||||
|
a = 2 * (nptr + 1);
|
||||||
|
on = name;
|
||||||
|
name = grub_realloc (name, a * 16);
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
grub_free (on);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
naddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
16, name + 16 * nptr);
|
||||||
|
if (err)
|
||||||
|
return 1;
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
if (!name[16 * nptr + j])
|
||||||
|
break;
|
||||||
|
if (j != 16)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < sizeof (hdr) / sizeof (grub_uint32_t); i++)
|
||||||
|
csum += grub_be_to_cpu32 (((grub_uint32_t *) &hdr)[i]);
|
||||||
|
for (i = 0; i < (nptr + 1) * 4; i++)
|
||||||
|
csum += grub_be_to_cpu32 (((grub_uint32_t *) name)[i]);
|
||||||
|
if (csum != 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "invalid checksum");
|
||||||
|
grub_free (name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
node = grub_malloc (sizeof (*node));
|
||||||
|
if (!node)
|
||||||
|
return 1;
|
||||||
|
node->addr = caddr;
|
||||||
|
node->data_addr = caddr + (nptr + 1) * 16 + sizeof (hdr);
|
||||||
|
node->data = dir->data;
|
||||||
|
node->file = hdr;
|
||||||
|
switch (grub_be_to_cpu32 (hdr.next_file) & GRUB_ROMFS_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case GRUB_ROMFS_TYPE_REGULAR:
|
||||||
|
filetype = GRUB_FSHELP_REG;
|
||||||
|
break;
|
||||||
|
case GRUB_ROMFS_TYPE_SYMLINK:
|
||||||
|
filetype = GRUB_FSHELP_SYMLINK;
|
||||||
|
break;
|
||||||
|
case GRUB_ROMFS_TYPE_DIRECTORY:
|
||||||
|
node->data_addr = grub_be_to_cpu32 (hdr.spec);
|
||||||
|
filetype = GRUB_FSHELP_DIR;
|
||||||
|
break;
|
||||||
|
case GRUB_ROMFS_TYPE_HARDLINK:
|
||||||
|
{
|
||||||
|
grub_disk_addr_t laddr;
|
||||||
|
node->addr = laddr = grub_be_to_cpu32 (hdr.spec);
|
||||||
|
err = grub_disk_read (dir->data->disk,
|
||||||
|
laddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
laddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
sizeof (node->file), &node->file);
|
||||||
|
if (err)
|
||||||
|
return 1;
|
||||||
|
if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK)
|
||||||
|
== GRUB_ROMFS_TYPE_REGULAR
|
||||||
|
|| (grub_be_to_cpu32 (node->file.next_file)
|
||||||
|
& GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK)
|
||||||
|
{
|
||||||
|
laddr += sizeof (hdr);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
err = grub_disk_read (dir->data->disk,
|
||||||
|
laddr >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
laddr & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
16, buf);
|
||||||
|
if (err)
|
||||||
|
return 1;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
if (!buf[i])
|
||||||
|
break;
|
||||||
|
if (i != 16)
|
||||||
|
break;
|
||||||
|
laddr += 16;
|
||||||
|
}
|
||||||
|
node->data_addr = laddr + 16;
|
||||||
|
}
|
||||||
|
if ((grub_be_to_cpu32 (node->file.next_file)
|
||||||
|
& GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_REGULAR)
|
||||||
|
filetype = GRUB_FSHELP_REG;
|
||||||
|
if ((grub_be_to_cpu32 (node->file.next_file)
|
||||||
|
& GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK)
|
||||||
|
filetype = GRUB_FSHELP_SYMLINK;
|
||||||
|
if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK)
|
||||||
|
== GRUB_ROMFS_TYPE_DIRECTORY)
|
||||||
|
{
|
||||||
|
node->data_addr = grub_be_to_cpu32 (node->file.spec);
|
||||||
|
filetype = GRUB_FSHELP_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hook (name, filetype, node))
|
||||||
|
{
|
||||||
|
grub_free (name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grub_free (name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_romfs_dir (grub_device_t device, const char *path,
|
||||||
|
int (*hook) (const char *filename,
|
||||||
|
const struct grub_dirhook_info *info))
|
||||||
|
{
|
||||||
|
struct grub_romfs_data *data = 0;
|
||||||
|
struct grub_fshelp_node *fdiro = 0, start;
|
||||||
|
|
||||||
|
auto int NESTED_FUNC_ATTR iterate (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node);
|
||||||
|
|
||||||
|
int NESTED_FUNC_ATTR iterate (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
struct grub_dirhook_info info;
|
||||||
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
grub_free (node);
|
||||||
|
return hook (filename, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = grub_romfs_mount (device);
|
||||||
|
if (! data)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start.addr = data->first_file;
|
||||||
|
start.data_addr = data->first_file;
|
||||||
|
start.data = data;
|
||||||
|
grub_fshelp_find_file (path, &start, &fdiro, grub_romfs_iterate_dir,
|
||||||
|
grub_romfs_read_symlink, GRUB_FSHELP_DIR);
|
||||||
|
if (grub_errno)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_romfs_iterate_dir (fdiro, iterate);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_romfs_open (struct grub_file *file, const char *name)
|
||||||
|
{
|
||||||
|
struct grub_romfs_data *data = 0;
|
||||||
|
struct grub_fshelp_node *fdiro = 0, start;
|
||||||
|
|
||||||
|
data = grub_romfs_mount (file->device);
|
||||||
|
if (! data)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start.addr = data->first_file;
|
||||||
|
start.data_addr = data->first_file;
|
||||||
|
start.data = data;
|
||||||
|
|
||||||
|
grub_fshelp_find_file (name, &start, &fdiro, grub_romfs_iterate_dir,
|
||||||
|
grub_romfs_read_symlink, GRUB_FSHELP_REG);
|
||||||
|
if (grub_errno)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
file->size = grub_be_to_cpu32 (fdiro->file.size);
|
||||||
|
file->data = fdiro;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
grub_romfs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
{
|
||||||
|
struct grub_fshelp_node *data = file->data;
|
||||||
|
|
||||||
|
/* XXX: The file is stored in as a single extent. */
|
||||||
|
data->data->disk->read_hook = file->read_hook;
|
||||||
|
grub_disk_read (data->data->disk,
|
||||||
|
(data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
(data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
len, buf);
|
||||||
|
data->data->disk->read_hook = NULL;
|
||||||
|
|
||||||
|
if (grub_errno)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_romfs_close (grub_file_t file)
|
||||||
|
{
|
||||||
|
grub_free (file->data);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_romfs_label (grub_device_t device, char **label)
|
||||||
|
{
|
||||||
|
struct grub_romfs_data *data;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
*label = NULL;
|
||||||
|
|
||||||
|
data = grub_romfs_mount (device);
|
||||||
|
if (!data)
|
||||||
|
return grub_errno;
|
||||||
|
*label = grub_malloc (data->first_file + 1
|
||||||
|
- sizeof (struct grub_romfs_superblock));
|
||||||
|
if (!*label)
|
||||||
|
{
|
||||||
|
grub_free (data);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
err = grub_disk_read (device->disk, 0, sizeof (struct grub_romfs_superblock),
|
||||||
|
data->first_file
|
||||||
|
- sizeof (struct grub_romfs_superblock),
|
||||||
|
*label);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (data);
|
||||||
|
grub_free (*label);
|
||||||
|
*label = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
(*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct grub_fs grub_romfs_fs =
|
||||||
|
{
|
||||||
|
.name = "romfs",
|
||||||
|
.dir = grub_romfs_dir,
|
||||||
|
.open = grub_romfs_open,
|
||||||
|
.read = grub_romfs_read,
|
||||||
|
.close = grub_romfs_close,
|
||||||
|
.label = grub_romfs_label,
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
.reserved_first_sector = 0,
|
||||||
|
#endif
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(romfs)
|
||||||
|
{
|
||||||
|
grub_fs_register (&grub_romfs_fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(romfs)
|
||||||
|
{
|
||||||
|
grub_fs_unregister (&grub_romfs_fs);
|
||||||
|
}
|
|
@ -68,7 +68,7 @@ struct grub_sfs_obj
|
||||||
grub_uint32_t dir_objc;
|
grub_uint32_t dir_objc;
|
||||||
} dir __attribute__ ((packed));
|
} dir __attribute__ ((packed));
|
||||||
} file_dir;
|
} file_dir;
|
||||||
grub_uint8_t unused3[4];
|
grub_uint32_t mtime;
|
||||||
grub_uint8_t type;
|
grub_uint8_t type;
|
||||||
grub_uint8_t filename[1];
|
grub_uint8_t filename[1];
|
||||||
grub_uint8_t comment[1];
|
grub_uint8_t comment[1];
|
||||||
|
@ -121,6 +121,7 @@ struct grub_fshelp_node
|
||||||
struct grub_sfs_data *data;
|
struct grub_sfs_data *data;
|
||||||
int block;
|
int block;
|
||||||
int size;
|
int size;
|
||||||
|
grub_uint32_t mtime;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about a "mounted" sfs filesystem. */
|
/* Information about a "mounted" sfs filesystem. */
|
||||||
|
@ -357,10 +358,12 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
|
auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
|
||||||
int size, int type);
|
int size, int type,
|
||||||
|
grub_uint32_t mtime);
|
||||||
|
|
||||||
int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
|
int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
|
||||||
int size, int type)
|
int size, int type,
|
||||||
|
grub_uint32_t mtime)
|
||||||
{
|
{
|
||||||
node = grub_malloc (sizeof (*node));
|
node = grub_malloc (sizeof (*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
|
@ -369,6 +372,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->size = size;
|
node->size = size;
|
||||||
node->block = block;
|
node->block = block;
|
||||||
|
node->mtime = mtime;
|
||||||
|
|
||||||
return hook (name, type, node);
|
return hook (name, type, node);
|
||||||
}
|
}
|
||||||
|
@ -428,7 +432,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
if (grub_sfs_create_node (filename, block,
|
if (grub_sfs_create_node (filename, block,
|
||||||
grub_be_to_cpu32 (obj->file_dir.file.size),
|
grub_be_to_cpu32 (obj->file_dir.file.size),
|
||||||
type))
|
type, grub_be_to_cpu32 (obj->mtime)))
|
||||||
{
|
{
|
||||||
grub_free (objc_data);
|
grub_free (objc_data);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -527,6 +531,8 @@ grub_sfs_dir (grub_device_t device, const char *path,
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2;
|
||||||
|
info.mtimeset = 1;
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
|
548
grub-core/fs/squash4.c
Normal file
548
grub-core/fs/squash4.c
Normal file
|
@ -0,0 +1,548 @@
|
||||||
|
/* squash4.c - SquashFS */
|
||||||
|
/*
|
||||||
|
* 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/err.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/deflate.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
/*
|
||||||
|
object format Pointed by
|
||||||
|
superblock RAW Fixed offset (0)
|
||||||
|
data RAW ? Fixed offset (60)
|
||||||
|
inode table Chunk superblock
|
||||||
|
dir table Chunk superblock
|
||||||
|
fragment table Chunk unk1
|
||||||
|
unk1 RAW, Chunk superblock
|
||||||
|
unk2 RAW superblock
|
||||||
|
UID/GID Chunk exttblptr
|
||||||
|
exttblptr RAW superblock
|
||||||
|
|
||||||
|
UID/GID table is the array ot uint32_t
|
||||||
|
unk1 contains pointer to unk3 followed by some chunk.
|
||||||
|
unk2 containts one uint64_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct grub_squash_super
|
||||||
|
{
|
||||||
|
grub_uint32_t magic;
|
||||||
|
#define SQUASH_MAGIC 0x73717368
|
||||||
|
grub_uint32_t dummy1;
|
||||||
|
grub_uint32_t creation_time;
|
||||||
|
grub_uint32_t dummy2;
|
||||||
|
grub_uint64_t dummy3;
|
||||||
|
grub_uint8_t flags;
|
||||||
|
#define SQUASH_FLAG_UNCOMPRESSED_INODES 1
|
||||||
|
#define SQUASH_FLAG_UNCOMPRESSED_DATA 2
|
||||||
|
#define SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS 8
|
||||||
|
grub_uint8_t dummy4[7];
|
||||||
|
grub_uint16_t root_ino_offset;
|
||||||
|
grub_uint32_t root_ino_chunk;
|
||||||
|
grub_uint16_t dummy5;
|
||||||
|
grub_uint64_t total_size;
|
||||||
|
grub_uint64_t exttbloffset;
|
||||||
|
grub_uint64_t dummy6;
|
||||||
|
grub_uint64_t inodeoffset;
|
||||||
|
grub_uint64_t diroffset;
|
||||||
|
grub_uint64_t unk1offset;
|
||||||
|
grub_uint64_t unk2offset;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
/* Chunk-based */
|
||||||
|
struct grub_squash_inode
|
||||||
|
{
|
||||||
|
/* Same values as direlem types. */
|
||||||
|
grub_uint16_t type;
|
||||||
|
grub_uint16_t dummy[3];
|
||||||
|
grub_uint32_t mtime;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
grub_uint32_t dummy;
|
||||||
|
grub_uint32_t chunk;
|
||||||
|
grub_uint32_t fragment;
|
||||||
|
grub_uint32_t offset;
|
||||||
|
grub_uint32_t size;
|
||||||
|
} __attribute__ ((packed)) file;
|
||||||
|
struct {
|
||||||
|
grub_uint32_t dummy1;
|
||||||
|
grub_uint32_t chunk;
|
||||||
|
grub_uint32_t dummy2;
|
||||||
|
grub_uint16_t size;
|
||||||
|
grub_uint32_t offset;
|
||||||
|
grub_uint16_t dummy3;
|
||||||
|
} __attribute__ ((packed)) dir;
|
||||||
|
struct {
|
||||||
|
grub_uint64_t dummy;
|
||||||
|
grub_uint32_t namelen;
|
||||||
|
char name[0];
|
||||||
|
} __attribute__ ((packed)) symlink;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* Chunk-based. */
|
||||||
|
struct grub_squash_dirent_header
|
||||||
|
{
|
||||||
|
/* Actually the value is the number of elements - 1. */
|
||||||
|
grub_uint32_t nelems;
|
||||||
|
grub_uint64_t ino_chunk;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_squash_dirent
|
||||||
|
{
|
||||||
|
grub_uint16_t ino_offset;
|
||||||
|
grub_uint16_t dummy;
|
||||||
|
grub_uint16_t type;
|
||||||
|
#define SQUASH_TYPE_DIR 1
|
||||||
|
#define SQUASH_TYPE_REGULAR 2
|
||||||
|
#define SQUASH_TYPE_SYMLINK 3
|
||||||
|
/* Actually the value is the length of name - 1. */
|
||||||
|
grub_uint16_t namelen;
|
||||||
|
char name[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_squash_frag_desc
|
||||||
|
{
|
||||||
|
grub_uint64_t offset;
|
||||||
|
grub_uint64_t dummy;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define SQUASH_CHUNK_SIZE 0x2000
|
||||||
|
#define SQUASH_CHUNK_FLAGS 0x8000
|
||||||
|
#define SQUASH_CHUNK_UNCOMPRESSED 0x8000
|
||||||
|
|
||||||
|
struct grub_squash_data
|
||||||
|
{
|
||||||
|
grub_disk_t disk;
|
||||||
|
struct grub_squash_super sb;
|
||||||
|
struct grub_squash_inode ino;
|
||||||
|
grub_uint64_t fragments;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_fshelp_node
|
||||||
|
{
|
||||||
|
struct grub_squash_data *data;
|
||||||
|
struct grub_squash_inode ino;
|
||||||
|
grub_uint32_t ino_chunk;
|
||||||
|
grub_uint16_t ino_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
|
||||||
|
grub_uint64_t chunk, grub_off_t offset)
|
||||||
|
{
|
||||||
|
grub_uint64_t chunk_start;
|
||||||
|
chunk_start = grub_le_to_cpu64 (chunk);
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
grub_uint64_t csize;
|
||||||
|
grub_uint16_t d;
|
||||||
|
grub_err_t err;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
err = grub_disk_read (disk, chunk_start >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
chunk_start & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
sizeof (d), &d);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
if (offset < SQUASH_CHUNK_SIZE)
|
||||||
|
break;
|
||||||
|
offset -= SQUASH_CHUNK_SIZE;
|
||||||
|
chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
csize = SQUASH_CHUNK_SIZE - offset;
|
||||||
|
if (csize > len)
|
||||||
|
csize = len;
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED)
|
||||||
|
{
|
||||||
|
grub_disk_addr_t a = chunk_start + 2 + offset;
|
||||||
|
err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS),
|
||||||
|
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
csize, buf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS;
|
||||||
|
grub_disk_addr_t a = chunk_start + 2;
|
||||||
|
tmp = grub_malloc (bsize);
|
||||||
|
if (!tmp)
|
||||||
|
return grub_errno;
|
||||||
|
/* FIXME: buffer uncompressed data. */
|
||||||
|
err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS),
|
||||||
|
a & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
bsize, tmp);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (tmp);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_zlib_decompress (tmp, bsize, offset,
|
||||||
|
buf, csize) < 0)
|
||||||
|
{
|
||||||
|
grub_free (tmp);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_free (tmp);
|
||||||
|
}
|
||||||
|
len -= csize;
|
||||||
|
offset += csize;
|
||||||
|
buf = (char *) buf + csize;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_squash_data *
|
||||||
|
squash_mount (grub_disk_t disk)
|
||||||
|
{
|
||||||
|
struct grub_squash_super sb;
|
||||||
|
grub_err_t err;
|
||||||
|
struct grub_squash_data *data;
|
||||||
|
grub_uint64_t frag;
|
||||||
|
|
||||||
|
err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb);
|
||||||
|
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not squash4");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = grub_disk_read (disk, grub_le_to_cpu32 (sb.unk1offset)
|
||||||
|
>> GRUB_DISK_SECTOR_BITS,
|
||||||
|
grub_le_to_cpu32 (sb.unk1offset)
|
||||||
|
& (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag);
|
||||||
|
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "not a squash4");
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
data = grub_malloc (sizeof (*data));
|
||||||
|
if (!data)
|
||||||
|
return NULL;
|
||||||
|
data->sb = sb;
|
||||||
|
data->disk = disk;
|
||||||
|
data->fragments = frag;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
grub_squash_read_symlink (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
grub_err_t err;
|
||||||
|
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
||||||
|
|
||||||
|
err = read_chunk (node->data->disk, ret,
|
||||||
|
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
||||||
|
grub_le_to_cpu64 (node->data->sb.inodeoffset)
|
||||||
|
+ node->ino_chunk,
|
||||||
|
node->ino_offset + (node->ino.symlink.name
|
||||||
|
- (char *) &node->ino));
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
grub_free (ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret[grub_le_to_cpu32 (node->ino.symlink.namelen)] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
int NESTED_FUNC_ATTR
|
||||||
|
(*hook) (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node))
|
||||||
|
{
|
||||||
|
grub_uint32_t off = grub_le_to_cpu16 (dir->ino.dir.offset);
|
||||||
|
grub_uint32_t endoff;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* FIXME: why - 3 ? */
|
||||||
|
endoff = grub_le_to_cpu32 (dir->ino.dir.size) + off - 3;
|
||||||
|
|
||||||
|
while (off < endoff)
|
||||||
|
{
|
||||||
|
struct grub_squash_dirent_header dh;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
err = read_chunk (dir->data->disk, &dh, sizeof (dh),
|
||||||
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
|
if (err)
|
||||||
|
return 0;
|
||||||
|
off += sizeof (dh);
|
||||||
|
for (i = 0; i < (unsigned) grub_le_to_cpu16 (dh.nelems) + 1; i++)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int r;
|
||||||
|
struct grub_fshelp_node *node;
|
||||||
|
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
||||||
|
struct grub_squash_dirent di;
|
||||||
|
struct grub_squash_inode ino;
|
||||||
|
|
||||||
|
err = read_chunk (dir->data->disk, &di, sizeof (di),
|
||||||
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
|
if (err)
|
||||||
|
return 0;
|
||||||
|
off += sizeof (di);
|
||||||
|
|
||||||
|
err = read_chunk (dir->data->disk, &ino, sizeof (ino),
|
||||||
|
grub_le_to_cpu64 (dir->data->sb.inodeoffset)
|
||||||
|
+ grub_le_to_cpu32 (dh.ino_chunk),
|
||||||
|
grub_cpu_to_le16 (di.ino_offset));
|
||||||
|
if (err)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
err = read_chunk (dir->data->disk, buf,
|
||||||
|
grub_le_to_cpu16 (di.namelen) + 1,
|
||||||
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
|
+ grub_le_to_cpu32 (dir->ino.dir.chunk), off);
|
||||||
|
if (err)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
off += grub_le_to_cpu16 (di.namelen) + 1;
|
||||||
|
buf[grub_le_to_cpu16 (di.namelen) + 1] = 0;
|
||||||
|
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR)
|
||||||
|
filetype = GRUB_FSHELP_DIR;
|
||||||
|
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
||||||
|
filetype = GRUB_FSHELP_SYMLINK;
|
||||||
|
|
||||||
|
node = grub_malloc (sizeof (*node));
|
||||||
|
if (! node)
|
||||||
|
return 0;
|
||||||
|
*node = *dir;
|
||||||
|
node->ino = ino;
|
||||||
|
node->ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
||||||
|
node->ino_offset = grub_le_to_cpu16 (di.ino_offset);
|
||||||
|
|
||||||
|
r = hook (buf, filetype, node);
|
||||||
|
|
||||||
|
grub_free (buf);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root)
|
||||||
|
{
|
||||||
|
grub_memset (root, 0, sizeof (*root));
|
||||||
|
root->data = data;
|
||||||
|
|
||||||
|
return read_chunk (data->disk, &root->ino, sizeof (root->ino),
|
||||||
|
grub_le_to_cpu64 (data->sb.inodeoffset)
|
||||||
|
+ grub_le_to_cpu16 (data->sb.root_ino_chunk),
|
||||||
|
grub_cpu_to_le16 (data->sb.root_ino_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_squash_dir (grub_device_t device, const char *path,
|
||||||
|
int (*hook) (const char *filename,
|
||||||
|
const struct grub_dirhook_info *info))
|
||||||
|
{
|
||||||
|
auto int NESTED_FUNC_ATTR iterate (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node);
|
||||||
|
|
||||||
|
int NESTED_FUNC_ATTR iterate (const char *filename,
|
||||||
|
enum grub_fshelp_filetype filetype,
|
||||||
|
grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
struct grub_dirhook_info info;
|
||||||
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_le_to_cpu32 (node->ino.mtime);
|
||||||
|
return hook (filename, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_squash_data *data = 0;
|
||||||
|
struct grub_fshelp_node *fdiro = 0;
|
||||||
|
struct grub_fshelp_node root;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
data = squash_mount (device->disk);
|
||||||
|
if (! data)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
err = make_root_node (data, &root);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir,
|
||||||
|
grub_squash_read_symlink, GRUB_FSHELP_DIR);
|
||||||
|
if (!grub_errno)
|
||||||
|
grub_squash_iterate_dir (fdiro, iterate);
|
||||||
|
|
||||||
|
grub_free (data);
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_squash_open (struct grub_file *file, const char *name)
|
||||||
|
{
|
||||||
|
struct grub_squash_data *data = 0;
|
||||||
|
struct grub_fshelp_node *fdiro = 0;
|
||||||
|
struct grub_fshelp_node root;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
data = squash_mount (file->device->disk);
|
||||||
|
if (! data)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
err = make_root_node (data, &root);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir,
|
||||||
|
grub_squash_read_symlink, GRUB_FSHELP_REG);
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_free (data);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->data = data;
|
||||||
|
data->ino = fdiro->ino;
|
||||||
|
file->size = grub_le_to_cpu32 (fdiro->ino.file.size);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
grub_squash_read_data (struct grub_squash_data *data,
|
||||||
|
grub_disk_t disk, const struct grub_squash_inode *ino,
|
||||||
|
grub_off_t off, char *buf, grub_size_t len)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_uint64_t a, b;
|
||||||
|
int compressed = 0;
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff)
|
||||||
|
{
|
||||||
|
if (grub_le_to_cpu32 (ino->file.chunk))
|
||||||
|
a = grub_le_to_cpu32 (ino->file.chunk);
|
||||||
|
else
|
||||||
|
a = sizeof (struct grub_squash_super);
|
||||||
|
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct grub_squash_frag_desc frag;
|
||||||
|
err = read_chunk (disk, &frag, sizeof (frag),
|
||||||
|
data->fragments, sizeof (frag)
|
||||||
|
* grub_le_to_cpu16 (ino->file.fragment));
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk);
|
||||||
|
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
b = grub_le_to_cpu32 (data->ino.file.offset) + off;
|
||||||
|
|
||||||
|
/* FIXME: cache uncompressed chunks. */
|
||||||
|
if (compressed)
|
||||||
|
err = grub_zlib_disk_read (disk, a, b, buf, len);
|
||||||
|
else
|
||||||
|
err = grub_disk_read (disk, (a + b) >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
(a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf);
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
grub_squash_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
{
|
||||||
|
struct grub_squash_data *data = file->data;
|
||||||
|
|
||||||
|
return grub_squash_read_data (data, file->device->disk, &data->ino,
|
||||||
|
file->offset, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_squash_close (grub_file_t file)
|
||||||
|
{
|
||||||
|
grub_free (file->data);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_squash_mtime (grub_device_t dev, grub_int32_t *tm)
|
||||||
|
{
|
||||||
|
struct grub_squash_data *data = 0;
|
||||||
|
|
||||||
|
data = squash_mount (dev->disk);
|
||||||
|
if (! data)
|
||||||
|
return grub_errno;
|
||||||
|
*tm = grub_le_to_cpu32 (data->sb.creation_time);
|
||||||
|
grub_free (data);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_fs grub_squash_fs =
|
||||||
|
{
|
||||||
|
.name = "squash4",
|
||||||
|
.dir = grub_squash_dir,
|
||||||
|
.open = grub_squash_open,
|
||||||
|
.read = grub_squash_read,
|
||||||
|
.close = grub_squash_close,
|
||||||
|
.mtime = grub_squash_mtime,
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
.reserved_first_sector = 0,
|
||||||
|
#endif
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(squash4)
|
||||||
|
{
|
||||||
|
grub_fs_register (&grub_squash_fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(squash4)
|
||||||
|
{
|
||||||
|
grub_fs_unregister (&grub_squash_fs);
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/datetime.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -885,6 +886,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
|
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
|
||||||
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
|
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
|
||||||
|
if (child->fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK)
|
||||||
|
type = GRUB_FSHELP_SYMLINK;
|
||||||
|
|
||||||
if ((grub_udf_read_file (dir, 0, offset,
|
if ((grub_udf_read_file (dir, 0, offset,
|
||||||
dirent.file_ident_length,
|
dirent.file_ident_length,
|
||||||
|
@ -912,6 +915,25 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
grub_ufs_read_symlink (grub_fshelp_node_t node)
|
||||||
|
{
|
||||||
|
grub_size_t sz = U64 (node->fe.file_size);
|
||||||
|
grub_uint8_t *raw;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if (sz < 4)
|
||||||
|
return NULL;
|
||||||
|
raw = grub_malloc (sz - 4);
|
||||||
|
if (!raw)
|
||||||
|
return NULL;
|
||||||
|
if (grub_udf_read_file (node, NULL, 4, sz - 4, (char *) raw) < 0)
|
||||||
|
return NULL;
|
||||||
|
ret = read_string (raw, sz - 4);
|
||||||
|
grub_free (raw);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_udf_dir (grub_device_t device, const char *path,
|
grub_udf_dir (grub_device_t device, const char *path,
|
||||||
int (*hook) (const char *filename,
|
int (*hook) (const char *filename,
|
||||||
|
@ -930,8 +952,36 @@ grub_udf_dir (grub_device_t device, const char *path,
|
||||||
grub_fshelp_node_t node)
|
grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
|
const struct grub_udf_timestamp *tstamp = NULL;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
|
if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
|
||||||
|
tstamp = &node->fe.modification_time;
|
||||||
|
else if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE)
|
||||||
|
tstamp = &node->efe.modification_time;
|
||||||
|
|
||||||
|
if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000)
|
||||||
|
{
|
||||||
|
grub_int16_t tz;
|
||||||
|
struct grub_datetime datetime;
|
||||||
|
|
||||||
|
datetime.year = U16 (tstamp->year);
|
||||||
|
datetime.month = tstamp->month;
|
||||||
|
datetime.day = tstamp->day;
|
||||||
|
datetime.hour = tstamp->hour;
|
||||||
|
datetime.minute = tstamp->minute;
|
||||||
|
datetime.second = tstamp->second;
|
||||||
|
|
||||||
|
tz = U16 (tstamp->type_and_timezone) & 0xfff;
|
||||||
|
if (tz & 0x800)
|
||||||
|
tz |= 0xf000;
|
||||||
|
if (tz == -2047)
|
||||||
|
tz = 0;
|
||||||
|
|
||||||
|
info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime);
|
||||||
|
|
||||||
|
info.mtime -= 60 * tz;
|
||||||
|
}
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
}
|
}
|
||||||
|
@ -947,7 +997,8 @@ grub_udf_dir (grub_device_t device, const char *path,
|
||||||
|
|
||||||
if (grub_fshelp_find_file (path, &rootnode,
|
if (grub_fshelp_find_file (path, &rootnode,
|
||||||
&foundnode,
|
&foundnode,
|
||||||
grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR))
|
grub_udf_iterate_dir, grub_ufs_read_symlink,
|
||||||
|
GRUB_FSHELP_DIR))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_udf_iterate_dir (foundnode, iterate);
|
grub_udf_iterate_dir (foundnode, iterate);
|
||||||
|
@ -981,7 +1032,8 @@ grub_udf_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
if (grub_fshelp_find_file (name, &rootnode,
|
if (grub_fshelp_find_file (name, &rootnode,
|
||||||
&foundnode,
|
&foundnode,
|
||||||
grub_udf_iterate_dir, 0, GRUB_FSHELP_REG))
|
grub_udf_iterate_dir, grub_ufs_read_symlink,
|
||||||
|
GRUB_FSHELP_REG))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
file->data = foundnode;
|
file->data = foundnode;
|
||||||
|
|
|
@ -100,13 +100,22 @@ struct grub_xfs_btree_root
|
||||||
grub_uint64_t keys[1];
|
grub_uint64_t keys[1];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct grub_xfs_time
|
||||||
|
{
|
||||||
|
grub_uint32_t sec;
|
||||||
|
grub_uint32_t nanosec;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_xfs_inode
|
struct grub_xfs_inode
|
||||||
{
|
{
|
||||||
grub_uint8_t magic[2];
|
grub_uint8_t magic[2];
|
||||||
grub_uint16_t mode;
|
grub_uint16_t mode;
|
||||||
grub_uint8_t version;
|
grub_uint8_t version;
|
||||||
grub_uint8_t format;
|
grub_uint8_t format;
|
||||||
grub_uint8_t unused2[50];
|
grub_uint8_t unused2[26];
|
||||||
|
struct grub_xfs_time atime;
|
||||||
|
struct grub_xfs_time mtime;
|
||||||
|
struct grub_xfs_time ctime;
|
||||||
grub_uint64_t size;
|
grub_uint64_t size;
|
||||||
grub_uint64_t nblocks;
|
grub_uint64_t nblocks;
|
||||||
grub_uint32_t extsize;
|
grub_uint32_t extsize;
|
||||||
|
@ -654,6 +663,11 @@ grub_xfs_dir (grub_device_t device, const char *path,
|
||||||
{
|
{
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
if (node->inode_read)
|
||||||
|
{
|
||||||
|
info.mtimeset = 1;
|
||||||
|
info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
|
||||||
|
}
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return hook (filename, &info);
|
return hook (filename, &info);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#! /bin/sh -e
|
#! /bin/sh
|
||||||
#
|
set -e
|
||||||
|
|
||||||
# Copyright (C) 2010 Free Software Foundation, Inc.
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This gensymlist.sh is free software; the author
|
# This gensymlist.sh is free software; the author
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#! /bin/sh -e
|
#! /bin/sh
|
||||||
#
|
set -e
|
||||||
|
|
||||||
# Copyright (C) 2010 Free Software Foundation, Inc.
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This gensymlist.sh is free software; the author
|
# This gensymlist.sh is free software; the author
|
||||||
|
|
|
@ -47,7 +47,7 @@ grub_register_exported_symbols (void)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
struct symtab { const char *name; void *addr; };
|
struct symtab { const char *name; void *addr; int isfunc; };
|
||||||
struct symtab *p;
|
struct symtab *p;
|
||||||
static struct symtab tab[] =
|
static struct symtab tab[] =
|
||||||
{
|
{
|
||||||
|
@ -56,16 +56,16 @@ EOF
|
||||||
(while read LINE; do echo $LINE; done) \
|
(while read LINE; do echo $LINE; done) \
|
||||||
| grep -v '^#' \
|
| grep -v '^#' \
|
||||||
| sed -n \
|
| sed -n \
|
||||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/ {"\1", \1},/;p;}' \
|
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/ {"\1", \1, 1},/;p;}' \
|
||||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/ {"\1", \&\1},/;p;}' \
|
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/ {"\1", \&\1, 0},/;p;}' \
|
||||||
| sort -u
|
| sort -u
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
{0, 0}
|
{0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (tab) > sizeof (tab[0]));
|
COMPILE_TIME_ASSERT (sizeof (tab) > sizeof (tab[0]));
|
||||||
for (p = tab; p->name; p++)
|
for (p = tab; p->name; p++)
|
||||||
grub_dl_register_symbol (p->name, p->addr, 0);
|
grub_dl_register_symbol (p->name, p->addr, p->isfunc, 0);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct grub_gui_label
|
||||||
char *text;
|
char *text;
|
||||||
char *template;
|
char *template;
|
||||||
grub_font_t font;
|
grub_font_t font;
|
||||||
grub_gui_color_t color;
|
grub_video_rgba_color_t color;
|
||||||
int value;
|
int value;
|
||||||
enum align_mode align;
|
enum align_mode align;
|
||||||
};
|
};
|
||||||
|
@ -107,7 +107,7 @@ label_paint (void *vself, const grub_video_rect_t *region)
|
||||||
grub_gui_set_viewport (&self->bounds, &vpsave);
|
grub_gui_set_viewport (&self->bounds, &vpsave);
|
||||||
grub_font_draw_string (self->text,
|
grub_font_draw_string (self->text,
|
||||||
self->font,
|
self->font,
|
||||||
grub_gui_map_color (self->color),
|
grub_video_map_rgba_color (self->color),
|
||||||
left_x,
|
left_x,
|
||||||
grub_font_get_ascent (self->font));
|
grub_font_get_ascent (self->font));
|
||||||
grub_gui_restore_viewport (&vpsave);
|
grub_gui_restore_viewport (&vpsave);
|
||||||
|
@ -186,7 +186,7 @@ label_set_property (void *vself, const char *name, const char *value)
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "color") == 0)
|
else if (grub_strcmp (name, "color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->color);
|
grub_video_parse_color (value, &self->color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "align") == 0)
|
else if (grub_strcmp (name, "align") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,9 +41,9 @@ struct grub_gui_list_impl
|
||||||
int item_spacing;
|
int item_spacing;
|
||||||
grub_font_t item_font;
|
grub_font_t item_font;
|
||||||
grub_font_t selected_item_font;
|
grub_font_t selected_item_font;
|
||||||
grub_gui_color_t item_color;
|
grub_video_rgba_color_t item_color;
|
||||||
int selected_item_color_set;
|
int selected_item_color_set;
|
||||||
grub_gui_color_t selected_item_color;
|
grub_video_rgba_color_t selected_item_color;
|
||||||
|
|
||||||
int draw_scrollbar;
|
int draw_scrollbar;
|
||||||
int need_to_recreate_scrollbar;
|
int need_to_recreate_scrollbar;
|
||||||
|
@ -269,13 +269,13 @@ draw_menu (list_impl_t self, int num_shown_items)
|
||||||
(is_selected && self->selected_item_font
|
(is_selected && self->selected_item_font
|
||||||
? self->selected_item_font
|
? self->selected_item_font
|
||||||
: self->item_font);
|
: self->item_font);
|
||||||
grub_gui_color_t text_color =
|
grub_video_rgba_color_t text_color =
|
||||||
((is_selected && self->selected_item_color_set)
|
((is_selected && self->selected_item_color_set)
|
||||||
? self->selected_item_color
|
? self->selected_item_color
|
||||||
: self->item_color);
|
: self->item_color);
|
||||||
grub_font_draw_string (item_title,
|
grub_font_draw_string (item_title,
|
||||||
font,
|
font,
|
||||||
grub_gui_map_color (text_color),
|
grub_video_map_rgba_color (text_color),
|
||||||
sel_leftpad + self->icon_width + icon_text_space,
|
sel_leftpad + self->icon_width + icon_text_space,
|
||||||
(item_top + (item_height - (ascent + descent))
|
(item_top + (item_height - (ascent + descent))
|
||||||
/ 2 + ascent));
|
/ 2 + ascent));
|
||||||
|
@ -431,7 +431,7 @@ list_set_property (void *vself, const char *name, const char *value)
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "item_color") == 0)
|
else if (grub_strcmp (name, "item_color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->item_color);
|
grub_video_parse_color (value, &self->item_color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "selected_item_color") == 0)
|
else if (grub_strcmp (name, "selected_item_color") == 0)
|
||||||
{
|
{
|
||||||
|
@ -441,7 +441,7 @@ list_set_property (void *vself, const char *name, const char *value)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (grub_gui_parse_color (value, &self->selected_item_color)
|
if (grub_video_parse_color (value, &self->selected_item_color)
|
||||||
== GRUB_ERR_NONE)
|
== GRUB_ERR_NONE)
|
||||||
self->selected_item_color_set = 1;
|
self->selected_item_color_set = 1;
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,7 @@ grub_gui_list_new (void)
|
||||||
{
|
{
|
||||||
list_impl_t self;
|
list_impl_t self;
|
||||||
grub_font_t default_font;
|
grub_font_t default_font;
|
||||||
grub_gui_color_t default_fg_color;
|
grub_video_rgba_color_t default_fg_color;
|
||||||
|
|
||||||
self = grub_zalloc (sizeof (*self));
|
self = grub_zalloc (sizeof (*self));
|
||||||
if (! self)
|
if (! self)
|
||||||
|
@ -576,7 +576,7 @@ grub_gui_list_new (void)
|
||||||
self->visible = 1;
|
self->visible = 1;
|
||||||
|
|
||||||
default_font = grub_font_get ("Unknown Regular 16");
|
default_font = grub_font_get ("Unknown Regular 16");
|
||||||
default_fg_color = grub_gui_color_rgb (0, 0, 0);
|
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
||||||
|
|
||||||
self->icon_width = 32;
|
self->icon_width = 32;
|
||||||
self->icon_height = 32;
|
self->icon_height = 32;
|
||||||
|
|
|
@ -40,10 +40,10 @@ struct grub_gui_progress_bar
|
||||||
int show_text;
|
int show_text;
|
||||||
char *template;
|
char *template;
|
||||||
grub_font_t font;
|
grub_font_t font;
|
||||||
grub_gui_color_t text_color;
|
grub_video_rgba_color_t text_color;
|
||||||
grub_gui_color_t border_color;
|
grub_video_rgba_color_t border_color;
|
||||||
grub_gui_color_t bg_color;
|
grub_video_rgba_color_t bg_color;
|
||||||
grub_gui_color_t fg_color;
|
grub_video_rgba_color_t fg_color;
|
||||||
|
|
||||||
char *theme_dir;
|
char *theme_dir;
|
||||||
int need_to_recreate_pixmaps;
|
int need_to_recreate_pixmaps;
|
||||||
|
@ -109,7 +109,7 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self)
|
||||||
f.height = self->bounds.height - 2;
|
f.height = self->bounds.height - 2;
|
||||||
|
|
||||||
/* Border. */
|
/* Border. */
|
||||||
grub_video_fill_rect (grub_gui_map_color (self->border_color),
|
grub_video_fill_rect (grub_video_map_rgba_color (self->border_color),
|
||||||
f.x - 1, f.y - 1,
|
f.x - 1, f.y - 1,
|
||||||
f.width + 2, f.height + 2);
|
f.width + 2, f.height + 2);
|
||||||
|
|
||||||
|
@ -117,12 +117,12 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self)
|
||||||
int barwidth = (f.width
|
int barwidth = (f.width
|
||||||
* (self->value - self->start)
|
* (self->value - self->start)
|
||||||
/ (self->end - self->start));
|
/ (self->end - self->start));
|
||||||
grub_video_fill_rect (grub_gui_map_color (self->bg_color),
|
grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color),
|
||||||
f.x + barwidth, f.y,
|
f.x + barwidth, f.y,
|
||||||
f.width - barwidth, f.height);
|
f.width - barwidth, f.height);
|
||||||
|
|
||||||
/* Bar foreground. */
|
/* Bar foreground. */
|
||||||
grub_video_fill_rect (grub_gui_map_color (self->fg_color),
|
grub_video_fill_rect (grub_video_map_rgba_color (self->fg_color),
|
||||||
f.x, f.y,
|
f.x, f.y,
|
||||||
barwidth, f.height);
|
barwidth, f.height);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,8 @@ draw_text (grub_gui_progress_bar_t self)
|
||||||
if (self->template)
|
if (self->template)
|
||||||
{
|
{
|
||||||
grub_font_t font = self->font;
|
grub_font_t font = self->font;
|
||||||
grub_video_color_t text_color = grub_gui_map_color (self->text_color);
|
grub_video_color_t text_color =
|
||||||
|
grub_video_map_rgba_color (self->text_color);
|
||||||
int width = self->bounds.width;
|
int width = self->bounds.width;
|
||||||
int height = self->bounds.height;
|
int height = self->bounds.height;
|
||||||
char *text;
|
char *text;
|
||||||
|
@ -298,19 +299,19 @@ progress_bar_set_property (void *vself, const char *name, const char *value)
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "text_color") == 0)
|
else if (grub_strcmp (name, "text_color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->text_color);
|
grub_video_parse_color (value, &self->text_color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "border_color") == 0)
|
else if (grub_strcmp (name, "border_color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->border_color);
|
grub_video_parse_color (value, &self->border_color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "bg_color") == 0)
|
else if (grub_strcmp (name, "bg_color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->bg_color);
|
grub_video_parse_color (value, &self->bg_color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "fg_color") == 0)
|
else if (grub_strcmp (name, "fg_color") == 0)
|
||||||
{
|
{
|
||||||
grub_gui_parse_color (value, &self->fg_color);
|
grub_video_parse_color (value, &self->fg_color);
|
||||||
}
|
}
|
||||||
else if (grub_strcmp (name, "bar_style") == 0)
|
else if (grub_strcmp (name, "bar_style") == 0)
|
||||||
{
|
{
|
||||||
|
@ -379,9 +380,9 @@ grub_gui_progress_bar_new (void)
|
||||||
self->progress.component.ops = &progress_bar_ops;
|
self->progress.component.ops = &progress_bar_ops;
|
||||||
self->visible = 1;
|
self->visible = 1;
|
||||||
self->font = grub_font_get ("Unknown Regular 16");
|
self->font = grub_font_get ("Unknown Regular 16");
|
||||||
grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 };
|
grub_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 };
|
||||||
grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 };
|
grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 };
|
||||||
grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 };
|
grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 };
|
||||||
self->text_color = black;
|
self->text_color = black;
|
||||||
self->border_color = black;
|
self->border_color = black;
|
||||||
self->bg_color = gray;
|
self->bg_color = gray;
|
||||||
|
|
|
@ -204,124 +204,3 @@ grub_get_dirname (const char *file_path)
|
||||||
|
|
||||||
return grub_new_substring (file_path, 0, last_slash + 1);
|
return grub_new_substring (file_path, 0, last_slash + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
|
||||||
my_isxdigit (char c)
|
|
||||||
{
|
|
||||||
return ((c >= '0' && c <= '9')
|
|
||||||
|| (c >= 'a' && c <= 'f')
|
|
||||||
|| (c >= 'A' && c <= 'F'));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
parse_hex_color_component (const char *s, unsigned start, unsigned end)
|
|
||||||
{
|
|
||||||
unsigned len;
|
|
||||||
char buf[3];
|
|
||||||
|
|
||||||
len = end - start;
|
|
||||||
/* Check the limits so we don't overrun the buffer. */
|
|
||||||
if (len < 1 || len > 2)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (len == 1)
|
|
||||||
{
|
|
||||||
buf[0] = s[start]; /* Get the first and only hex digit. */
|
|
||||||
buf[1] = buf[0]; /* Duplicate the hex digit. */
|
|
||||||
}
|
|
||||||
else if (len == 2)
|
|
||||||
{
|
|
||||||
buf[0] = s[start];
|
|
||||||
buf[1] = s[start + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[2] = '\0';
|
|
||||||
|
|
||||||
return grub_strtoul (buf, 0, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA",
|
|
||||||
"#RRGGBB", or "#RRGGBBAA". */
|
|
||||||
grub_err_t
|
|
||||||
grub_gui_parse_color (const char *s, grub_gui_color_t *color)
|
|
||||||
{
|
|
||||||
grub_gui_color_t c;
|
|
||||||
|
|
||||||
/* Skip whitespace. */
|
|
||||||
while (*s && grub_isspace (*s))
|
|
||||||
s++;
|
|
||||||
|
|
||||||
if (*s == '#')
|
|
||||||
{
|
|
||||||
/* HTML-style. Number if hex digits:
|
|
||||||
[6] #RRGGBB [3] #RGB
|
|
||||||
[8] #RRGGBBAA [4] #RGBA */
|
|
||||||
|
|
||||||
s++; /* Skip the '#'. */
|
|
||||||
/* Count the hexits to determine the format. */
|
|
||||||
int hexits = 0;
|
|
||||||
const char *end = s;
|
|
||||||
while (my_isxdigit (*end))
|
|
||||||
{
|
|
||||||
end++;
|
|
||||||
hexits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the color components based on the format. */
|
|
||||||
if (hexits == 3 || hexits == 4)
|
|
||||||
{
|
|
||||||
c.red = parse_hex_color_component (s, 0, 1);
|
|
||||||
c.green = parse_hex_color_component (s, 1, 2);
|
|
||||||
c.blue = parse_hex_color_component (s, 2, 3);
|
|
||||||
if (hexits == 4)
|
|
||||||
c.alpha = parse_hex_color_component (s, 3, 4);
|
|
||||||
else
|
|
||||||
c.alpha = 255;
|
|
||||||
}
|
|
||||||
else if (hexits == 6 || hexits == 8)
|
|
||||||
{
|
|
||||||
c.red = parse_hex_color_component (s, 0, 2);
|
|
||||||
c.green = parse_hex_color_component (s, 2, 4);
|
|
||||||
c.blue = parse_hex_color_component (s, 4, 6);
|
|
||||||
if (hexits == 8)
|
|
||||||
c.alpha = parse_hex_color_component (s, 6, 8);
|
|
||||||
else
|
|
||||||
c.alpha = 255;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
"invalid HTML-type color string `%s'", s);
|
|
||||||
}
|
|
||||||
else if (grub_isdigit (*s))
|
|
||||||
{
|
|
||||||
/* Comma separated decimal values. */
|
|
||||||
c.red = grub_strtoul (s, 0, 0);
|
|
||||||
if ((s = grub_strchr (s, ',')) == 0)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
"missing 1st comma separator in color `%s'", s);
|
|
||||||
s++;
|
|
||||||
c.green = grub_strtoul (s, 0, 0);
|
|
||||||
if ((s = grub_strchr (s, ',')) == 0)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
"missing 2nd comma separator in color `%s'", s);
|
|
||||||
s++;
|
|
||||||
c.blue = grub_strtoul (s, 0, 0);
|
|
||||||
if ((s = grub_strchr (s, ',')) == 0)
|
|
||||||
c.alpha = 255;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s++;
|
|
||||||
c.alpha = grub_strtoul (s, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (! grub_gui_get_named_color (s, &c))
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
"invalid named color `%s'", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
*color = c;
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
|
@ -135,11 +135,11 @@ theme_set_string (grub_gfxmenu_view_t view,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
else if (! grub_strcmp ("title-color", name))
|
else if (! grub_strcmp ("title-color", name))
|
||||||
grub_gui_parse_color (value, &view->title_color);
|
grub_video_parse_color (value, &view->title_color);
|
||||||
else if (! grub_strcmp ("message-color", name))
|
else if (! grub_strcmp ("message-color", name))
|
||||||
grub_gui_parse_color (value, &view->message_color);
|
grub_video_parse_color (value, &view->message_color);
|
||||||
else if (! grub_strcmp ("message-bg-color", name))
|
else if (! grub_strcmp ("message-bg-color", name))
|
||||||
grub_gui_parse_color (value, &view->message_bg_color);
|
grub_video_parse_color (value, &view->message_bg_color);
|
||||||
else if (! grub_strcmp ("desktop-image", name))
|
else if (! grub_strcmp ("desktop-image", name))
|
||||||
{
|
{
|
||||||
struct grub_video_bitmap *raw_bitmap;
|
struct grub_video_bitmap *raw_bitmap;
|
||||||
|
@ -170,7 +170,7 @@ theme_set_string (grub_gfxmenu_view_t view,
|
||||||
view->desktop_image = scaled_bitmap;
|
view->desktop_image = scaled_bitmap;
|
||||||
}
|
}
|
||||||
else if (! grub_strcmp ("desktop-color", name))
|
else if (! grub_strcmp ("desktop-color", name))
|
||||||
grub_gui_parse_color (value, &view->desktop_color);
|
grub_video_parse_color (value, &view->desktop_color);
|
||||||
else if (! grub_strcmp ("terminal-box", name))
|
else if (! grub_strcmp ("terminal-box", name))
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
|
@ -50,8 +50,8 @@ grub_gfxmenu_view_new (const char *theme_path,
|
||||||
{
|
{
|
||||||
grub_gfxmenu_view_t view;
|
grub_gfxmenu_view_t view;
|
||||||
grub_font_t default_font;
|
grub_font_t default_font;
|
||||||
grub_gui_color_t default_fg_color;
|
grub_video_rgba_color_t default_fg_color;
|
||||||
grub_gui_color_t default_bg_color;
|
grub_video_rgba_color_t default_bg_color;
|
||||||
|
|
||||||
view = grub_malloc (sizeof (*view));
|
view = grub_malloc (sizeof (*view));
|
||||||
if (! view)
|
if (! view)
|
||||||
|
@ -63,8 +63,8 @@ grub_gfxmenu_view_new (const char *theme_path,
|
||||||
view->screen.height = height;
|
view->screen.height = height;
|
||||||
|
|
||||||
default_font = grub_font_get ("Unknown Regular 16");
|
default_font = grub_font_get ("Unknown Regular 16");
|
||||||
default_fg_color = grub_gui_color_rgb (0, 0, 0);
|
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
||||||
default_bg_color = grub_gui_color_rgb (255, 255, 255);
|
default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
|
||||||
|
|
||||||
view->canvas = 0;
|
view->canvas = 0;
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ redraw_background (grub_gfxmenu_view_t view,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
grub_video_fill_rect (grub_gui_map_color (view->desktop_color),
|
grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color),
|
||||||
bounds->x, bounds->y,
|
bounds->x, bounds->y,
|
||||||
bounds->width, bounds->height);
|
bounds->width, bounds->height);
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ draw_title (grub_gfxmenu_view_t view)
|
||||||
int y = 40 + grub_font_get_ascent (view->title_font);
|
int y = 40 + grub_font_get_ascent (view->title_font);
|
||||||
grub_font_draw_string (view->title_text,
|
grub_font_draw_string (view->title_text,
|
||||||
view->title_font,
|
view->title_font,
|
||||||
grub_gui_map_color (view->title_color),
|
grub_video_map_rgba_color (view->title_color),
|
||||||
x, y);
|
x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +244,13 @@ draw_message (grub_gfxmenu_view_t view)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
grub_font_t font = view->message_font;
|
grub_font_t font = view->message_font;
|
||||||
grub_video_color_t color = grub_gui_map_color (view->message_color);
|
grub_video_color_t color = grub_video_map_rgba_color (view->message_color);
|
||||||
|
|
||||||
/* Border. */
|
/* Border. */
|
||||||
grub_video_fill_rect (color,
|
grub_video_fill_rect (color,
|
||||||
f.x-1, f.y-1, f.width+2, f.height+2);
|
f.x-1, f.y-1, f.width+2, f.height+2);
|
||||||
/* Fill. */
|
/* Fill. */
|
||||||
grub_video_fill_rect (grub_gui_map_color (view->message_bg_color),
|
grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color),
|
||||||
f.x, f.y, f.width, f.height);
|
f.x, f.y, f.width, f.height);
|
||||||
|
|
||||||
/* Center the text. */
|
/* Center the text. */
|
||||||
|
|
|
@ -106,7 +106,7 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
grub_size_t res = len;
|
grub_size_t res = len;
|
||||||
grub_bufio_t bufio = file->data;
|
grub_bufio_t bufio = file->data;
|
||||||
grub_uint32_t pos;
|
grub_uint64_t pos;
|
||||||
|
|
||||||
if ((file->offset >= bufio->file->offset) &&
|
if ((file->offset >= bufio->file->offset) &&
|
||||||
(file->offset < bufio->file->offset + bufio->buffer_len))
|
(file->offset < bufio->file->offset + bufio->buffer_len))
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <grub/fs.h>
|
#include <grub/fs.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
@ -64,6 +65,9 @@ struct grub_gzio
|
||||||
/* If input is in memory following fields are used instead of file. */
|
/* If input is in memory following fields are used instead of file. */
|
||||||
grub_size_t mem_input_size, mem_input_off;
|
grub_size_t mem_input_size, mem_input_off;
|
||||||
grub_uint8_t *mem_input;
|
grub_uint8_t *mem_input;
|
||||||
|
grub_disk_addr_t disk_input_off;
|
||||||
|
grub_disk_addr_t disk_input_start;
|
||||||
|
grub_disk_t disk_input;
|
||||||
/* The offset at which the data starts in the underlying file. */
|
/* The offset at which the data starts in the underlying file. */
|
||||||
grub_off_t data_offset;
|
grub_off_t data_offset;
|
||||||
/* The type of current block. */
|
/* The type of current block. */
|
||||||
|
@ -384,8 +388,21 @@ get_byte (grub_gzio_t gzio)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
|
if (gzio->disk_input && (gzio->disk_input_off == gzio->data_offset
|
||||||
|| gzio->inbuf_d == INBUFSIZ)
|
|| gzio->inbuf_d == INBUFSIZ))
|
||||||
|
{
|
||||||
|
grub_disk_addr_t d = gzio->disk_input_start + gzio->disk_input_off;
|
||||||
|
gzio->inbuf_d = 0;
|
||||||
|
grub_disk_read (gzio->disk_input,
|
||||||
|
d >> GRUB_DISK_SECTOR_BITS,
|
||||||
|
d & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
INBUFSIZ, gzio->inbuf);
|
||||||
|
gzio->disk_input_off += INBUFSIZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gzio->file && (grub_file_tell (gzio->file)
|
||||||
|
== (grub_off_t) gzio->data_offset
|
||||||
|
|| gzio->inbuf_d == INBUFSIZ))
|
||||||
{
|
{
|
||||||
gzio->inbuf_d = 0;
|
gzio->inbuf_d = 0;
|
||||||
grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
|
grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
|
||||||
|
@ -403,8 +420,10 @@ gzio_seek (grub_gzio_t gzio, grub_off_t off)
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
"attempt to seek outside of the file");
|
"attempt to seek outside of the file");
|
||||||
else
|
else
|
||||||
gzio->mem_input_off = gzio->data_offset;
|
gzio->mem_input_off = off;
|
||||||
}
|
}
|
||||||
|
else if (gzio->disk_input)
|
||||||
|
gzio->disk_input_off = off;
|
||||||
else
|
else
|
||||||
grub_file_seek (gzio->file, off);
|
grub_file_seek (gzio->file, off);
|
||||||
}
|
}
|
||||||
|
@ -1298,6 +1317,34 @@ grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_zlib_disk_read (grub_disk_t disk, grub_disk_addr_t zlibstart,
|
||||||
|
grub_off_t off, char *outbuf, grub_size_t outsize)
|
||||||
|
{
|
||||||
|
grub_gzio_t gzio = 0;
|
||||||
|
grub_ssize_t ret;
|
||||||
|
|
||||||
|
gzio = grub_zalloc (sizeof (*gzio));
|
||||||
|
if (! gzio)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
gzio->disk_input_off = 0;
|
||||||
|
gzio->disk_input_start = zlibstart;
|
||||||
|
gzio->disk_input = disk;
|
||||||
|
|
||||||
|
if (!test_zlib_header (gzio))
|
||||||
|
{
|
||||||
|
grub_free (gzio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_gzio_read_real (gzio, off, outbuf, outsize);
|
||||||
|
grub_free (gzio);
|
||||||
|
|
||||||
|
/* FIXME: Check Adler. */
|
||||||
|
return ret < 0 ? grub_errno : GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct grub_fs grub_gzio_fs =
|
static struct grub_fs grub_gzio_fs =
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
#define GRUB_MODULES_MACHINE_READONLY
|
#define GRUB_MODULES_MACHINE_READONLY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EMU
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
grub_dl_t grub_dl_head = 0;
|
grub_dl_t grub_dl_head = 0;
|
||||||
|
@ -86,6 +90,7 @@ struct grub_symbol
|
||||||
struct grub_symbol *next;
|
struct grub_symbol *next;
|
||||||
const char *name;
|
const char *name;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
int isfunc;
|
||||||
grub_dl_t mod; /* The module to which this symbol belongs. */
|
grub_dl_t mod; /* The module to which this symbol belongs. */
|
||||||
};
|
};
|
||||||
typedef struct grub_symbol *grub_symbol_t;
|
typedef struct grub_symbol *grub_symbol_t;
|
||||||
|
@ -110,21 +115,22 @@ grub_symbol_hash (const char *s)
|
||||||
|
|
||||||
/* Resolve the symbol name NAME and return the address.
|
/* Resolve the symbol name NAME and return the address.
|
||||||
Return NULL, if not found. */
|
Return NULL, if not found. */
|
||||||
static void *
|
static grub_symbol_t
|
||||||
grub_dl_resolve_symbol (const char *name)
|
grub_dl_resolve_symbol (const char *name)
|
||||||
{
|
{
|
||||||
grub_symbol_t sym;
|
grub_symbol_t sym;
|
||||||
|
|
||||||
for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
|
for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
|
||||||
if (grub_strcmp (sym->name, name) == 0)
|
if (grub_strcmp (sym->name, name) == 0)
|
||||||
return sym->addr;
|
return sym;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register a symbol with the name NAME and the address ADDR. */
|
/* Register a symbol with the name NAME and the address ADDR. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod)
|
grub_dl_register_symbol (const char *name, void *addr, int isfunc,
|
||||||
|
grub_dl_t mod)
|
||||||
{
|
{
|
||||||
grub_symbol_t sym;
|
grub_symbol_t sym;
|
||||||
unsigned k;
|
unsigned k;
|
||||||
|
@ -147,6 +153,7 @@ grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod)
|
||||||
|
|
||||||
sym->addr = addr;
|
sym->addr = addr;
|
||||||
sym->mod = mod;
|
sym->mod = mod;
|
||||||
|
sym->isfunc = isfunc;
|
||||||
|
|
||||||
k = grub_symbol_hash (name);
|
k = grub_symbol_hash (name);
|
||||||
sym->next = grub_symtab[k];
|
sym->next = grub_symtab[k];
|
||||||
|
@ -225,6 +232,48 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
Elf_Shdr *s;
|
Elf_Shdr *s;
|
||||||
|
grub_size_t tsize = 0, talign = 1;
|
||||||
|
#ifdef __ia64__
|
||||||
|
grub_size_t tramp;
|
||||||
|
grub_size_t got;
|
||||||
|
#endif
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
|
||||||
|
i < e->e_shnum;
|
||||||
|
i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
|
||||||
|
{
|
||||||
|
tsize += ALIGN_UP (s->sh_size, s->sh_addralign);
|
||||||
|
if (talign < s->sh_addralign)
|
||||||
|
talign = s->sh_addralign;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __ia64__
|
||||||
|
grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
|
||||||
|
tramp *= GRUB_IA64_DL_TRAMP_SIZE;
|
||||||
|
got *= sizeof (grub_uint64_t);
|
||||||
|
tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
|
||||||
|
if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
|
||||||
|
talign = GRUB_ARCH_DL_TRAMP_ALIGN;
|
||||||
|
tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN);
|
||||||
|
if (talign < GRUB_ARCH_DL_GOT_ALIGN)
|
||||||
|
talign = GRUB_ARCH_DL_GOT_ALIGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EMU
|
||||||
|
if (talign < 8192 * 16)
|
||||||
|
talign = 8192 * 16;
|
||||||
|
tsize = ALIGN_UP (tsize, 8192 * 16);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mod->base = grub_memalign (talign, tsize);
|
||||||
|
if (!mod->base)
|
||||||
|
return grub_errno;
|
||||||
|
ptr = mod->base;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EMU
|
||||||
|
mprotect (mod->base, tsize, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
|
for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
|
||||||
i < e->e_shnum;
|
i < e->e_shnum;
|
||||||
|
@ -242,12 +291,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||||
{
|
{
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
addr = grub_memalign (s->sh_addralign, s->sh_size);
|
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
|
||||||
if (! addr)
|
addr = ptr;
|
||||||
{
|
ptr += s->sh_size;
|
||||||
grub_free (seg);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (s->sh_type)
|
switch (s->sh_type)
|
||||||
{
|
{
|
||||||
|
@ -270,6 +316,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||||
mod->segment = seg;
|
mod->segment = seg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef __ia64__
|
||||||
|
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
|
||||||
|
mod->tramp = ptr;
|
||||||
|
ptr += tramp;
|
||||||
|
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
|
||||||
|
mod->got = ptr;
|
||||||
|
ptr += got;
|
||||||
|
#endif
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -320,17 +374,20 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||||
/* Resolve a global symbol. */
|
/* Resolve a global symbol. */
|
||||||
if (sym->st_name != 0 && sym->st_shndx == 0)
|
if (sym->st_name != 0 && sym->st_shndx == 0)
|
||||||
{
|
{
|
||||||
sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
|
grub_symbol_t nsym = grub_dl_resolve_symbol (name);
|
||||||
if (! sym->st_value)
|
if (! nsym)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
"symbol not found: `%s'", name);
|
"symbol not found: `%s'", name);
|
||||||
|
sym->st_value = (Elf_Addr) nsym->addr;
|
||||||
|
if (nsym->isfunc)
|
||||||
|
sym->st_info = ELF_ST_INFO (bind, STT_FUNC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
||||||
sym->st_shndx);
|
sym->st_shndx);
|
||||||
if (bind != STB_LOCAL)
|
if (bind != STB_LOCAL)
|
||||||
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
if (grub_dl_register_symbol (name, (void *) sym->st_value, 0, mod))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -338,10 +395,21 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||||
case STT_FUNC:
|
case STT_FUNC:
|
||||||
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
|
||||||
sym->st_shndx);
|
sym->st_shndx);
|
||||||
|
#ifdef __ia64__
|
||||||
|
{
|
||||||
|
/* FIXME: free descriptor once it's not used anymore. */
|
||||||
|
char **desc;
|
||||||
|
desc = grub_malloc (2 * sizeof (char *));
|
||||||
|
if (!desc)
|
||||||
|
return grub_errno;
|
||||||
|
desc[0] = (void *) sym->st_value;
|
||||||
|
desc[1] = mod->base;
|
||||||
|
sym->st_value = (grub_addr_t) desc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (bind != STB_LOCAL)
|
if (bind != STB_LOCAL)
|
||||||
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
if (grub_dl_register_symbol (name, (void *) sym->st_value, 1, mod))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_strcmp (name, "grub_mod_init") == 0)
|
if (grub_strcmp (name, "grub_mod_init") == 0)
|
||||||
mod->init = (void (*) (grub_dl_t)) sym->st_value;
|
mod->init = (void (*) (grub_dl_t)) sym->st_value;
|
||||||
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
||||||
|
@ -626,7 +694,7 @@ grub_dl_load_file (const char *filename)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod->ref_count = 0;
|
mod->ref_count--;
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,8 +751,7 @@ grub_dl_unload (grub_dl_t mod)
|
||||||
{
|
{
|
||||||
depn = dep->next;
|
depn = dep->next;
|
||||||
|
|
||||||
if (! grub_dl_unref (dep->mod))
|
grub_dl_unload (dep->mod);
|
||||||
grub_dl_unload (dep->mod);
|
|
||||||
|
|
||||||
grub_free (dep);
|
grub_free (dep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/efi/console_control.h>
|
#include <grub/efi/console_control.h>
|
||||||
#include <grub/efi/pe32.h>
|
#include <grub/efi/pe32.h>
|
||||||
#include <grub/machine/time.h>
|
#include <grub/machine/time.h>
|
||||||
|
#include <grub/time.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/kernel.h>
|
#include <grub/kernel.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
@ -193,8 +194,8 @@ grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
|
||||||
return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
|
return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_uint32_t
|
grub_uint64_t
|
||||||
grub_get_rtc (void)
|
grub_rtc_get_time_ms (void)
|
||||||
{
|
{
|
||||||
grub_efi_time_t time;
|
grub_efi_time_t time;
|
||||||
grub_efi_runtime_services_t *r;
|
grub_efi_runtime_services_t *r;
|
||||||
|
@ -204,9 +205,14 @@ grub_get_rtc (void)
|
||||||
/* What is possible in this case? */
|
/* What is possible in this case? */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (((time.minute * 60 + time.second) * 1000
|
return ((time.minute * 60 + time.second) * 1000
|
||||||
+ time.nanosecond / 1000000)
|
+ time.nanosecond / 1000000);
|
||||||
* GRUB_TICKS_PER_SECOND / 1000);
|
}
|
||||||
|
|
||||||
|
grub_uint32_t
|
||||||
|
grub_get_rtc (void)
|
||||||
|
{
|
||||||
|
return grub_rtc_get_time_ms ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search the mods section from the PE32/PE32+ image. This code uses
|
/* Search the mods section from the PE32/PE32+ image. This code uses
|
||||||
|
|
13
grub-core/kern/emu/cache.c
Normal file
13
grub-core/kern/emu/cache.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
#if defined(__ia64__)
|
||||||
|
#include <grub/cache.h>
|
||||||
|
|
||||||
|
void __clear_cache (char *beg, char *end);
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_arch_sync_caches (void *address, grub_size_t len)
|
||||||
|
{
|
||||||
|
__clear_cache (address, (char *) address + len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@ FUNCTION (grub_arch_sync_caches)
|
||||||
.set macro
|
.set macro
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
#include "../powerpc/cache.S"
|
#include "../powerpc/cache.S"
|
||||||
|
#elif defined(__ia64__)
|
||||||
#else
|
#else
|
||||||
#error "No target cpu type is defined"
|
#error "No target cpu type is defined"
|
||||||
#endif
|
#endif
|
|
@ -50,6 +50,15 @@ grub_emu_init (void)
|
||||||
grub_no_autoload = 1;
|
grub_no_autoload = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __ia64__
|
||||||
|
void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
|
||||||
|
grub_size_t *tramp, grub_size_t *got)
|
||||||
|
{
|
||||||
|
*tramp = 0;
|
||||||
|
*got = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GRUB_LINKER_HAVE_INIT
|
#ifdef GRUB_LINKER_HAVE_INIT
|
||||||
void
|
void
|
||||||
grub_arch_dl_init_linker (void)
|
grub_arch_dl_init_linker (void)
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <grub/util/misc.h>
|
#include <grub/util/misc.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
|
# include <libdevmapper.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __GNU__
|
#ifdef __GNU__
|
||||||
#include <hurd.h>
|
#include <hurd.h>
|
||||||
#include <hurd/lookup.h>
|
#include <hurd/lookup.h>
|
||||||
|
@ -354,7 +358,7 @@ grub_find_device (const char *dir, dev_t dev)
|
||||||
|
|
||||||
if (S_ISLNK (st.st_mode)) {
|
if (S_ISLNK (st.st_mode)) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (strcmp (dir, "mapper") == 0) {
|
if (strcmp (dir, "mapper") == 0 || strcmp (dir, "/dev/mapper") == 0) {
|
||||||
/* Follow symbolic links under /dev/mapper/; the canonical name
|
/* Follow symbolic links under /dev/mapper/; the canonical name
|
||||||
may be something like /dev/dm-0, but the names under
|
may be something like /dev/dm-0, but the names under
|
||||||
/dev/mapper/ are more human-readable and so we prefer them if
|
/dev/mapper/ are more human-readable and so we prefer them if
|
||||||
|
@ -605,20 +609,27 @@ grub_guess_root_device (const char *dir)
|
||||||
|
|
||||||
if (os_dev)
|
if (os_dev)
|
||||||
{
|
{
|
||||||
if (stat (os_dev, &st) >= 0)
|
char *tmp = os_dev;
|
||||||
dev = st.st_rdev;
|
os_dev = canonicalize_file_name (os_dev);
|
||||||
else
|
free (tmp);
|
||||||
grub_util_error ("cannot stat `%s'", os_dev);
|
|
||||||
free (os_dev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (stat (dir, &st) >= 0)
|
|
||||||
dev = st.st_dev;
|
|
||||||
else
|
|
||||||
grub_util_error ("cannot stat `%s'", dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (os_dev)
|
||||||
|
{
|
||||||
|
if (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) != 0)
|
||||||
|
return os_dev;
|
||||||
|
if (stat (os_dev, &st) < 0)
|
||||||
|
grub_util_error ("cannot stat `%s'", os_dev);
|
||||||
|
free (os_dev);
|
||||||
|
dev = st.st_rdev;
|
||||||
|
return grub_find_device ("/dev/mapper", dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat (dir, &st) < 0)
|
||||||
|
grub_util_error ("cannot stat `%s'", dir);
|
||||||
|
|
||||||
|
dev = st.st_dev;
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
/* Cygwin specific function. */
|
/* Cygwin specific function. */
|
||||||
os_dev = grub_find_device (dir, dev);
|
os_dev = grub_find_device (dir, dev);
|
||||||
|
@ -634,32 +645,65 @@ grub_guess_root_device (const char *dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_util_is_dmraid (const char *os_dev)
|
grub_util_is_lvm (const char *os_dev)
|
||||||
{
|
{
|
||||||
if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
|
if ((strncmp ("/dev/mapper/", os_dev, 12) != 0))
|
||||||
return 1;
|
return 0;
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
|
|
||||||
return 1;
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
|
{
|
||||||
return 1;
|
struct dm_tree *tree;
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
|
uint32_t maj, min;
|
||||||
return 1;
|
struct dm_tree_node *node = NULL;
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
|
const char *node_uuid;
|
||||||
return 1;
|
struct stat st;
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
|
|
||||||
return 1;
|
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
|
|
||||||
return 1;
|
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
|
|
||||||
return 1;
|
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
|
|
||||||
return 1;
|
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
|
|
||||||
return 1;
|
|
||||||
else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
if (stat (os_dev, &st) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tree = dm_tree_create ();
|
||||||
|
if (! tree)
|
||||||
|
{
|
||||||
|
grub_printf ("Failed to create tree\n");
|
||||||
|
grub_dprintf ("hostdisk", "dm_tree_create failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
maj = major (st.st_rdev);
|
||||||
|
min = minor (st.st_rdev);
|
||||||
|
|
||||||
|
if (! dm_tree_add_dev (tree, maj, min))
|
||||||
|
{
|
||||||
|
grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n");
|
||||||
|
dm_tree_free (tree);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = dm_tree_find_node (tree, maj, min);
|
||||||
|
if (! node)
|
||||||
|
{
|
||||||
|
grub_dprintf ("hostdisk", "dm_tree_find_node failed\n");
|
||||||
|
dm_tree_free (tree);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
node_uuid = dm_tree_node_get_uuid (node);
|
||||||
|
if (! node_uuid)
|
||||||
|
{
|
||||||
|
grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev);
|
||||||
|
dm_tree_free (tree);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strncmp (node_uuid, "LVM-", 4) != 0)
|
||||||
|
{
|
||||||
|
dm_tree_free (tree);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dm_tree_free (tree);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif /* HAVE_DEVICE_MAPPER */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -671,13 +715,11 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
|
||||||
return GRUB_DEV_ABSTRACTION_NONE;
|
return GRUB_DEV_ABSTRACTION_NONE;
|
||||||
|
|
||||||
/* Check for LVM. */
|
/* Check for LVM. */
|
||||||
if (!strncmp (os_dev, "/dev/mapper/", 12)
|
if (grub_util_is_lvm (os_dev))
|
||||||
&& ! grub_util_is_dmraid (os_dev)
|
|
||||||
&& strncmp (os_dev, "/dev/mapper/mpath", 17) != 0)
|
|
||||||
return GRUB_DEV_ABSTRACTION_LVM;
|
return GRUB_DEV_ABSTRACTION_LVM;
|
||||||
|
|
||||||
/* Check for RAID. */
|
/* Check for RAID. */
|
||||||
if (!strncmp (os_dev, "/dev/md", 7))
|
if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev))
|
||||||
return GRUB_DEV_ABSTRACTION_RAID;
|
return GRUB_DEV_ABSTRACTION_RAID;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/emu/misc.h>
|
#include <grub/emu/misc.h>
|
||||||
#include <grub/emu/hostdisk.h>
|
#include <grub/emu/hostdisk.h>
|
||||||
|
#include <grub/emu/getroot.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/list.h>
|
#include <grub/list.h>
|
||||||
|
@ -331,18 +332,23 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DEVICE_MAPPER
|
int
|
||||||
static int
|
grub_util_device_is_mapped (const char *dev)
|
||||||
device_is_mapped (const char *dev)
|
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
if (!grub_device_mapper_supported ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (stat (dev, &st) < 0)
|
if (stat (dev, &st) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return dm_is_dm_major (major (st.st_rdev));
|
return dm_is_dm_major (major (st.st_rdev));
|
||||||
}
|
#else
|
||||||
|
return 0;
|
||||||
#endif /* HAVE_DEVICE_MAPPER */
|
#endif /* HAVE_DEVICE_MAPPER */
|
||||||
|
}
|
||||||
|
|
||||||
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
/* FIXME: geom actually gives us the whole container hierarchy.
|
/* FIXME: geom actually gives us the whole container hierarchy.
|
||||||
|
@ -418,7 +424,7 @@ find_partition_start (const char *dev)
|
||||||
# endif /* !defined(HAVE_DIOCGDINFO) */
|
# endif /* !defined(HAVE_DIOCGDINFO) */
|
||||||
|
|
||||||
# ifdef HAVE_DEVICE_MAPPER
|
# ifdef HAVE_DEVICE_MAPPER
|
||||||
if (grub_device_mapper_supported () && device_is_mapped (dev)) {
|
if (grub_util_device_is_mapped (dev)) {
|
||||||
struct dm_task *task = NULL;
|
struct dm_task *task = NULL;
|
||||||
grub_uint64_t start, length;
|
grub_uint64_t start, length;
|
||||||
char *target_type, *params, *space;
|
char *target_type, *params, *space;
|
||||||
|
@ -550,7 +556,7 @@ struct linux_partition_cache
|
||||||
struct linux_partition_cache *linux_partition_cache_list;
|
struct linux_partition_cache *linux_partition_cache_list;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linux_find_partition (char *dev, unsigned long sector)
|
linux_find_partition (char *dev, grub_disk_addr_t sector)
|
||||||
{
|
{
|
||||||
size_t len = strlen (dev);
|
size_t len = strlen (dev);
|
||||||
const char *format;
|
const char *format;
|
||||||
|
@ -596,7 +602,7 @@ linux_find_partition (char *dev, unsigned long sector)
|
||||||
|
|
||||||
fd = open (real_dev, O_RDONLY);
|
fd = open (real_dev, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return 0;
|
continue;
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
start = find_partition_start (real_dev);
|
start = find_partition_start (real_dev);
|
||||||
|
@ -678,6 +684,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
close (data->fd);
|
close (data->fd);
|
||||||
|
data->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the partition. */
|
/* Open the partition. */
|
||||||
|
@ -736,6 +743,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
close (data->fd);
|
close (data->fd);
|
||||||
|
data->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open (map[disk->id].device, flags);
|
fd = open (map[disk->id].device, flags);
|
||||||
|
@ -1147,6 +1155,54 @@ make_device_name (int drive, int dos_part, int bsd_part)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
|
static int
|
||||||
|
grub_util_get_dm_node_linear_info (const char *dev,
|
||||||
|
int *maj, int *min)
|
||||||
|
{
|
||||||
|
struct dm_task *dmt;
|
||||||
|
void *next = NULL;
|
||||||
|
uint64_t length, start;
|
||||||
|
char *target, *params;
|
||||||
|
char *ptr;
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
dmt = dm_task_create(DM_DEVICE_TABLE);
|
||||||
|
if (!dmt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!dm_task_set_name(dmt, dev))
|
||||||
|
return 0;
|
||||||
|
dm_task_no_open_count(dmt);
|
||||||
|
if (!dm_task_run(dmt))
|
||||||
|
return 0;
|
||||||
|
next = dm_get_next_target(dmt, next, &start, &length,
|
||||||
|
&target, ¶ms);
|
||||||
|
if (grub_strcmp (target, "linear") != 0)
|
||||||
|
return 0;
|
||||||
|
major = grub_strtoul (params, &ptr, 10);
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (*ptr != ':')
|
||||||
|
return 0;
|
||||||
|
ptr++;
|
||||||
|
minor = grub_strtoul (ptr, 0, 10);
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (maj)
|
||||||
|
*maj = major;
|
||||||
|
if (min)
|
||||||
|
*min = minor;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
||||||
{
|
{
|
||||||
|
@ -1323,9 +1379,40 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
||||||
node = NULL;
|
node = NULL;
|
||||||
goto devmapper_out;
|
goto devmapper_out;
|
||||||
}
|
}
|
||||||
else if (strncmp (node_uuid, "DMRAID-", 7) != 0)
|
if (strncmp (node_uuid, "LVM-", 4) == 0)
|
||||||
{
|
{
|
||||||
|
grub_dprintf ("hostdisk", "%s is an LVM\n", path);
|
||||||
|
node = NULL;
|
||||||
|
goto devmapper_out;
|
||||||
|
}
|
||||||
|
if (strncmp (node_uuid, "mpath-", 6) == 0)
|
||||||
|
{
|
||||||
|
/* Multipath partitions have partN-mpath-* UUIDs, and are
|
||||||
|
linear mappings so are handled by
|
||||||
|
grub_util_get_dm_node_linear_info. Multipath disks are not
|
||||||
|
linear mappings and must be handled specially. */
|
||||||
|
grub_dprintf ("hostdisk", "%s is a multipath disk\n", path);
|
||||||
|
mapper_name = dm_tree_node_get_name (node);
|
||||||
|
goto devmapper_out;
|
||||||
|
}
|
||||||
|
if (strncmp (node_uuid, "DMRAID-", 7) != 0)
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
const char *node_name;
|
||||||
grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path);
|
grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path);
|
||||||
|
|
||||||
|
if ((node_name = dm_tree_node_get_name (node))
|
||||||
|
&& grub_util_get_dm_node_linear_info (node_name,
|
||||||
|
&major, &minor))
|
||||||
|
{
|
||||||
|
if (tree)
|
||||||
|
dm_tree_free (tree);
|
||||||
|
free (path);
|
||||||
|
char *ret = grub_find_device ("/dev/mapper",
|
||||||
|
(major << 8) | minor);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
node = NULL;
|
node = NULL;
|
||||||
goto devmapper_out;
|
goto devmapper_out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "../mips/dl.c"
|
#include "../mips/dl.c"
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
#include "../powerpc/dl.c"
|
#include "../powerpc/dl.c"
|
||||||
|
#elif defined(__ia64__)
|
||||||
|
#include "../ia64/dl.c"
|
||||||
#else
|
#else
|
||||||
#error "No target cpu type is defined"
|
#error "No target cpu type is defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
276
grub-core/kern/ia64/dl.c
Normal file
276
grub-core/kern/ia64/dl.c
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/* dl.c - arch-dependent part of loadable module support */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2002,2004,2005,2007,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/dl.h>
|
||||||
|
#include <grub/elf.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
|
/* Check if EHDR is a valid ELF header. */
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_check_header (void *ehdr)
|
||||||
|
{
|
||||||
|
Elf_Ehdr *e = ehdr;
|
||||||
|
|
||||||
|
/* Check the magic numbers. */
|
||||||
|
if (e->e_ident[EI_CLASS] != ELFCLASS64
|
||||||
|
|| e->e_ident[EI_DATA] != ELFDATA2LSB
|
||||||
|
|| e->e_machine != EM_IA_64)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MASK20 ((1 << 20) - 1)
|
||||||
|
#define MASK19 ((1 << 19) - 1)
|
||||||
|
|
||||||
|
struct unaligned_uint32
|
||||||
|
{
|
||||||
|
grub_uint32_t val;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
|
||||||
|
{
|
||||||
|
struct unaligned_uint32 *p;
|
||||||
|
switch (addr & 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2);
|
||||||
|
p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2)
|
||||||
|
| (p->val & ~(MASK20 << 2)));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7);
|
||||||
|
p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3)
|
||||||
|
| (p->val & ~(MASK20 << 3)));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12);
|
||||||
|
p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4)
|
||||||
|
| (p->val & ~(MASK20 << 4)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) )
|
||||||
|
|
||||||
|
static grub_uint32_t
|
||||||
|
add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value)
|
||||||
|
{
|
||||||
|
grub_uint32_t high, mid, low, c;
|
||||||
|
low = (a & 0x00007f);
|
||||||
|
mid = (a & 0x7fc000) >> 7;
|
||||||
|
high = (a & 0x003e00) << 7;
|
||||||
|
c = (low | mid | high) + value;
|
||||||
|
return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value)
|
||||||
|
{
|
||||||
|
struct unaligned_uint32 *p;
|
||||||
|
switch (addr & 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2);
|
||||||
|
p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7);
|
||||||
|
p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12);
|
||||||
|
p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_uint8_t nopm[5] =
|
||||||
|
{
|
||||||
|
/* [MLX] nop.m 0x0 */
|
||||||
|
0x05, 0x00, 0x00, 0x00, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
static grub_uint8_t jump[0x20] =
|
||||||
|
{
|
||||||
|
/* ld8 r16=[r15],8 */
|
||||||
|
0x02, 0x80, 0x20, 0x1e, 0x18, 0x14,
|
||||||
|
/* mov r14=r1;; */
|
||||||
|
0xe0, 0x00, 0x04, 0x00, 0x42, 0x00,
|
||||||
|
/* nop.i 0x0 */
|
||||||
|
0x00, 0x00, 0x04, 0x00,
|
||||||
|
/* ld8 r1=[r15] */
|
||||||
|
0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,
|
||||||
|
/* mov b6=r16 */
|
||||||
|
0x60, 0x80, 0x04, 0x80, 0x03, 0x00,
|
||||||
|
/* br.few b6;; */
|
||||||
|
0x60, 0x00, 0x80, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ia64_trampoline
|
||||||
|
{
|
||||||
|
/* nop.m */
|
||||||
|
grub_uint8_t nop[5];
|
||||||
|
/* movl r15 = addr*/
|
||||||
|
grub_uint8_t addr_hi[6];
|
||||||
|
grub_uint8_t e0;
|
||||||
|
grub_uint8_t addr_lo[4];
|
||||||
|
grub_uint8_t jump[0x20];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr)
|
||||||
|
{
|
||||||
|
COMPILE_TIME_ASSERT (sizeof (struct ia64_trampoline)
|
||||||
|
== GRUB_IA64_DL_TRAMP_SIZE);
|
||||||
|
grub_memcpy (tr->nop, nopm, sizeof (tr->nop));
|
||||||
|
tr->addr_hi[0] = ((addr & 0xc00000) >> 16);
|
||||||
|
tr->addr_hi[1] = (addr >> 24) & 0xff;
|
||||||
|
tr->addr_hi[2] = (addr >> 32) & 0xff;
|
||||||
|
tr->addr_hi[3] = (addr >> 40) & 0xff;
|
||||||
|
tr->addr_hi[4] = (addr >> 48) & 0xff;
|
||||||
|
tr->addr_hi[5] = (addr >> 56) & 0xff;
|
||||||
|
tr->e0 = 0xe0;
|
||||||
|
tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01;
|
||||||
|
tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11)
|
||||||
|
| ((addr & 0x200000) >> 17));
|
||||||
|
tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19);
|
||||||
|
tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60;
|
||||||
|
grub_memcpy (tr->jump, jump, sizeof (tr->jump));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Relocate symbols. */
|
||||||
|
grub_err_t
|
||||||
|
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
|
{
|
||||||
|
Elf_Ehdr *e = ehdr;
|
||||||
|
Elf_Shdr *s;
|
||||||
|
Elf_Word entsize;
|
||||||
|
unsigned i;
|
||||||
|
grub_uint64_t *gp, *gpptr;
|
||||||
|
struct ia64_trampoline *tr;
|
||||||
|
|
||||||
|
gp = (grub_uint64_t *) mod->base;
|
||||||
|
gpptr = (grub_uint64_t *) mod->got;
|
||||||
|
tr = mod->tramp;
|
||||||
|
|
||||||
|
/* Find a symbol table. */
|
||||||
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
|
i < e->e_shnum;
|
||||||
|
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
||||||
|
if (s->sh_type == SHT_SYMTAB)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == e->e_shnum)
|
||||||
|
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
|
||||||
|
|
||||||
|
entsize = s->sh_entsize;
|
||||||
|
|
||||||
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
|
i < e->e_shnum;
|
||||||
|
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
||||||
|
if (s->sh_type == SHT_RELA)
|
||||||
|
{
|
||||||
|
grub_dl_segment_t seg;
|
||||||
|
|
||||||
|
/* Find the target segment. */
|
||||||
|
for (seg = mod->segment; seg; seg = seg->next)
|
||||||
|
if (seg->section == s->sh_info)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (seg)
|
||||||
|
{
|
||||||
|
Elf_Rela *rel, *max;
|
||||||
|
|
||||||
|
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
|
||||||
|
max = rel + s->sh_size / s->sh_entsize;
|
||||||
|
rel < max;
|
||||||
|
rel++)
|
||||||
|
{
|
||||||
|
grub_addr_t addr;
|
||||||
|
Elf_Sym *sym;
|
||||||
|
grub_uint64_t value;
|
||||||
|
|
||||||
|
if (seg->size < (rel->r_offset & ~3))
|
||||||
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
|
"reloc offset is out of the segment");
|
||||||
|
|
||||||
|
addr = (grub_addr_t) seg->addr + rel->r_offset;
|
||||||
|
sym = (Elf_Sym *) ((char *) mod->symtab
|
||||||
|
+ entsize * ELF_R_SYM (rel->r_info));
|
||||||
|
|
||||||
|
/* On the PPC the value does not have an explicit
|
||||||
|
addend, add it. */
|
||||||
|
value = sym->st_value + rel->r_addend;
|
||||||
|
|
||||||
|
switch (ELF_R_TYPE (rel->r_info))
|
||||||
|
{
|
||||||
|
case R_IA64_PCREL21B:
|
||||||
|
{
|
||||||
|
grub_uint64_t noff;
|
||||||
|
make_trampoline (tr, value);
|
||||||
|
noff = ((char *) tr - (char *) (addr & ~3)) >> 4;
|
||||||
|
tr++;
|
||||||
|
if (noff & ~MASK19)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"trampoline offset too big (%lx)", noff);
|
||||||
|
add_value_to_slot_20b (addr, noff);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R_IA64_SEGREL64LSB:
|
||||||
|
*(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr;
|
||||||
|
break;
|
||||||
|
case R_IA64_FPTR64LSB:
|
||||||
|
case R_IA64_DIR64LSB:
|
||||||
|
*(grub_uint64_t *) addr += value;
|
||||||
|
break;
|
||||||
|
case R_IA64_PCREL64LSB:
|
||||||
|
*(grub_uint64_t *) addr += value - addr;
|
||||||
|
break;
|
||||||
|
case R_IA64_GPREL22:
|
||||||
|
add_value_to_slot_21 (addr, value - (grub_addr_t) gp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_IA64_LTOFF22X:
|
||||||
|
case R_IA64_LTOFF22:
|
||||||
|
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
|
||||||
|
value = *(grub_uint64_t *) sym->st_value + rel->r_addend;
|
||||||
|
case R_IA64_LTOFF_FPTR22:
|
||||||
|
*gpptr = value;
|
||||||
|
add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp);
|
||||||
|
gpptr++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
|
||||||
|
case R_IA64_LDXMOV:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
"this relocation (0x%x) is not implemented yet",
|
||||||
|
ELF_R_TYPE (rel->r_info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
73
grub-core/kern/ia64/dl_helper.c
Normal file
73
grub-core/kern/ia64/dl_helper.c
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* dl.c - arch-dependent part of loadable module support */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2002,2004,2005,2007,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/dl.h>
|
||||||
|
#include <grub/elf.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
|
||||||
|
grub_size_t *got)
|
||||||
|
{
|
||||||
|
const Elf64_Ehdr *e = ehdr;
|
||||||
|
grub_size_t cntt = 0, cntg = 0;;
|
||||||
|
const Elf64_Shdr *s;
|
||||||
|
Elf64_Word entsize;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Find a symbol table. */
|
||||||
|
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
|
||||||
|
i < grub_le_to_cpu16 (e->e_shnum);
|
||||||
|
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
|
||||||
|
if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == grub_le_to_cpu16 (e->e_shnum))
|
||||||
|
return;
|
||||||
|
|
||||||
|
entsize = s->sh_entsize;
|
||||||
|
|
||||||
|
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
|
||||||
|
i < grub_le_to_cpu16 (e->e_shnum);
|
||||||
|
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
|
||||||
|
if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA)
|
||||||
|
{
|
||||||
|
Elf64_Rela *rel, *max;
|
||||||
|
|
||||||
|
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)),
|
||||||
|
max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize);
|
||||||
|
rel < max; rel++)
|
||||||
|
switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info)))
|
||||||
|
{
|
||||||
|
case R_IA64_PCREL21B:
|
||||||
|
cntt++;
|
||||||
|
break;
|
||||||
|
case R_IA64_LTOFF_FPTR22:
|
||||||
|
case R_IA64_LTOFF22X:
|
||||||
|
case R_IA64_LTOFF22:
|
||||||
|
cntg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*tramp = cntt;
|
||||||
|
*got = cntg;
|
||||||
|
}
|
||||||
|
|
60
grub-core/kern/ia64/efi/init.c
Normal file
60
grub-core/kern/ia64/efi/init.c
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* init.c - initialize an ia64-based EFI system */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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/types.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_init (void)
|
||||||
|
{
|
||||||
|
grub_efi_init ();
|
||||||
|
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_fini (void)
|
||||||
|
{
|
||||||
|
grub_efi_fini ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_set_prefix (void)
|
||||||
|
{
|
||||||
|
grub_efi_set_prefix ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_arch_sync_caches (void *address, grub_size_t len)
|
||||||
|
{
|
||||||
|
/* Cache line length is at least 32. */
|
||||||
|
grub_uint64_t a = (grub_uint64_t)address & ~0x1f;
|
||||||
|
|
||||||
|
/* Flush data. */
|
||||||
|
for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20)
|
||||||
|
asm volatile ("fc.i %0" : : "r" (a));
|
||||||
|
/* Sync and serialize. Maybe extra. */
|
||||||
|
asm volatile (";; sync.i;; srlz.i;;");
|
||||||
|
}
|
54
grub-core/kern/ia64/efi/startup.S
Normal file
54
grub-core/kern/ia64/efi/startup.S
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 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 <config.h>
|
||||||
|
#include <grub/symbol.h>
|
||||||
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.psr abi64
|
||||||
|
.psr lsb
|
||||||
|
.lsb
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
.proc _start
|
||||||
|
_start:
|
||||||
|
alloc loc0=ar.pfs,2,4,0,0
|
||||||
|
mov loc1=rp
|
||||||
|
addl loc2=@gprel(grub_efi_image_handle),gp
|
||||||
|
addl loc3=@gprel(grub_efi_system_table),gp
|
||||||
|
;;
|
||||||
|
st8 [loc2]=in0
|
||||||
|
st8 [loc3]=in1
|
||||||
|
br.call.sptk.few rp=grub_main
|
||||||
|
;;
|
||||||
|
mov ar.pfs=loc0
|
||||||
|
mov rp=loc1
|
||||||
|
;;
|
||||||
|
br.ret.sptk.few rp
|
||||||
|
|
||||||
|
.endp _start
|
||||||
|
|
||||||
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX
|
||||||
|
VARIABLE(grub_prefix)
|
||||||
|
.byte 0
|
||||||
|
/* to be filled by grub-mkimage */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Leave some breathing room for the prefix.
|
||||||
|
*/
|
||||||
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
|
@ -53,8 +53,8 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is actualy platform-independant but used only on yeeloong and sparc. */
|
/* This is actualy platform-independant but used only on loongson and sparc. */
|
||||||
#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_SPARC64)
|
#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64)
|
||||||
grub_addr_t
|
grub_addr_t
|
||||||
grub_modules_get_end (void)
|
grub_modules_get_end (void)
|
||||||
{
|
{
|
||||||
|
|
213
grub-core/kern/mips/arc/init.c
Normal file
213
grub-core/kern/mips/arc/init.c
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* 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/kernel.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
|
#include <grub/machine/memory.h>
|
||||||
|
#include <grub/arc/console.h>
|
||||||
|
#include <grub/cpu/memory.h>
|
||||||
|
#include <grub/cpu/time.h>
|
||||||
|
#include <grub/memory.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
#include <grub/arc/arc.h>
|
||||||
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
|
const char *type_names[] = {
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
"eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm",
|
||||||
|
"serial", "net", "video", "par", "point", "key", "audio", "other",
|
||||||
|
"rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer",
|
||||||
|
"keyboard", "term", "other", "line", "network", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
iterate_rec (const char *prefix, const struct grub_arc_component *parent,
|
||||||
|
int (*hook) (const char *name,
|
||||||
|
const struct grub_arc_component *comp),
|
||||||
|
int alt_names)
|
||||||
|
{
|
||||||
|
const struct grub_arc_component *comp;
|
||||||
|
FOR_ARC_CHILDREN(comp, parent)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
const char *cname = NULL;
|
||||||
|
if (comp->type < ARRAY_SIZE (type_names))
|
||||||
|
cname = type_names[comp->type];
|
||||||
|
if (!cname)
|
||||||
|
cname = "unknown";
|
||||||
|
if (alt_names)
|
||||||
|
name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key);
|
||||||
|
else
|
||||||
|
name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
|
||||||
|
if (!name)
|
||||||
|
return 1;
|
||||||
|
if (hook (name, comp))
|
||||||
|
{
|
||||||
|
grub_free (name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names))
|
||||||
|
{
|
||||||
|
grub_free (name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
grub_free (name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_arc_iterate_devs (int (*hook) (const char *name,
|
||||||
|
const struct grub_arc_component *comp),
|
||||||
|
int alt_names)
|
||||||
|
{
|
||||||
|
return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
||||||
|
{
|
||||||
|
struct grub_arc_memory_descriptor *cur = NULL;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
grub_memory_type_t type;
|
||||||
|
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
|
||||||
|
if (!cur)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
switch (cur->type)
|
||||||
|
{
|
||||||
|
case GRUB_ARC_MEMORY_EXCEPTION_BLOCK:
|
||||||
|
case GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK:
|
||||||
|
case GRUB_ARC_MEMORY_FW_PERMANENT:
|
||||||
|
default:
|
||||||
|
type = GRUB_MEMORY_RESERVED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GRUB_ARC_MEMORY_FW_TEMPORARY:
|
||||||
|
case GRUB_ARC_MEMORY_FREE:
|
||||||
|
case GRUB_ARC_MEMORY_LOADED:
|
||||||
|
case GRUB_ARC_MEMORY_FREE_CONTIGUOUS:
|
||||||
|
type = GRUB_MEMORY_AVAILABLE;
|
||||||
|
break;
|
||||||
|
case GRUB_ARC_MEMORY_BADRAM:
|
||||||
|
type = GRUB_MEMORY_BADRAM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (hook (((grub_uint64_t) cur->start_page) << 12,
|
||||||
|
((grub_uint64_t) cur->num_pages) << 12, type))
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern grub_uint32_t grub_total_modules_size;
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_init (void)
|
||||||
|
{
|
||||||
|
struct grub_arc_memory_descriptor *cur = NULL;
|
||||||
|
|
||||||
|
grub_console_init_early ();
|
||||||
|
|
||||||
|
/* FIXME: measure this. */
|
||||||
|
grub_arch_cpuclock = 64000000;
|
||||||
|
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
grub_uint64_t start, end;
|
||||||
|
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
|
||||||
|
if (!cur)
|
||||||
|
break;
|
||||||
|
if (cur->type != GRUB_ARC_MEMORY_FREE
|
||||||
|
&& cur->type != GRUB_ARC_MEMORY_LOADED
|
||||||
|
&& cur->type != GRUB_ARC_MEMORY_FREE_CONTIGUOUS)
|
||||||
|
continue;
|
||||||
|
start = ((grub_uint64_t) cur->start_page) << 12;
|
||||||
|
end = ((grub_uint64_t) cur->num_pages) << 12;
|
||||||
|
end += start;
|
||||||
|
if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR
|
||||||
|
- grub_total_modules_size) & 0x1fffffff))
|
||||||
|
end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size)
|
||||||
|
& 0x1fffffff);
|
||||||
|
if (end > start)
|
||||||
|
grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000),
|
||||||
|
end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_console_init_lately ();
|
||||||
|
|
||||||
|
grub_arcdisk_init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_addr_t
|
||||||
|
grub_arch_modules_addr (void)
|
||||||
|
{
|
||||||
|
return GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_machine_fini (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_halt (void)
|
||||||
|
{
|
||||||
|
GRUB_ARC_FIRMWARE_VECTOR->powerdown ();
|
||||||
|
|
||||||
|
grub_millisleep (1500);
|
||||||
|
|
||||||
|
grub_printf ("Shutdown failed\n");
|
||||||
|
grub_refresh ();
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_exit (void)
|
||||||
|
{
|
||||||
|
GRUB_ARC_FIRMWARE_VECTOR->exit ();
|
||||||
|
|
||||||
|
grub_millisleep (1500);
|
||||||
|
|
||||||
|
grub_printf ("Exit failed\n");
|
||||||
|
grub_refresh ();
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_reboot (void)
|
||||||
|
{
|
||||||
|
GRUB_ARC_FIRMWARE_VECTOR->restart ();
|
||||||
|
|
||||||
|
grub_millisleep (1500);
|
||||||
|
|
||||||
|
grub_printf ("Reboot failed\n");
|
||||||
|
grub_refresh ();
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
|
@ -8,3 +8,38 @@ FUNCTION (grub_cpu_flush_cache)
|
||||||
FUNCTION (grub_arch_sync_caches)
|
FUNCTION (grub_arch_sync_caches)
|
||||||
#include "cache_flush.S"
|
#include "cache_flush.S"
|
||||||
j $ra
|
j $ra
|
||||||
|
|
||||||
|
FUNCTION (grub_arch_sync_dma_caches)
|
||||||
|
move $t2, $a0
|
||||||
|
addu $t3, $a0, $a1
|
||||||
|
srl $t2, $t2, 5
|
||||||
|
sll $t2, $t2, 5
|
||||||
|
addu $t3, $t3, 0x1f
|
||||||
|
srl $t3, $t3, 5
|
||||||
|
sll $t3, $t3, 5
|
||||||
|
move $t0, $t2
|
||||||
|
subu $t1, $t3, $t2
|
||||||
|
1:
|
||||||
|
cache 1, 0($t0)
|
||||||
|
addiu $t1, $t1, 0xffff
|
||||||
|
bne $t1, $zero, 1b
|
||||||
|
addiu $t0, $t0, 0x1
|
||||||
|
sync
|
||||||
|
move $t0, $t2
|
||||||
|
subu $t1, $t3, $t2
|
||||||
|
2:
|
||||||
|
cache 0, 0($t0)
|
||||||
|
addiu $t1, $t1, 0xffff
|
||||||
|
bne $t1, $zero, 2b
|
||||||
|
addiu $t0, $t0, 0x1
|
||||||
|
sync
|
||||||
|
move $t0, $t2
|
||||||
|
subu $t1, $t3, $t2
|
||||||
|
2:
|
||||||
|
cache 23, 0($t0)
|
||||||
|
addiu $t1, $t1, 0xffff
|
||||||
|
bne $t1, $zero, 2b
|
||||||
|
addiu $t0, $t0, 0x1
|
||||||
|
sync
|
||||||
|
|
||||||
|
jr $ra
|
|
@ -9,15 +9,15 @@
|
||||||
subu $t1, $t3, $t2
|
subu $t1, $t3, $t2
|
||||||
1:
|
1:
|
||||||
cache 1, 0($t0)
|
cache 1, 0($t0)
|
||||||
addiu $t1, $t1, 0xffff
|
addiu $t1, $t1, -0x4
|
||||||
bne $t1, $zero, 1b
|
bne $t1, $zero, 1b
|
||||||
addiu $t0, $t0, 0x1
|
addiu $t0, $t0, 0x4
|
||||||
sync
|
sync
|
||||||
move $t0, $t2
|
move $t0, $t2
|
||||||
subu $t1, $t3, $t2
|
subu $t1, $t3, $t2
|
||||||
2:
|
2:
|
||||||
cache 0, 0($t0)
|
cache 0, 0($t0)
|
||||||
addiu $t1, $t1, 0xffff
|
addiu $t1, $t1, -0x4
|
||||||
bne $t1, $zero, 2b
|
bne $t1, $zero, 2b
|
||||||
addiu $t0, $t0, 0x1
|
addiu $t0, $t0, 0x4
|
||||||
sync
|
sync
|
||||||
|
|
|
@ -34,7 +34,7 @@ grub_arch_dl_check_header (void *ehdr)
|
||||||
Elf_Ehdr *e = ehdr;
|
Elf_Ehdr *e = ehdr;
|
||||||
|
|
||||||
/* Check the magic numbers. */
|
/* Check the magic numbers. */
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
if (e->e_ident[EI_CLASS] != ELFCLASS32
|
if (e->e_ident[EI_CLASS] != ELFCLASS32
|
||||||
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|
||||||
|| e->e_machine != EM_MIPS)
|
|| e->e_machine != EM_MIPS)
|
||||||
|
@ -144,14 +144,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
rel < max;
|
rel < max;
|
||||||
rel++)
|
rel++)
|
||||||
{
|
{
|
||||||
Elf_Word *addr;
|
grub_uint8_t *addr;
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
|
|
||||||
if (seg->size < rel->r_offset)
|
if (seg->size < rel->r_offset)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
"reloc offset is out of the segment");
|
"reloc offset is out of the segment");
|
||||||
|
|
||||||
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
|
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
|
||||||
sym = (Elf_Sym *) ((char *) mod->symtab
|
sym = (Elf_Sym *) ((char *) mod->symtab
|
||||||
+ entsize * ELF_R_SYM (rel->r_info));
|
+ entsize * ELF_R_SYM (rel->r_info));
|
||||||
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
|
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
|
||||||
|
@ -163,7 +163,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
{
|
{
|
||||||
grub_uint32_t value;
|
grub_uint32_t value;
|
||||||
Elf_Rel *rel2;
|
Elf_Rel *rel2;
|
||||||
|
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle partner lo16 relocation. Lower part is
|
/* Handle partner lo16 relocation. Lower part is
|
||||||
treated as signed. Hence add 0x8000 to compensate.
|
treated as signed. Hence add 0x8000 to compensate.
|
||||||
*/
|
*/
|
||||||
|
@ -175,13 +179,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
|
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
|
||||||
{
|
{
|
||||||
value += *(grub_int16_t *)
|
value += *(grub_int16_t *)
|
||||||
((char *) seg->addr + rel2->r_offset);
|
((char *) seg->addr + rel2->r_offset
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
+ 2
|
||||||
|
#endif
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
|
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_MIPS_LO16:
|
case R_MIPS_LO16:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
|
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
|
||||||
break;
|
break;
|
||||||
case R_MIPS_32:
|
case R_MIPS_32:
|
||||||
|
@ -208,11 +219,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
case R_MIPS_GOT16:
|
case R_MIPS_GOT16:
|
||||||
case R_MIPS_CALL16:
|
case R_MIPS_CALL16:
|
||||||
/* FIXME: reuse*/
|
/* FIXME: reuse*/
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
||||||
*(grub_uint16_t *) addr
|
*(grub_uint16_t *) addr
|
||||||
= sizeof (grub_uint32_t) * (gpptr - gp);
|
= sizeof (grub_uint32_t) * (gpptr - gp);
|
||||||
gpptr++;
|
gpptr++;
|
||||||
break;
|
break;
|
||||||
|
case R_MIPS_JALR:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
grub_free (gp);
|
grub_free (gp);
|
||||||
|
@ -232,6 +248,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
void
|
void
|
||||||
grub_arch_dl_init_linker (void)
|
grub_arch_dl_init_linker (void)
|
||||||
{
|
{
|
||||||
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
|
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,17 +18,27 @@
|
||||||
|
|
||||||
#include <grub/kernel.h>
|
#include <grub/kernel.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
#include <grub/cpu/time.h>
|
||||||
|
#include <grub/cpu/mips.h>
|
||||||
|
|
||||||
|
/* FIXME: use interrupt to count high. */
|
||||||
|
grub_uint64_t
|
||||||
|
grub_get_rtc (void)
|
||||||
|
{
|
||||||
|
static grub_uint32_t high = 0;
|
||||||
|
static grub_uint32_t last = 0;
|
||||||
|
grub_uint32_t low;
|
||||||
|
|
||||||
|
asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low));
|
||||||
|
if (low < last)
|
||||||
|
high++;
|
||||||
|
last = low;
|
||||||
|
|
||||||
|
return (((grub_uint64_t) high) << 32) | low;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_set_prefix (void)
|
grub_machine_set_prefix (void)
|
||||||
{
|
{
|
||||||
grub_env_set ("prefix", grub_prefix);
|
grub_env_set ("prefix", grub_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char _end[];
|
|
||||||
|
|
||||||
grub_addr_t
|
|
||||||
grub_arch_modules_addr (void)
|
|
||||||
{
|
|
||||||
return (grub_addr_t) _end;
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,8 +31,10 @@
|
||||||
#include <grub/cs5536.h>
|
#include <grub/cs5536.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/machine/ec.h>
|
#include <grub/machine/ec.h>
|
||||||
|
#include <grub/cpu/memory.h>
|
||||||
|
|
||||||
extern void grub_video_sm712_init (void);
|
extern void grub_video_sm712_init (void);
|
||||||
|
extern void grub_video_sis315pro_init (void);
|
||||||
extern void grub_video_init (void);
|
extern void grub_video_init (void);
|
||||||
extern void grub_bitmap_init (void);
|
extern void grub_bitmap_init (void);
|
||||||
extern void grub_font_init (void);
|
extern void grub_font_init (void);
|
||||||
|
@ -43,22 +45,6 @@ extern void grub_terminfo_init (void);
|
||||||
extern void grub_keylayouts_init (void);
|
extern void grub_keylayouts_init (void);
|
||||||
extern void grub_boot_init (void);
|
extern void grub_boot_init (void);
|
||||||
|
|
||||||
/* FIXME: use interrupt to count high. */
|
|
||||||
grub_uint64_t
|
|
||||||
grub_get_rtc (void)
|
|
||||||
{
|
|
||||||
static grub_uint32_t high = 0;
|
|
||||||
static grub_uint32_t last = 0;
|
|
||||||
grub_uint32_t low;
|
|
||||||
|
|
||||||
asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low));
|
|
||||||
if (low < last)
|
|
||||||
high++;
|
|
||||||
last = low;
|
|
||||||
|
|
||||||
return (((grub_uint64_t) high) << 32) | low;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +65,7 @@ init_pci (void)
|
||||||
/* FIXME: autoscan for BARs and devices. */
|
/* FIXME: autoscan for BARs and devices. */
|
||||||
switch (pciid)
|
switch (pciid)
|
||||||
{
|
{
|
||||||
case GRUB_YEELOONG_OHCI_PCIID:
|
case GRUB_LOONGSON_OHCI_PCIID:
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
||||||
grub_pci_write (addr, 0x5025000);
|
grub_pci_write (addr, 0x5025000);
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
||||||
|
@ -91,7 +77,7 @@ init_pci (void)
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
|
||||||
grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
|
grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
|
||||||
break;
|
break;
|
||||||
case GRUB_YEELOONG_EHCI_PCIID:
|
case GRUB_LOONGSON_EHCI_PCIID:
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
||||||
grub_pci_write (addr, 0x5026000);
|
grub_pci_write (addr, 0x5026000);
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
|
||||||
|
@ -163,7 +149,7 @@ grub_machine_init (void)
|
||||||
if (err)
|
if (err)
|
||||||
grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg);
|
grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg);
|
||||||
|
|
||||||
/* Yeeloong has only one memory slot. */
|
/* Yeeloong and Fuloong have only one memory slot. */
|
||||||
err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd);
|
err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd);
|
||||||
if (err)
|
if (err)
|
||||||
grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg);
|
grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg);
|
||||||
|
@ -202,12 +188,14 @@ grub_machine_init (void)
|
||||||
relies on a working heap. */
|
relies on a working heap. */
|
||||||
grub_video_init ();
|
grub_video_init ();
|
||||||
grub_video_sm712_init ();
|
grub_video_sm712_init ();
|
||||||
|
grub_video_sis315pro_init ();
|
||||||
grub_bitmap_init ();
|
grub_bitmap_init ();
|
||||||
grub_font_init ();
|
grub_font_init ();
|
||||||
grub_gfxterm_init ();
|
grub_gfxterm_init ();
|
||||||
|
|
||||||
grub_keylayouts_init ();
|
grub_keylayouts_init ();
|
||||||
grub_at_keyboard_init ();
|
if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG)
|
||||||
|
grub_at_keyboard_init ();
|
||||||
|
|
||||||
grub_terminfo_init ();
|
grub_terminfo_init ();
|
||||||
grub_serial_init ();
|
grub_serial_init ();
|
||||||
|
@ -223,10 +211,28 @@ grub_machine_fini (void)
|
||||||
void
|
void
|
||||||
grub_halt (void)
|
grub_halt (void)
|
||||||
{
|
{
|
||||||
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
|
switch (grub_arch_machine)
|
||||||
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
|
{
|
||||||
|
case GRUB_ARCH_MACHINE_FULOONG:
|
||||||
grub_millisleep (1500);
|
{
|
||||||
|
grub_pci_device_t dev;
|
||||||
|
grub_port_t p;
|
||||||
|
if (grub_cs5536_find (&dev))
|
||||||
|
{
|
||||||
|
p = (grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_GPIO_BAR)
|
||||||
|
& GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE;
|
||||||
|
grub_outl ((1 << 13), p + 4);
|
||||||
|
grub_outl ((1 << 29), p);
|
||||||
|
grub_millisleep (5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GRUB_ARCH_MACHINE_YEELOONG:
|
||||||
|
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
|
||||||
|
& ~GRUB_CPU_YEELOONG_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
|
||||||
|
grub_millisleep (1500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
grub_printf ("Shutdown failed\n");
|
grub_printf ("Shutdown failed\n");
|
||||||
grub_refresh ();
|
grub_refresh ();
|
||||||
|
@ -251,3 +257,10 @@ grub_reboot (void)
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char _end[];
|
||||||
|
|
||||||
|
grub_addr_t
|
||||||
|
grub_arch_modules_addr (void)
|
||||||
|
{
|
||||||
|
return (grub_addr_t) _end;
|
||||||
|
}
|
|
@ -6,25 +6,29 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/machine/kernel.h>
|
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/cpu/kernel.h>
|
#include <grub/cpu/memory.h>
|
||||||
|
#include <grub/memory.h>
|
||||||
|
|
||||||
#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
|
extern void grub_serial_init (void);
|
||||||
|
extern void grub_terminfo_init (void);
|
||||||
grub_uint32_t
|
|
||||||
grub_get_rtc (void)
|
|
||||||
{
|
|
||||||
static int calln = 0;
|
|
||||||
return calln++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_init (void)
|
grub_machine_init (void)
|
||||||
{
|
{
|
||||||
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
|
grub_addr_t modend;
|
||||||
RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
|
|
||||||
|
/* FIXME: measure this. */
|
||||||
|
grub_arch_cpuclock = 64000000;
|
||||||
|
|
||||||
|
modend = grub_modules_get_end ();
|
||||||
|
grub_mm_init_region ((void *) modend, grub_arch_memsize
|
||||||
|
- (modend - GRUB_ARCH_LOWMEMVSTART));
|
||||||
|
|
||||||
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||||
|
|
||||||
|
grub_terminfo_init ();
|
||||||
|
grub_serial_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -53,6 +57,14 @@ grub_reboot (void)
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
||||||
{
|
{
|
||||||
hook (0, RAMSIZE, GRUB_MEMORY_AVAILABLE);
|
hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char _end[];
|
||||||
|
|
||||||
|
grub_addr_t
|
||||||
|
grub_arch_modules_addr (void)
|
||||||
|
{
|
||||||
|
return (grub_addr_t) _end;
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
|
|
||||||
#define BASE_ADDR 8
|
#define BASE_ADDR 8
|
||||||
|
@ -35,8 +36,8 @@ start:
|
||||||
bal cont
|
bal cont
|
||||||
nop
|
nop
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE
|
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||||
total_module_size:
|
VARIABLE(grub_total_modules_size)
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_PREFIX
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX
|
||||||
|
@ -50,7 +51,6 @@ VARIABLE(grub_prefix)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
|
||||||
VARIABLE (grub_arch_busclock)
|
VARIABLE (grub_arch_busclock)
|
||||||
.long 0
|
.long 0
|
||||||
VARIABLE (grub_arch_cpuclock)
|
VARIABLE (grub_arch_cpuclock)
|
||||||
|
@ -59,21 +59,32 @@ VARIABLE (grub_arch_memsize)
|
||||||
.long 0
|
.long 0
|
||||||
VARIABLE (grub_arch_highmemsize)
|
VARIABLE (grub_arch_highmemsize)
|
||||||
.long 0
|
.long 0
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
VARIABLE (grub_arch_machine)
|
||||||
|
.long GRUB_ARCH_MACHINE_FULOONG
|
||||||
#endif
|
#endif
|
||||||
cont:
|
cont:
|
||||||
/* Save our base. */
|
/* Save our base. */
|
||||||
move $s0, $ra
|
move $s0, $ra
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
lui $t1, %hi(grub_arch_busclock)
|
||||||
|
addiu $t1, %lo(grub_arch_busclock)
|
||||||
|
sw $s4, 8($t1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
lui $t1, %hi(grub_arch_busclock)
|
lui $t1, %hi(grub_arch_busclock)
|
||||||
addiu $t1, %lo(grub_arch_busclock)
|
addiu $t1, %lo(grub_arch_busclock)
|
||||||
sw $s2, 0($t1)
|
sw $s2, 0($t1)
|
||||||
sw $s3, 4($t1)
|
sw $s3, 4($t1)
|
||||||
sw $s4, 8($t1)
|
sw $s4, 8($t1)
|
||||||
sw $s5, 12($t1)
|
sw $s5, 12($t1)
|
||||||
|
sw $s7, 16($t1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Move the modules out of BSS. */
|
/* Move the modules out of BSS. */
|
||||||
|
#ifndef GRUB_MACHINE_ARC
|
||||||
lui $t2, %hi(__bss_start)
|
lui $t2, %hi(__bss_start)
|
||||||
addiu $t2, %lo(__bss_start)
|
addiu $t2, %lo(__bss_start)
|
||||||
|
|
||||||
|
@ -103,6 +114,7 @@ modulesmovcont:
|
||||||
b modulesmovcont
|
b modulesmovcont
|
||||||
addiu $t3, $t3, -1
|
addiu $t3, $t3, -1
|
||||||
modulesmovdone:
|
modulesmovdone:
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clean BSS. */
|
/* Clean BSS. */
|
||||||
|
|
||||||
|
|
|
@ -597,7 +597,7 @@ grub_reverse (char *str)
|
||||||
|
|
||||||
/* Divide N by D, return the quotient, and store the remainder in *R. */
|
/* Divide N by D, return the quotient, and store the remainder in *R. */
|
||||||
grub_uint64_t
|
grub_uint64_t
|
||||||
grub_divmod64_full (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
|
grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
|
||||||
{
|
{
|
||||||
/* This algorithm is typically implemented by hardware. The idea
|
/* This algorithm is typically implemented by hardware. The idea
|
||||||
is to get the highest bit in N, 64 times, by keeping
|
is to get the highest bit in N, 64 times, by keeping
|
||||||
|
@ -666,7 +666,7 @@ grub_lltoa (char *str, int c, unsigned long long n)
|
||||||
/* BASE == 10 */
|
/* BASE == 10 */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned m;
|
grub_uint64_t m;
|
||||||
|
|
||||||
n = grub_divmod64 (n, 10, &m);
|
n = grub_divmod64 (n, 10, &m);
|
||||||
*p++ = m + '0';
|
*p++ = m + '0';
|
||||||
|
|
|
@ -311,11 +311,13 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||||
count++;
|
count++;
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case 1:
|
case 1:
|
||||||
/* Unload unneeded modules. */
|
/* Unload unneeded modules. */
|
||||||
grub_dl_unload_unneeded ();
|
grub_dl_unload_unneeded ();
|
||||||
count++;
|
count++;
|
||||||
goto again;
|
goto again;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
48
grub-core/lib/arc/datetime.c
Normal file
48
grub-core/lib/arc/datetime.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2011 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/datetime.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/arc/arc.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_get_datetime (struct grub_datetime *datetime)
|
||||||
|
{
|
||||||
|
struct grub_arc_timeinfo *dt;
|
||||||
|
grub_memset (datetime, 0, sizeof (*datetime));
|
||||||
|
|
||||||
|
dt = GRUB_ARC_FIRMWARE_VECTOR->gettime ();
|
||||||
|
|
||||||
|
datetime->year = dt->y;
|
||||||
|
datetime->month = dt->m;
|
||||||
|
datetime->day = dt->d;
|
||||||
|
datetime->hour = dt->h;
|
||||||
|
datetime->minute = dt->min;
|
||||||
|
datetime->second = dt->s;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_IO, "setting time isn't supported");
|
||||||
|
}
|
|
@ -28,7 +28,9 @@ void
|
||||||
grub_halt (void)
|
grub_halt (void)
|
||||||
{
|
{
|
||||||
grub_machine_fini ();
|
grub_machine_fini ();
|
||||||
|
#ifndef __ia64__
|
||||||
grub_acpi_halt ();
|
grub_acpi_halt ();
|
||||||
|
#endif
|
||||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||||
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ extern grub_uint16_t grub_relocator16_gs;
|
||||||
extern grub_uint16_t grub_relocator16_ss;
|
extern grub_uint16_t grub_relocator16_ss;
|
||||||
extern grub_uint16_t grub_relocator16_sp;
|
extern grub_uint16_t grub_relocator16_sp;
|
||||||
extern grub_uint32_t grub_relocator16_edx;
|
extern grub_uint32_t grub_relocator16_edx;
|
||||||
|
extern grub_uint32_t grub_relocator16_ebx;
|
||||||
|
|
||||||
extern grub_uint8_t grub_relocator32_start;
|
extern grub_uint8_t grub_relocator32_start;
|
||||||
extern grub_uint8_t grub_relocator32_end;
|
extern grub_uint8_t grub_relocator32_end;
|
||||||
|
@ -212,6 +213,7 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
||||||
grub_relocator16_ss = state.ss;
|
grub_relocator16_ss = state.ss;
|
||||||
grub_relocator16_sp = state.sp;
|
grub_relocator16_sp = state.sp;
|
||||||
|
|
||||||
|
grub_relocator16_ebx = state.ebx;
|
||||||
grub_relocator16_edx = state.edx;
|
grub_relocator16_edx = state.edx;
|
||||||
|
|
||||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
||||||
|
|
|
@ -136,7 +136,12 @@ VARIABLE(grub_relocator16_sp)
|
||||||
.byte 0x66, 0xba
|
.byte 0x66, 0xba
|
||||||
VARIABLE(grub_relocator16_edx)
|
VARIABLE(grub_relocator16_edx)
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
|
/* movw imm32, %ebx. */
|
||||||
|
.byte 0x66, 0xbb
|
||||||
|
VARIABLE(grub_relocator16_ebx)
|
||||||
|
.long 0
|
||||||
|
|
||||||
/* Cleared direction flag is of no problem with any current
|
/* Cleared direction flag is of no problem with any current
|
||||||
payload and makes this implementation easier. */
|
payload and makes this implementation easier. */
|
||||||
cld
|
cld
|
||||||
|
|
162
grub-core/lib/ia64/longjmp.S
Normal file
162
grub-core/lib/ia64/longjmp.S
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA.
|
||||||
|
|
||||||
|
Note that __sigsetjmp() did NOT flush the register stack. Instead,
|
||||||
|
we do it here since __longjmp() is usually much less frequently
|
||||||
|
invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
|
||||||
|
didn't (and wouldn't be able to) save ar.rnat either. This is a problem
|
||||||
|
because if we're not careful, we could end up loading random NaT bits.
|
||||||
|
There are two cases:
|
||||||
|
|
||||||
|
(i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||||
|
ar.rnat contains the desired bits---preserve ar.rnat
|
||||||
|
across loadrs and write to ar.bspstore
|
||||||
|
|
||||||
|
(ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||||
|
The desired ar.rnat is stored in
|
||||||
|
ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
|
||||||
|
bits into ar.rnat after setting ar.bspstore. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# define pPos p6 /* is rotate count positive? */
|
||||||
|
# define pNeg p7 /* is rotate count negative? */
|
||||||
|
|
||||||
|
|
||||||
|
/* __longjmp(__jmp_buf buf, int val) */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global longjmp
|
||||||
|
.proc longjmp
|
||||||
|
longjmp:
|
||||||
|
alloc r8=ar.pfs,2,1,0,0
|
||||||
|
mov r27=ar.rsc
|
||||||
|
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
|
||||||
|
;;
|
||||||
|
ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
|
||||||
|
mov r10=ar.bsp
|
||||||
|
and r11=~0x3,r27 // clear ar.rsc.mode
|
||||||
|
;;
|
||||||
|
flushrs // flush dirty regs to backing store (must be first in insn grp)
|
||||||
|
ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
|
||||||
|
sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
|
||||||
|
;;
|
||||||
|
ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
|
||||||
|
extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
|
||||||
|
;;
|
||||||
|
cmp.lt pNeg,pPos=r8,r0
|
||||||
|
mov r2=in0
|
||||||
|
;;
|
||||||
|
(pPos) mov r16=r8
|
||||||
|
(pNeg) add r16=64,r8
|
||||||
|
(pPos) sub r17=64,r8
|
||||||
|
(pNeg) sub r17=r0,r8
|
||||||
|
;;
|
||||||
|
mov ar.rsc=r11 // put RSE in enforced lazy mode
|
||||||
|
shr.u r8=r25,r16
|
||||||
|
add r3=8,in0 // r3 <- &jmpbuf.r1
|
||||||
|
shl r9=r25,r17
|
||||||
|
;;
|
||||||
|
or r25=r8,r9
|
||||||
|
;;
|
||||||
|
mov r26=ar.rnat
|
||||||
|
mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
|
||||||
|
;;
|
||||||
|
ld8.fill.nta sp=[r2],16 // r12 (sp)
|
||||||
|
ld8.fill.nta gp=[r3],16 // r1 (gp)
|
||||||
|
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||||
|
;;
|
||||||
|
ld8.nta r16=[r2],16 // caller's unat
|
||||||
|
ld8.nta r17=[r3],16 // fpsr
|
||||||
|
;;
|
||||||
|
ld8.fill.nta r4=[r2],16 // r4
|
||||||
|
ld8.fill.nta r5=[r3],16 // r5 (gp)
|
||||||
|
cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
|
||||||
|
;;
|
||||||
|
ld8.fill.nta r6=[r2],16 // r6
|
||||||
|
ld8.fill.nta r7=[r3],16 // r7
|
||||||
|
;;
|
||||||
|
mov ar.unat=r16 // restore caller's unat
|
||||||
|
mov ar.fpsr=r17 // restore fpsr
|
||||||
|
;;
|
||||||
|
ld8.nta r16=[r2],16 // b0
|
||||||
|
ld8.nta r17=[r3],16 // b1
|
||||||
|
;;
|
||||||
|
(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||||
|
mov ar.bspstore=r23 // restore ar.bspstore
|
||||||
|
;;
|
||||||
|
ld8.nta r18=[r2],16 // b2
|
||||||
|
ld8.nta r19=[r3],16 // b3
|
||||||
|
;;
|
||||||
|
ld8.nta r20=[r2],16 // b4
|
||||||
|
ld8.nta r21=[r3],16 // b5
|
||||||
|
;;
|
||||||
|
ld8.nta r11=[r2],16 // ar.pfs
|
||||||
|
ld8.nta r22=[r3],56 // ar.lc
|
||||||
|
;;
|
||||||
|
ld8.nta r24=[r2],32 // pr
|
||||||
|
mov b0=r16
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f2=[r2],32
|
||||||
|
ldf.fill.nta f3=[r3],32
|
||||||
|
mov b1=r17
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f4=[r2],32
|
||||||
|
ldf.fill.nta f5=[r3],32
|
||||||
|
mov b2=r18
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f16=[r2],32
|
||||||
|
ldf.fill.nta f17=[r3],32
|
||||||
|
mov b3=r19
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f18=[r2],32
|
||||||
|
ldf.fill.nta f19=[r3],32
|
||||||
|
mov b4=r20
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f20=[r2],32
|
||||||
|
ldf.fill.nta f21=[r3],32
|
||||||
|
mov b5=r21
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f22=[r2],32
|
||||||
|
ldf.fill.nta f23=[r3],32
|
||||||
|
mov ar.lc=r22
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f24=[r2],32
|
||||||
|
ldf.fill.nta f25=[r3],32
|
||||||
|
cmp.eq p8,p9=0,in1
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f26=[r2],32
|
||||||
|
ldf.fill.nta f27=[r3],32
|
||||||
|
mov ar.pfs=r11
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f28=[r2],32
|
||||||
|
ldf.fill.nta f29=[r3],32
|
||||||
|
;;
|
||||||
|
ldf.fill.nta f30=[r2]
|
||||||
|
ldf.fill.nta f31=[r3]
|
||||||
|
(p8) mov r8=1
|
||||||
|
|
||||||
|
mov ar.rnat=r26 // restore ar.rnat
|
||||||
|
;;
|
||||||
|
mov ar.rsc=r27 // restore ar.rsc
|
||||||
|
(p9) mov r8=in1
|
||||||
|
|
||||||
|
invala // virt. -> phys. regnum mapping may change
|
||||||
|
mov pr=r24,-1
|
||||||
|
br.ret.dptk.few rp
|
||||||
|
.endp longjmp
|
171
grub-core/lib/ia64/setjmp.S
Normal file
171
grub-core/lib/ia64/setjmp.S
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA.
|
||||||
|
|
||||||
|
The layout of the jmp_buf is as follows. This is subject to change
|
||||||
|
and user-code should never depend on the particular layout of
|
||||||
|
jmp_buf!
|
||||||
|
|
||||||
|
|
||||||
|
offset: description:
|
||||||
|
------- ------------
|
||||||
|
0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
|
||||||
|
0x008 r1 (gp)
|
||||||
|
0x010 caller's unat
|
||||||
|
0x018 fpsr
|
||||||
|
0x020 r4
|
||||||
|
0x028 r5
|
||||||
|
0x030 r6
|
||||||
|
0x038 r7
|
||||||
|
0x040 rp (b0)
|
||||||
|
0x048 b1
|
||||||
|
0x050 b2
|
||||||
|
0x058 b3
|
||||||
|
0x060 b4
|
||||||
|
0x068 b5
|
||||||
|
0x070 ar.pfs
|
||||||
|
0x078 ar.lc
|
||||||
|
0x080 pr
|
||||||
|
0x088 ar.bsp ; unchangeable (see __longjmp.S)
|
||||||
|
0x090 ar.unat
|
||||||
|
0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
|
||||||
|
0x0a0 f2
|
||||||
|
0x0b0 f3
|
||||||
|
0x0c0 f4
|
||||||
|
0x0d0 f5
|
||||||
|
0x0e0 f16
|
||||||
|
0x0f0 f17
|
||||||
|
0x100 f18
|
||||||
|
0x110 f19
|
||||||
|
0x120 f20
|
||||||
|
0x130 f21
|
||||||
|
0x130 f22
|
||||||
|
0x140 f23
|
||||||
|
0x150 f24
|
||||||
|
0x160 f25
|
||||||
|
0x170 f26
|
||||||
|
0x180 f27
|
||||||
|
0x190 f28
|
||||||
|
0x1a0 f29
|
||||||
|
0x1b0 f30
|
||||||
|
0x1c0 f31 */
|
||||||
|
|
||||||
|
|
||||||
|
/* The following two entry points are the traditional entry points: */
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global setjmp
|
||||||
|
.proc setjmp
|
||||||
|
setjmp:
|
||||||
|
alloc r8=ar.pfs,2,0,0,0
|
||||||
|
mov in1=1
|
||||||
|
br.cond.sptk.many __sigsetjmp
|
||||||
|
.endp setjmp
|
||||||
|
|
||||||
|
/* __sigsetjmp(__jmp_buf buf, int savemask) */
|
||||||
|
|
||||||
|
.proc __sigsetjmp
|
||||||
|
__sigsetjmp:
|
||||||
|
//.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
|
||||||
|
alloc loc1=ar.pfs,2,2,2,0
|
||||||
|
mov r16=ar.unat
|
||||||
|
;;
|
||||||
|
mov r17=ar.fpsr
|
||||||
|
mov r2=in0
|
||||||
|
add r3=8,in0
|
||||||
|
;;
|
||||||
|
st8.spill.nta [r2]=sp,16 // r12 (sp)
|
||||||
|
st8.spill.nta [r3]=gp,16 // r1 (gp)
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=r16,16 // save caller's unat
|
||||||
|
st8.nta [r3]=r17,16 // save fpsr
|
||||||
|
add r8=0xa0,in0
|
||||||
|
;;
|
||||||
|
st8.spill.nta [r2]=r4,16 // r4
|
||||||
|
st8.spill.nta [r3]=r5,16 // r5
|
||||||
|
add r9=0xb0,in0
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f2,32
|
||||||
|
stf.spill.nta [r9]=f3,32
|
||||||
|
mov loc0=rp
|
||||||
|
.body
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f4,32
|
||||||
|
stf.spill.nta [r9]=f5,32
|
||||||
|
mov r17=b1
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f16,32
|
||||||
|
stf.spill.nta [r9]=f17,32
|
||||||
|
mov r18=b2
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f18,32
|
||||||
|
stf.spill.nta [r9]=f19,32
|
||||||
|
mov r19=b3
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f20,32
|
||||||
|
stf.spill.nta [r9]=f21,32
|
||||||
|
mov r20=b4
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f22,32
|
||||||
|
stf.spill.nta [r9]=f23,32
|
||||||
|
mov r21=b5
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f24,32
|
||||||
|
stf.spill.nta [r9]=f25,32
|
||||||
|
mov r22=ar.lc
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f26,32
|
||||||
|
stf.spill.nta [r9]=f27,32
|
||||||
|
mov r24=pr
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f28,32
|
||||||
|
stf.spill.nta [r9]=f29,32
|
||||||
|
;;
|
||||||
|
stf.spill.nta [r8]=f30
|
||||||
|
stf.spill.nta [r9]=f31
|
||||||
|
|
||||||
|
st8.spill.nta [r2]=r6,16 // r6
|
||||||
|
st8.spill.nta [r3]=r7,16 // r7
|
||||||
|
;;
|
||||||
|
mov r23=ar.bsp
|
||||||
|
mov r25=ar.unat
|
||||||
|
mov out0=in0
|
||||||
|
|
||||||
|
st8.nta [r2]=loc0,16 // b0
|
||||||
|
st8.nta [r3]=r17,16 // b1
|
||||||
|
mov out1=in1
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=r18,16 // b2
|
||||||
|
st8.nta [r3]=r19,16 // b3
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=r20,16 // b4
|
||||||
|
st8.nta [r3]=r21,16 // b5
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=loc1,16 // ar.pfs
|
||||||
|
st8.nta [r3]=r22,16 // ar.lc
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=r24,16 // pr
|
||||||
|
st8.nta [r3]=r23,16 // ar.bsp
|
||||||
|
;;
|
||||||
|
st8.nta [r2]=r25 // ar.unat
|
||||||
|
st8.nta [r3]=in0 // &__jmp_buf
|
||||||
|
mov r8=0
|
||||||
|
mov rp=loc0
|
||||||
|
mov ar.pfs=loc1
|
||||||
|
br.ret.sptk.many rp
|
||||||
|
|
||||||
|
.endp __sigsetjmp
|
|
@ -8,6 +8,8 @@
|
||||||
#include "./mips/setjmp.S"
|
#include "./mips/setjmp.S"
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
#include "./powerpc/setjmp.S"
|
#include "./powerpc/setjmp.S"
|
||||||
|
#elif defined(__ia64__)
|
||||||
|
#include "./ia64/setjmp.S"
|
||||||
#else
|
#else
|
||||||
#error "Unknwon target cpu type"
|
#error "Unknown target cpu type"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,6 +57,7 @@ grub_chainloader_unload (void)
|
||||||
grub_free (file_path);
|
grub_free (file_path);
|
||||||
grub_free (cmdline);
|
grub_free (cmdline);
|
||||||
cmdline = 0;
|
cmdline = 0;
|
||||||
|
file_path = 0;
|
||||||
|
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -68,7 +69,7 @@ grub_chainloader_boot (void)
|
||||||
grub_efi_boot_services_t *b;
|
grub_efi_boot_services_t *b;
|
||||||
grub_efi_status_t status;
|
grub_efi_status_t status;
|
||||||
grub_efi_uintn_t exit_data_size;
|
grub_efi_uintn_t exit_data_size;
|
||||||
grub_efi_char16_t *exit_data;
|
grub_efi_char16_t *exit_data = NULL;
|
||||||
|
|
||||||
b = grub_efi_system_table->boot_services;
|
b = grub_efi_system_table->boot_services;
|
||||||
status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
|
status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
|
||||||
|
@ -95,7 +96,7 @@ grub_chainloader_boot (void)
|
||||||
if (exit_data)
|
if (exit_data)
|
||||||
efi_call_1 (b->free_pool, exit_data);
|
efi_call_1 (b->free_pool, exit_data);
|
||||||
|
|
||||||
grub_chainloader_unload ();
|
grub_loader_unset ();
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -238,6 +239,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_efi_print_device_path (file_path);
|
grub_efi_print_device_path (file_path);
|
||||||
|
|
||||||
size = grub_file_size (file);
|
size = grub_file_size (file);
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "file is empty");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
|
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
|
||||||
|
|
||||||
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
|
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
|
||||||
|
|
|
@ -57,7 +57,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GRUB_LINUX_CL_OFFSET 0x1000
|
#define GRUB_LINUX_CL_OFFSET 0x1000
|
||||||
#define GRUB_LINUX_CL_END_OFFSET 0x2000
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
@ -74,6 +73,7 @@ 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 struct grub_relocator *relocator = NULL;
|
||||||
static void *efi_mmap_buf;
|
static void *efi_mmap_buf;
|
||||||
|
static grub_size_t maximal_cmdline_size;
|
||||||
#ifdef GRUB_MACHINE_EFI
|
#ifdef GRUB_MACHINE_EFI
|
||||||
static grub_efi_uintn_t efi_mmap_size;
|
static grub_efi_uintn_t efi_mmap_size;
|
||||||
#else
|
#else
|
||||||
|
@ -189,7 +189,7 @@ allocate_pages (grub_size_t prot_size)
|
||||||
grub_err_t err;
|
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_OFFSET + maximal_cmdline_size;
|
||||||
prot_size = page_align (prot_size);
|
prot_size = page_align (prot_size);
|
||||||
mmap_size = find_mmap_size ();
|
mmap_size = find_mmap_size ();
|
||||||
|
|
||||||
|
@ -367,6 +367,7 @@ grub_linux_setup_video (struct linux_kernel_params *params)
|
||||||
|
|
||||||
/* FIXME: check if better id is available. */
|
/* FIXME: check if better id is available. */
|
||||||
case GRUB_VIDEO_DRIVER_SM712:
|
case GRUB_VIDEO_DRIVER_SM712:
|
||||||
|
case GRUB_VIDEO_DRIVER_SIS315PRO:
|
||||||
case GRUB_VIDEO_DRIVER_VGA:
|
case GRUB_VIDEO_DRIVER_VGA:
|
||||||
case GRUB_VIDEO_DRIVER_CIRRUS:
|
case GRUB_VIDEO_DRIVER_CIRRUS:
|
||||||
case GRUB_VIDEO_DRIVER_BOCHS:
|
case GRUB_VIDEO_DRIVER_BOCHS:
|
||||||
|
@ -662,6 +663,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (lh.version) >= 0x0206)
|
||||||
|
maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
|
||||||
|
else
|
||||||
|
maximal_cmdline_size = 256;
|
||||||
|
|
||||||
|
if (maximal_cmdline_size < 128)
|
||||||
|
maximal_cmdline_size = 128;
|
||||||
|
|
||||||
setup_sects = lh.setup_sects;
|
setup_sects = lh.setup_sects;
|
||||||
|
|
||||||
/* If SETUP_SECTS is not set, set it to the default (4). */
|
/* If SETUP_SECTS is not set, set it to the default (4). */
|
||||||
|
@ -675,7 +684,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
params = (struct linux_kernel_params *) real_mode_mem;
|
params = (struct linux_kernel_params *) real_mode_mem;
|
||||||
grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
|
grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
|
||||||
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
|
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
|
||||||
|
|
||||||
params->ps_mouse = params->padding10 = 0;
|
params->ps_mouse = params->padding10 = 0;
|
||||||
|
@ -870,7 +879,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_create_loader_cmdline (argc, argv,
|
grub_create_loader_cmdline (argc, argv,
|
||||||
(char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
|
(char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
|
||||||
+ sizeof (LINUX_IMAGE) - 1,
|
+ sizeof (LINUX_IMAGE) - 1,
|
||||||
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
|
maximal_cmdline_size
|
||||||
- (sizeof (LINUX_IMAGE) - 1));
|
- (sizeof (LINUX_IMAGE) - 1));
|
||||||
|
|
||||||
len = prot_size;
|
len = prot_size;
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
#include <grub/fat.h>
|
||||||
|
#include <grub/ntfs.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -44,6 +46,12 @@ static grub_dl_t my_mod;
|
||||||
static int boot_drive;
|
static int boot_drive;
|
||||||
static void *boot_part_addr;
|
static void *boot_part_addr;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GRUB_CHAINLOADER_FORCE = 0x1,
|
||||||
|
GRUB_CHAINLOADER_BPB = 0x2,
|
||||||
|
} grub_chainloader_flags_t;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_chainloader_boot (void)
|
grub_chainloader_boot (void)
|
||||||
{
|
{
|
||||||
|
@ -61,6 +69,63 @@ grub_chainloader_unload (void)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl)
|
||||||
|
{
|
||||||
|
grub_uint32_t part_start = 0;
|
||||||
|
if (dev && dev->disk)
|
||||||
|
part_start = grub_partition_get_start (dev->disk->partition);
|
||||||
|
if (grub_memcmp ((char *) &((struct grub_ntfs_bpb *) bs)->oem_name,
|
||||||
|
"NTFS", 4) == 0)
|
||||||
|
{
|
||||||
|
struct grub_ntfs_bpb *bpb = (struct grub_ntfs_bpb *) bs;
|
||||||
|
bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start);
|
||||||
|
bpb->bios_drive = dl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
struct grub_fat_bpb *bpb = (struct grub_fat_bpb *) bs;
|
||||||
|
if (grub_strncmp((const char *) bpb->version_specific.fat12_or_fat16.fstype, "FAT12", 5)
|
||||||
|
&& grub_strncmp((const char *) bpb->version_specific.fat12_or_fat16.fstype, "FAT16", 5)
|
||||||
|
&& grub_strncmp((const char *) bpb->version_specific.fat32.fstype, "FAT32", 5))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (bpb->bytes_per_sector) < 512
|
||||||
|
|| (grub_le_to_cpu16 (bpb->bytes_per_sector)
|
||||||
|
& (grub_le_to_cpu16 (bpb->bytes_per_sector) - 1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bpb->sectors_per_cluster == 0
|
||||||
|
|| (bpb->sectors_per_cluster & (bpb->sectors_per_cluster - 1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bpb->num_reserved_sectors == 0)
|
||||||
|
break;
|
||||||
|
if (bpb->num_total_sectors_16 == 0 || bpb->num_total_sectors_32 == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bpb->num_fats == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bpb->sectors_per_fat_16)
|
||||||
|
{
|
||||||
|
bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start);
|
||||||
|
bpb->version_specific.fat12_or_fat16.num_ph_drive = dl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bpb->version_specific.fat32.sectors_per_fat_32)
|
||||||
|
{
|
||||||
|
bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start);
|
||||||
|
bpb->version_specific.fat32.num_ph_drive = dl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +186,9 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & GRUB_CHAINLOADER_BPB)
|
||||||
|
grub_chainloader_patch_bpb ((void *) 0x7C00, dev, drive);
|
||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
|
|
||||||
|
@ -147,11 +215,23 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_chainloader_flags_t flags = 0;
|
grub_chainloader_flags_t flags = 0;
|
||||||
|
|
||||||
if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
|
while (argc > 0)
|
||||||
{
|
{
|
||||||
flags |= GRUB_CHAINLOADER_FORCE;
|
if (grub_strcmp (argv[0], "--force") == 0)
|
||||||
argc--;
|
{
|
||||||
argv++;
|
flags |= GRUB_CHAINLOADER_FORCE;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (grub_strcmp (argv[0], "--bpb") == 0)
|
||||||
|
{
|
||||||
|
flags |= GRUB_CHAINLOADER_BPB;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
|
@ -167,7 +247,8 @@ static grub_command_t cmd;
|
||||||
GRUB_MOD_INIT(chainloader)
|
GRUB_MOD_INIT(chainloader)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
|
cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
|
||||||
0, N_("Load another boot loader."));
|
"[--force|--bpb] FILE",
|
||||||
|
N_("Load another boot loader."));
|
||||||
my_mod = mod;
|
my_mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
136
grub-core/loader/i386/pc/freedos.c
Normal file
136
grub-core/loader/i386/pc/freedos.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/* 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 ebx = 0xffffffff;
|
||||||
|
|
||||||
|
#define GRUB_FREEDOS_SEGMENT 0x60
|
||||||
|
#define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0
|
||||||
|
#define GRUB_FREEDOS_STACK_POINTER 0x8000
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_freedos_boot (void)
|
||||||
|
{
|
||||||
|
struct grub_relocator16_state state = {
|
||||||
|
.cs = GRUB_FREEDOS_SEGMENT,
|
||||||
|
.ip = 0,
|
||||||
|
.ds = 0,
|
||||||
|
.es = 0,
|
||||||
|
.fs = 0,
|
||||||
|
.gs = 0,
|
||||||
|
.ss = GRUB_FREEDOS_STACK_SEGMENT,
|
||||||
|
.sp = GRUB_FREEDOS_STACK_POINTER,
|
||||||
|
.ebx = ebx,
|
||||||
|
.edx = 0
|
||||||
|
};
|
||||||
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
return grub_relocator16_boot (rel, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_freedos_unload (void)
|
||||||
|
{
|
||||||
|
grub_relocator_unload (rel);
|
||||||
|
rel = NULL;
|
||||||
|
grub_dl_unref (my_mod);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
grub_file_t file = 0;
|
||||||
|
grub_err_t err;
|
||||||
|
void *kernelsys;
|
||||||
|
grub_size_t kernelsyssize;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ebx = grub_get_root_biosnumber ();
|
||||||
|
|
||||||
|
kernelsyssize = grub_file_size (file);
|
||||||
|
{
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4,
|
||||||
|
kernelsyssize);
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
kernelsys = get_virtual_current_address (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_file_read (file, kernelsys, kernelsyssize)
|
||||||
|
!= (grub_ssize_t) kernelsyssize)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
|
||||||
|
grub_freedos_unload ();
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_command_t cmd;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(freedos)
|
||||||
|
{
|
||||||
|
cmd = grub_register_command ("freedos", grub_cmd_freedos,
|
||||||
|
0, N_("Load FreeDOS kernel.sys."));
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(freedos)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd);
|
||||||
|
}
|
|
@ -39,7 +39,6 @@
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_LINUX_CL_OFFSET 0x9000
|
#define GRUB_LINUX_CL_OFFSET 0x9000
|
||||||
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
@ -49,6 +48,7 @@ static struct grub_relocator *relocator = NULL;
|
||||||
static grub_addr_t grub_linux_real_target;
|
static grub_addr_t grub_linux_real_target;
|
||||||
static char *grub_linux_real_chunk;
|
static char *grub_linux_real_chunk;
|
||||||
static grub_size_t grub_linux16_prot_size;
|
static grub_size_t grub_linux16_prot_size;
|
||||||
|
static grub_size_t maximal_cmdline_size;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux16_boot (void)
|
grub_linux16_boot (void)
|
||||||
|
@ -128,15 +128,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
setup_sects = lh.setup_sects;
|
setup_sects = lh.setup_sects;
|
||||||
linux_mem_size = 0;
|
linux_mem_size = 0;
|
||||||
|
|
||||||
|
maximal_cmdline_size = 256;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
|
grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
|
||||||
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
|
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (lh.version) >= 0x0206)
|
||||||
|
maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
|
||||||
|
|
||||||
/* 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_target = grub_mmap_get_lower ()
|
grub_linux_real_target = grub_mmap_get_lower ()
|
||||||
- GRUB_LINUX_SETUP_MOVE_SIZE;
|
- (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
|
||||||
/* But it must not exceed the traditional area. */
|
/* But it must not exceed the traditional area. */
|
||||||
if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR)
|
if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR)
|
||||||
grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
|
||||||
|
@ -153,7 +158,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
|
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
|
||||||
lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
|
lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
|
||||||
lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE);
|
lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET
|
||||||
|
+ maximal_cmdline_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -185,12 +191,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE
|
if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size
|
||||||
> 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_target + GRUB_LINUX_SETUP_MOVE_SIZE,
|
grub_linux_real_target + GRUB_LINUX_CL_OFFSET
|
||||||
|
+ maximal_cmdline_size,
|
||||||
(int) grub_mmap_get_lower ());
|
(int) grub_mmap_get_lower ());
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +270,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
grub_linux_real_target,
|
grub_linux_real_target,
|
||||||
GRUB_LINUX_SETUP_MOVE_SIZE);
|
GRUB_LINUX_CL_OFFSET
|
||||||
|
+ maximal_cmdline_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
grub_linux_real_chunk = get_virtual_current_address (ch);
|
grub_linux_real_chunk = get_virtual_current_address (ch);
|
||||||
|
@ -294,7 +302,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_create_loader_cmdline (argc, argv,
|
grub_create_loader_cmdline (argc, argv,
|
||||||
(char *)grub_linux_real_chunk
|
(char *)grub_linux_real_chunk
|
||||||
+ GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
|
+ GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
|
||||||
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
|
maximal_cmdline_size
|
||||||
- (sizeof (LINUX_IMAGE) - 1));
|
- (sizeof (LINUX_IMAGE) - 1));
|
||||||
|
|
||||||
if (grub_linux_is_bzimage)
|
if (grub_linux_is_bzimage)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/cpu/relocator.h>
|
#include <grub/cpu/relocator.h>
|
||||||
|
#include <grub/machine/chainloader.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
grub_chainloader_patch_bpb (bs, dev, edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
|
|
795
grub-core/loader/ia64/efi/linux.c
Normal file
795
grub-core/loader/ia64/efi/linux.c
Normal file
|
@ -0,0 +1,795 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2008,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/disk.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/cache.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/elf.h>
|
||||||
|
|
||||||
|
#define ALIGN_MIN (256*1024*1024)
|
||||||
|
|
||||||
|
#define GRUB_ELF_SEARCH 1024
|
||||||
|
|
||||||
|
#define BOOT_PARAM_SIZE 16384
|
||||||
|
|
||||||
|
struct ia64_boot_param
|
||||||
|
{
|
||||||
|
grub_uint64_t command_line; /* physical address of command line. */
|
||||||
|
grub_uint64_t efi_systab; /* physical address of EFI system table */
|
||||||
|
grub_uint64_t efi_memmap; /* physical address of EFI memory map */
|
||||||
|
grub_uint64_t efi_memmap_size; /* size of EFI memory map */
|
||||||
|
grub_uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
|
||||||
|
grub_uint32_t efi_memdesc_version; /* memory descriptor version */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
grub_uint16_t num_cols; /* number of columns on console output dev */
|
||||||
|
grub_uint16_t num_rows; /* number of rows on console output device */
|
||||||
|
grub_uint16_t orig_x; /* cursor's x position */
|
||||||
|
grub_uint16_t orig_y; /* cursor's y position */
|
||||||
|
} console_info;
|
||||||
|
grub_uint64_t fpswa; /* physical address of the fpswa interface */
|
||||||
|
grub_uint64_t initrd_start;
|
||||||
|
grub_uint64_t initrd_size;
|
||||||
|
grub_uint64_t domain_start; /* boot domain address. */
|
||||||
|
grub_uint64_t domain_size; /* how big is the boot domain */
|
||||||
|
grub_uint64_t payloads_chain;
|
||||||
|
grub_uint64_t payloads_nbr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ia64_boot_payload
|
||||||
|
{
|
||||||
|
grub_uint64_t start;
|
||||||
|
grub_uint64_t length;
|
||||||
|
|
||||||
|
/* Payload command line */
|
||||||
|
grub_uint64_t cmdline;
|
||||||
|
|
||||||
|
grub_uint64_t next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
grub_uint32_t revision;
|
||||||
|
grub_uint32_t reserved;
|
||||||
|
void *fpswa;
|
||||||
|
} fpswa_interface_t;
|
||||||
|
static fpswa_interface_t *fpswa;
|
||||||
|
|
||||||
|
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
|
||||||
|
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||||
|
|
||||||
|
static grub_dl_t my_mod;
|
||||||
|
|
||||||
|
static int loaded;
|
||||||
|
|
||||||
|
/* Kernel base and size. */
|
||||||
|
static void *kernel_mem;
|
||||||
|
static grub_efi_uintn_t kernel_pages;
|
||||||
|
static grub_uint64_t entry;
|
||||||
|
|
||||||
|
/* Initrd base and size. */
|
||||||
|
static void *initrd_mem;
|
||||||
|
static grub_efi_uintn_t initrd_pages;
|
||||||
|
static grub_efi_uintn_t initrd_size;
|
||||||
|
|
||||||
|
static struct ia64_boot_param *boot_param;
|
||||||
|
static grub_efi_uintn_t boot_param_pages;
|
||||||
|
static struct ia64_boot_payload *last_payload = NULL;
|
||||||
|
|
||||||
|
/* Can linux kernel be relocated ? */
|
||||||
|
#define RELOCATE_OFF 0 /* No. */
|
||||||
|
#define RELOCATE_ON 1 /* Yes. */
|
||||||
|
#define RELOCATE_FORCE 2 /* Always - used to debug. */
|
||||||
|
static int relocate = RELOCATE_OFF;
|
||||||
|
|
||||||
|
static inline grub_size_t
|
||||||
|
page_align (grub_size_t size)
|
||||||
|
{
|
||||||
|
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
query_fpswa (void)
|
||||||
|
{
|
||||||
|
grub_efi_handle_t fpswa_image;
|
||||||
|
grub_efi_boot_services_t *bs;
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_uintn_t size;
|
||||||
|
static const grub_efi_guid_t fpswa_protocol =
|
||||||
|
{ 0xc41b6531, 0x97b9, 0x11d3,
|
||||||
|
{0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} };
|
||||||
|
|
||||||
|
if (fpswa != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size = sizeof(grub_efi_handle_t);
|
||||||
|
|
||||||
|
bs = grub_efi_system_table->boot_services;
|
||||||
|
status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL,
|
||||||
|
(void *)&fpswa_protocol,
|
||||||
|
NULL, &size, &fpswa_image);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_printf("Could not locate FPSWA driver\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
status = bs->handle_protocol (fpswa_image,
|
||||||
|
(void *)&fpswa_protocol, (void *)&fpswa);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
grub_printf ("Fpswa protocol not able find the interface\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (kernel_mem)
|
||||||
|
{
|
||||||
|
grub_efi_free_pages ((grub_addr_t) kernel_mem, kernel_pages);
|
||||||
|
kernel_mem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initrd_mem)
|
||||||
|
{
|
||||||
|
grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
|
||||||
|
initrd_mem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boot_param)
|
||||||
|
{
|
||||||
|
struct ia64_boot_payload *payload;
|
||||||
|
struct ia64_boot_payload *next_payload;
|
||||||
|
|
||||||
|
/* Free payloads. */
|
||||||
|
payload = (struct ia64_boot_payload *)boot_param->payloads_chain;
|
||||||
|
while (payload != 0)
|
||||||
|
{
|
||||||
|
next_payload = (struct ia64_boot_payload *)payload->next;
|
||||||
|
|
||||||
|
grub_efi_free_pages
|
||||||
|
(payload->start, page_align (payload->length) >> 12);
|
||||||
|
grub_efi_free_pages ((grub_efi_physical_address_t)payload, 1);
|
||||||
|
|
||||||
|
payload = next_payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free bootparam. */
|
||||||
|
grub_efi_free_pages ((grub_efi_physical_address_t)boot_param,
|
||||||
|
boot_param_pages);
|
||||||
|
boot_param = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
allocate_pages (grub_uint64_t align, grub_uint64_t size_pages,
|
||||||
|
grub_uint64_t nobase)
|
||||||
|
{
|
||||||
|
grub_uint64_t 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;
|
||||||
|
void *mem = NULL;
|
||||||
|
|
||||||
|
size = size_pages << 12;
|
||||||
|
|
||||||
|
mmap_size = find_mmap_size ();
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
{
|
||||||
|
grub_uint64_t start, end;
|
||||||
|
grub_uint64_t aligned_start;
|
||||||
|
|
||||||
|
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
start = desc->physical_start;
|
||||||
|
end = start + (desc->num_pages << 12);
|
||||||
|
/* Align is a power of 2. */
|
||||||
|
aligned_start = (start + align - 1) & ~(align - 1);
|
||||||
|
if (aligned_start + size > end)
|
||||||
|
continue;
|
||||||
|
if (aligned_start == nobase)
|
||||||
|
aligned_start += align;
|
||||||
|
if (aligned_start + size > end)
|
||||||
|
continue;
|
||||||
|
mem = grub_efi_allocate_pages (aligned_start, size_pages);
|
||||||
|
if (! mem)
|
||||||
|
grub_fatal ("cannot allocate pages");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! mem)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free (mmap);
|
||||||
|
return mem;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (mmap);
|
||||||
|
free_pages ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_boot_param_console (void)
|
||||||
|
{
|
||||||
|
grub_efi_simple_text_output_interface_t *conout;
|
||||||
|
grub_efi_uintn_t cols, rows;
|
||||||
|
|
||||||
|
conout = grub_efi_system_table->con_out;
|
||||||
|
if (conout->query_mode (conout, conout->mode->mode, &cols, &rows)
|
||||||
|
!= GRUB_EFI_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_dprintf("linux",
|
||||||
|
"Console info: cols=%lu rows=%lu x=%u y=%u\n",
|
||||||
|
cols, rows,
|
||||||
|
conout->mode->cursor_column, conout->mode->cursor_row);
|
||||||
|
|
||||||
|
boot_param->console_info.num_cols = cols;
|
||||||
|
boot_param->console_info.num_rows = rows;
|
||||||
|
boot_param->console_info.orig_x = conout->mode->cursor_column;
|
||||||
|
boot_param->console_info.orig_y = conout->mode->cursor_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_boot (void)
|
||||||
|
{
|
||||||
|
grub_efi_uintn_t mmap_size;
|
||||||
|
grub_efi_uintn_t map_key;
|
||||||
|
grub_efi_uintn_t desc_size;
|
||||||
|
grub_efi_uint32_t desc_version;
|
||||||
|
grub_efi_memory_descriptor_t *mmap_buf;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
/* FPSWA. */
|
||||||
|
query_fpswa ();
|
||||||
|
boot_param->fpswa = (grub_uint64_t)fpswa;
|
||||||
|
|
||||||
|
/* Initrd. */
|
||||||
|
boot_param->initrd_start = (grub_uint64_t)initrd_mem;
|
||||||
|
boot_param->initrd_size = (grub_uint64_t)initrd_size;
|
||||||
|
|
||||||
|
set_boot_param_console ();
|
||||||
|
|
||||||
|
grub_printf ("Jump to %016lx\n", entry);
|
||||||
|
|
||||||
|
grub_machine_fini ();
|
||||||
|
|
||||||
|
/* MDT.
|
||||||
|
Must be done after grub_machine_fini because map_key is used by
|
||||||
|
exit_boot_services. */
|
||||||
|
mmap_size = find_mmap_size ();
|
||||||
|
mmap_buf = grub_efi_allocate_pages (0, page_align (mmap_size) >> 12);
|
||||||
|
if (! mmap_buf)
|
||||||
|
grub_fatal ("cannot allocate memory map");
|
||||||
|
err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key,
|
||||||
|
&desc_size, &desc_version);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
boot_param->efi_memmap = (grub_uint64_t)mmap_buf;
|
||||||
|
boot_param->efi_memmap_size = mmap_size;
|
||||||
|
boot_param->efi_memdesc_size = desc_size;
|
||||||
|
boot_param->efi_memdesc_version = desc_version;
|
||||||
|
|
||||||
|
/* See you next boot. */
|
||||||
|
asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(entry),"r"(boot_param));
|
||||||
|
|
||||||
|
/* 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_load_elf64 (grub_file_t file, void *buffer)
|
||||||
|
{
|
||||||
|
Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
|
||||||
|
Elf64_Phdr *phdr;
|
||||||
|
int i;
|
||||||
|
grub_uint64_t low_addr;
|
||||||
|
grub_uint64_t high_addr;
|
||||||
|
grub_uint64_t align;
|
||||||
|
grub_uint64_t reloc_offset;
|
||||||
|
|
||||||
|
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
|
||||||
|
return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
|
||||||
|
|
||||||
|
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|
||||||
|
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
|
||||||
|
|| ehdr->e_ident[EI_MAG2] != ELFMAG2
|
||||||
|
|| ehdr->e_ident[EI_MAG3] != ELFMAG3
|
||||||
|
|| ehdr->e_version != EV_CURRENT
|
||||||
|
|| ehdr->e_ident[EI_DATA] != ELFDATA2LSB
|
||||||
|
|| ehdr->e_machine != EM_IA_64)
|
||||||
|
return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
|
||||||
|
|
||||||
|
if (ehdr->e_type != ET_EXEC)
|
||||||
|
return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
|
||||||
|
|
||||||
|
/* FIXME: Should we support program headers at strange locations? */
|
||||||
|
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_ELF_SEARCH)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
|
||||||
|
|
||||||
|
entry = ehdr->e_entry;
|
||||||
|
|
||||||
|
/* Compute low, high and align addresses. */
|
||||||
|
low_addr = ~0UL;
|
||||||
|
high_addr = 0;
|
||||||
|
align = 0;
|
||||||
|
for (i = 0; i < ehdr->e_phnum; i++)
|
||||||
|
{
|
||||||
|
phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
|
||||||
|
+ i * ehdr->e_phentsize);
|
||||||
|
if (phdr->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
if (phdr->p_paddr < low_addr)
|
||||||
|
low_addr = phdr->p_paddr;
|
||||||
|
if (phdr->p_paddr + phdr->p_memsz > high_addr)
|
||||||
|
high_addr = phdr->p_paddr + phdr->p_memsz;
|
||||||
|
if (phdr->p_align > align)
|
||||||
|
align = phdr->p_align;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (align < ALIGN_MIN)
|
||||||
|
align = ALIGN_MIN;
|
||||||
|
|
||||||
|
if (high_addr == 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS, "no program entries");
|
||||||
|
|
||||||
|
kernel_pages = page_align (high_addr - low_addr) >> 12;
|
||||||
|
|
||||||
|
if (relocate != RELOCATE_FORCE)
|
||||||
|
{
|
||||||
|
kernel_mem = grub_efi_allocate_pages (low_addr, kernel_pages);
|
||||||
|
reloc_offset = 0;
|
||||||
|
}
|
||||||
|
/* Try to relocate. */
|
||||||
|
if (! kernel_mem && relocate != RELOCATE_OFF)
|
||||||
|
{
|
||||||
|
kernel_mem = allocate_pages (align, kernel_pages, low_addr);
|
||||||
|
if (kernel_mem)
|
||||||
|
{
|
||||||
|
reloc_offset = (grub_uint64_t)kernel_mem - low_addr;
|
||||||
|
grub_printf (" Relocated at %p (offset=%016lx)\n",
|
||||||
|
kernel_mem, reloc_offset);
|
||||||
|
entry += reloc_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! kernel_mem)
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||||
|
"cannot allocate memory for OS");
|
||||||
|
|
||||||
|
/* Load every loadable segment in memory. */
|
||||||
|
for (i = 0; i < ehdr->e_phnum; i++)
|
||||||
|
{
|
||||||
|
phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
|
||||||
|
+ i * ehdr->e_phentsize);
|
||||||
|
if (phdr->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
grub_printf (" [paddr=%lx load=%lx memsz=%08lx "
|
||||||
|
"off=%lx flags=%x]\n",
|
||||||
|
phdr->p_paddr, phdr->p_paddr + reloc_offset,
|
||||||
|
phdr->p_memsz, phdr->p_offset, phdr->p_flags);
|
||||||
|
|
||||||
|
if (grub_file_seek (file, phdr->p_offset) == (grub_off_t)-1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"invalid offset in program header");
|
||||||
|
|
||||||
|
if (grub_file_read (file, (void *)(phdr->p_paddr + reloc_offset),
|
||||||
|
phdr->p_filesz)
|
||||||
|
!= (grub_ssize_t) phdr->p_filesz)
|
||||||
|
return grub_error (GRUB_ERR_BAD_OS,
|
||||||
|
"couldn't read segment from file");
|
||||||
|
|
||||||
|
if (phdr->p_filesz < phdr->p_memsz)
|
||||||
|
grub_memset
|
||||||
|
((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz),
|
||||||
|
0, phdr->p_memsz - phdr->p_filesz);
|
||||||
|
|
||||||
|
/* Sync caches if necessary. */
|
||||||
|
if (phdr->p_flags & PF_X)
|
||||||
|
grub_arch_sync_caches
|
||||||
|
((void *)(phdr->p_paddr + reloc_offset), phdr->p_memsz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loaded = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
grub_file_t file = 0;
|
||||||
|
char buffer[GRUB_ELF_SEARCH];
|
||||||
|
char *cmdline, *p;
|
||||||
|
grub_ssize_t len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
grub_loader_unset ();
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = grub_file_open (argv[0]);
|
||||||
|
if (! file)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = grub_file_read (file, buffer, sizeof (buffer));
|
||||||
|
if (len < (grub_ssize_t)sizeof (Elf64_Ehdr))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "File too small");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_printf ("Loading linux: %s\n", argv[0]);
|
||||||
|
|
||||||
|
if (grub_load_elf64 (file, buffer))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
len = sizeof("BOOT_IMAGE=") + 8;
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
len += grub_strlen (argv[i]) + 1;
|
||||||
|
len += sizeof (struct ia64_boot_param) + 256; /* Room for extensions. */
|
||||||
|
boot_param_pages = page_align (len) >> 12;
|
||||||
|
boot_param = grub_efi_allocate_pages (0, boot_param_pages);
|
||||||
|
if (boot_param == 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||||
|
"cannot allocate memory for bootparams");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_memset (boot_param, 0, len);
|
||||||
|
cmdline = ((char *)(boot_param + 1)) + 256;
|
||||||
|
|
||||||
|
/* Build cmdline. */
|
||||||
|
p = grub_stpcpy (cmdline, "BOOT_IMAGE");
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
*p++ = ' ';
|
||||||
|
p = grub_stpcpy (p, argv[i]);
|
||||||
|
}
|
||||||
|
cmdline[10] = '=';
|
||||||
|
|
||||||
|
boot_param->command_line = (grub_uint64_t) cmdline;
|
||||||
|
boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table;
|
||||||
|
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_efi_free_pages ((grub_efi_physical_address_t) boot_param,
|
||||||
|
boot_param_pages);
|
||||||
|
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 filename 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;
|
||||||
|
|
||||||
|
grub_printf ("Loading initrd: %s\n",argv[0]);
|
||||||
|
|
||||||
|
initrd_size = grub_file_size (file);
|
||||||
|
initrd_pages = (page_align (initrd_size) >> 12);
|
||||||
|
initrd_mem = grub_efi_allocate_pages (0, initrd_pages);
|
||||||
|
if (! initrd_mem)
|
||||||
|
grub_fatal ("cannot allocate pages");
|
||||||
|
|
||||||
|
grub_printf (" [addr=0x%lx, size=0x%lx]\n",
|
||||||
|
(grub_uint64_t)initrd_mem, initrd_size);
|
||||||
|
|
||||||
|
if (grub_file_read (file, initrd_mem, initrd_size)
|
||||||
|
!= (grub_ssize_t)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_err_t
|
||||||
|
grub_cmd_payload (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
grub_file_t file = 0;
|
||||||
|
grub_ssize_t size, len = 0;
|
||||||
|
char *base = 0, *cmdline = 0, *p;
|
||||||
|
struct ia64_boot_payload *payload = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boot_param)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
base = grub_efi_allocate_pages (0, page_align (size) >> 12);
|
||||||
|
if (! base)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_printf ("Payload %s [addr=%lx + %lx]\n",
|
||||||
|
argv[0], (grub_uint64_t)base, size);
|
||||||
|
|
||||||
|
if (grub_file_read (file, base, size) != size)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof (struct ia64_boot_payload);
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
len += grub_strlen (argv[i]) + 1;
|
||||||
|
|
||||||
|
if (len > 4096)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, "payload command line too long");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
payload = grub_efi_allocate_pages (0, 1);
|
||||||
|
if (! payload)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
p = (char *)(payload + 1);
|
||||||
|
|
||||||
|
payload->start = (grub_uint64_t)base;
|
||||||
|
payload->length = size;
|
||||||
|
payload->cmdline = (grub_uint64_t)p;
|
||||||
|
payload->next = 0;
|
||||||
|
|
||||||
|
if (last_payload)
|
||||||
|
last_payload->next = (grub_uint64_t)payload;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_payload = payload;
|
||||||
|
boot_param->payloads_chain = (grub_uint64_t)payload;
|
||||||
|
}
|
||||||
|
boot_param->payloads_nbr++;
|
||||||
|
|
||||||
|
/* Copy command line. */
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
p = grub_stpcpy (p, argv[i]);
|
||||||
|
*(p++) = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the space after the last word. */
|
||||||
|
*(--p) = '\0';
|
||||||
|
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (file)
|
||||||
|
grub_file_close (file);
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_free (base);
|
||||||
|
grub_free (cmdline);
|
||||||
|
}
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_relocate (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static const char * const vals[] = { "off", "on", "force"};
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (argc == 0)
|
||||||
|
{
|
||||||
|
grub_printf ("relocate is %s\n", vals[relocate]);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
else if (argc == 1)
|
||||||
|
{
|
||||||
|
if (kernel_mem != NULL)
|
||||||
|
grub_printf ("Warning: kernel already loaded!\n");
|
||||||
|
for (i = 0; i < sizeof (vals)/sizeof(vals[0]); i++)
|
||||||
|
if (grub_strcmp (argv[0], vals[i]) == 0)
|
||||||
|
{
|
||||||
|
relocate = i;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_fpswa (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
int argc, char *argv[] __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (argc != 0)
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected");
|
||||||
|
}
|
||||||
|
query_fpswa ();
|
||||||
|
if (fpswa == NULL)
|
||||||
|
grub_printf ("No FPSWA loaded\n");
|
||||||
|
else
|
||||||
|
grub_printf ("FPSWA revision: %x\n", fpswa->revision);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_command_t cmd_linux, cmd_initrd, cmd_payload, cmd_relocate, cmd_fpswa;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(linux)
|
||||||
|
{
|
||||||
|
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
|
||||||
|
"FILE [ARGS...]", "Load Linux.");
|
||||||
|
|
||||||
|
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
|
||||||
|
"FILE", "Load initrd.");
|
||||||
|
|
||||||
|
cmd_payload = grub_register_command ("payload", grub_cmd_payload,
|
||||||
|
"FILE [ARGS...]",
|
||||||
|
"Load an additional file.");
|
||||||
|
|
||||||
|
cmd_relocate = grub_register_command ("relocate", grub_cmd_relocate,
|
||||||
|
"[on|off|force]",
|
||||||
|
"Set relocate feature.");
|
||||||
|
|
||||||
|
cmd_fpswa = grub_register_command ("fpswa", grub_cmd_fpswa,
|
||||||
|
"", "Display FPSWA version.");
|
||||||
|
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(linux)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd_linux);
|
||||||
|
grub_unregister_command (cmd_initrd);
|
||||||
|
grub_unregister_command (cmd_payload);
|
||||||
|
grub_unregister_command (cmd_relocate);
|
||||||
|
grub_unregister_command (cmd_fpswa);
|
||||||
|
}
|
|
@ -27,19 +27,22 @@
|
||||||
#include <grub/mips/relocator.h>
|
#include <grub/mips/relocator.h>
|
||||||
#include <grub/memory.h>
|
#include <grub/memory.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/lib/cmdline.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
/* For frequencies. */
|
/* For frequencies. */
|
||||||
#include <grub/pci.h>
|
|
||||||
#include <grub/machine/time.h>
|
#include <grub/machine/time.h>
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
/* This can be detected on runtime from PMON, but:
|
#include <grub/pci.h>
|
||||||
a) it wouldn't work when GRUB is the firmware
|
#include <grub/machine/kernel.h>
|
||||||
and
|
|
||||||
b) for now we only support Yeeloong anyway. */
|
const char loongson_machtypes[][60] =
|
||||||
#define LOONGSON_MACHTYPE "machtype=lemote-yeeloong-2f-8.9inches"
|
{
|
||||||
|
[GRUB_ARCH_MACHINE_YEELOONG] = "machtype=lemote-yeeloong-2f-8.9inches",
|
||||||
|
[GRUB_ARCH_MACHINE_FULOONG] = "machtype=lemote-fuloong-2f-unknown"
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
|
@ -51,9 +54,16 @@ static grub_size_t linux_size;
|
||||||
static struct grub_relocator *relocator;
|
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;
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
static char *params;
|
||||||
|
#else
|
||||||
static int linux_argc;
|
static int linux_argc;
|
||||||
static grub_off_t argv_off, envp_off;
|
static grub_off_t argv_off;
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
static grub_off_t envp_off;
|
||||||
|
#endif
|
||||||
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
|
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
|
||||||
|
#endif
|
||||||
static int initrd_loaded = 0;
|
static int initrd_loaded = 0;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -61,11 +71,43 @@ grub_linux_boot (void)
|
||||||
{
|
{
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
|
|
||||||
|
grub_memset (&state, 0, sizeof (state));
|
||||||
|
|
||||||
/* Boot the kernel. */
|
/* Boot the kernel. */
|
||||||
state.gpr[1] = entry_addr;
|
state.gpr[1] = entry_addr;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
grub_uint32_t *memsize;
|
||||||
|
grub_uint32_t *magic;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
((16 << 20) - 264),
|
||||||
|
grub_strlen (params) + 1 + 8);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
memsize = get_virtual_current_address (ch);
|
||||||
|
magic = memsize + 1;
|
||||||
|
*memsize = grub_mmap_get_lower ();
|
||||||
|
*magic = 0x12345678;
|
||||||
|
str = (char *) (magic + 1);
|
||||||
|
grub_strcpy (str, params);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
state.gpr[4] = linux_argc;
|
state.gpr[4] = linux_argc;
|
||||||
state.gpr[5] = target_addr + argv_off;
|
state.gpr[5] = target_addr + argv_off;
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
state.gpr[6] = target_addr + envp_off;
|
state.gpr[6] = target_addr + envp_off;
|
||||||
|
#else
|
||||||
|
state.gpr[6] = 0;
|
||||||
|
#endif
|
||||||
|
state.gpr[7] = 0;
|
||||||
|
#endif
|
||||||
state.jumpreg = 1;
|
state.jumpreg = 1;
|
||||||
grub_relocator32_boot (relocator, state);
|
grub_relocator32_boot (relocator, state);
|
||||||
|
|
||||||
|
@ -78,6 +120,11 @@ grub_linux_unload (void)
|
||||||
grub_relocator_unload (relocator);
|
grub_relocator_unload (relocator);
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
grub_free (params);
|
||||||
|
params = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -197,12 +244,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
grub_elf_t elf = 0;
|
grub_elf_t elf = 0;
|
||||||
int i;
|
|
||||||
int size;
|
int size;
|
||||||
void *extra = NULL;
|
void *extra = NULL;
|
||||||
grub_uint32_t *linux_argv, *linux_envp;
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
char *linux_args, *linux_envs;
|
int i;
|
||||||
|
grub_uint32_t *linux_argv;
|
||||||
|
char *linux_args;
|
||||||
|
#endif
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
char *linux_envs;
|
||||||
|
grub_uint32_t *linux_envp;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
|
||||||
|
@ -222,9 +275,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_loader_unset ();
|
grub_loader_unset ();
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
size = 0;
|
||||||
|
#else
|
||||||
/* For arguments. */
|
/* For arguments. */
|
||||||
linux_argc = argc;
|
linux_argc = argc;
|
||||||
#ifdef LOONGSON_MACHTYPE
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
linux_argc++;
|
linux_argc++;
|
||||||
#endif
|
#endif
|
||||||
/* Main arguments. */
|
/* Main arguments. */
|
||||||
|
@ -239,8 +295,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
/* Normal arguments. */
|
/* Normal arguments. */
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
|
size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
|
||||||
#ifdef LOONGSON_MACHTYPE
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
size += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4);
|
size += ALIGN_UP (sizeof (loongson_machtypes[0]), 4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* rd arguments. */
|
/* rd arguments. */
|
||||||
|
@ -254,6 +310,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
|
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
|
||||||
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
|
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
|
||||||
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
|
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (grub_elf_is_elf32 (elf))
|
if (grub_elf_is_elf32 (elf))
|
||||||
err = grub_linux_load32 (elf, &extra, size);
|
err = grub_linux_load32 (elf, &extra, size);
|
||||||
|
@ -268,6 +325,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
/* Create kernel command line. */
|
||||||
|
size = grub_loader_cmdline_size(argc, argv);
|
||||||
|
params = grub_malloc (size + sizeof (LINUX_IMAGE));
|
||||||
|
if (! params)
|
||||||
|
{
|
||||||
|
grub_linux_unload ();
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||||
|
grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1,
|
||||||
|
size);
|
||||||
|
#else
|
||||||
linux_argv = extra;
|
linux_argv = extra;
|
||||||
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
|
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
|
||||||
extra = linux_argv + (linux_argc + 1 + 2);
|
extra = linux_argv + (linux_argc + 1 + 2);
|
||||||
|
@ -279,14 +350,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
linux_argv++;
|
linux_argv++;
|
||||||
linux_args += ALIGN_UP (sizeof ("a0"), 4);
|
linux_args += ALIGN_UP (sizeof ("a0"), 4);
|
||||||
|
|
||||||
#ifdef LOONGSON_MACHTYPE
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
/* In Loongson platform, it is the responsibility of the bootloader/firmware
|
{
|
||||||
to supply the OS kernel with machine type information. */
|
unsigned mtype = grub_arch_machine;
|
||||||
grub_memcpy (linux_args, LOONGSON_MACHTYPE, sizeof (LOONGSON_MACHTYPE));
|
if (mtype >= ARRAY_SIZE (loongson_machtypes))
|
||||||
*linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
|
mtype = 0;
|
||||||
+ target_addr;
|
/* In Loongson platform, it is the responsibility of the bootloader/firmware
|
||||||
linux_argv++;
|
to supply the OS kernel with machine type information. */
|
||||||
linux_args += ALIGN_UP (sizeof (LOONGSON_MACHTYPE), 4);
|
grub_memcpy (linux_args, loongson_machtypes[mtype],
|
||||||
|
sizeof (loongson_machtypes[mtype]));
|
||||||
|
*linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
|
||||||
|
+ target_addr;
|
||||||
|
linux_argv++;
|
||||||
|
linux_args += ALIGN_UP (sizeof (loongson_machtypes[mtype]), 4);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
|
@ -313,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
extra = linux_args;
|
extra = linux_args;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
linux_envp = extra;
|
linux_envp = extra;
|
||||||
envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
|
envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
|
||||||
linux_envs = (char *) (linux_envp + 5);
|
linux_envs = (char *) (linux_envp + 5);
|
||||||
|
@ -340,8 +418,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
+ target_addr;
|
+ target_addr;
|
||||||
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
|
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
|
||||||
|
|
||||||
|
|
||||||
linux_envp[4] = 0;
|
linux_envp[4] = 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
|
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
|
||||||
initrd_loaded = 0;
|
initrd_loaded = 0;
|
||||||
|
@ -404,6 +483,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
tmp = grub_xasprintf ("%s rd_start=0x%" PRIxGRUB_ADDR
|
||||||
|
" rd_size=0x%" PRIxGRUB_ADDR, params,
|
||||||
|
initrd_dest, size);
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_free (params);
|
||||||
|
params = tmp;
|
||||||
|
}
|
||||||
|
#else
|
||||||
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) initrd_dest);
|
(unsigned long long) initrd_dest);
|
||||||
|
@ -417,6 +511,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
||||||
= target_addr + rd_size_arg_off;
|
= target_addr + rd_size_arg_off;
|
||||||
linux_argc++;
|
linux_argc++;
|
||||||
|
#endif
|
||||||
|
|
||||||
initrd_loaded = 1;
|
initrd_loaded = 1;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <grub/memory.h>
|
#include <grub/memory.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/cpu/memory.h>
|
||||||
|
|
||||||
grub_uint64_t
|
grub_uint64_t
|
||||||
grub_mmap_get_lower (void)
|
grub_mmap_get_lower (void)
|
4
grub-core/modinfo.sh.in
Normal file
4
grub-core/modinfo.sh.in
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
grub_modinfo_target_cpu=@target_cpu@
|
||||||
|
grub_modinfo_platform=@platform@
|
|
@ -473,9 +473,14 @@ grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
static grub_command_t cmd_clear;
|
static grub_command_t cmd_clear;
|
||||||
|
|
||||||
static void (*grub_xputs_saved) (const char *str);
|
static void (*grub_xputs_saved) (const char *str);
|
||||||
|
static const char *features[] = {
|
||||||
|
"feature_chainloader_bpb", "feature_ntldr"
|
||||||
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(normal)
|
GRUB_MOD_INIT(normal)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
/* Previously many modules depended on gzio. Be nice to user and load it. */
|
/* Previously many modules depended on gzio. Be nice to user and load it. */
|
||||||
grub_dl_load ("gzio");
|
grub_dl_load ("gzio");
|
||||||
|
|
||||||
|
@ -517,6 +522,12 @@ GRUB_MOD_INIT(normal)
|
||||||
/* Set default color names. */
|
/* Set default color names. */
|
||||||
grub_env_set ("color_normal", "white/black");
|
grub_env_set ("color_normal", "white/black");
|
||||||
grub_env_set ("color_highlight", "black/white");
|
grub_env_set ("color_highlight", "black/white");
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (features); i++)
|
||||||
|
{
|
||||||
|
grub_env_set (features[i], "y");
|
||||||
|
grub_env_export (features[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(normal)
|
GRUB_MOD_FINI(normal)
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct grub_amiga_rdsk
|
||||||
grub_uint32_t partitionlst;
|
grub_uint32_t partitionlst;
|
||||||
grub_uint32_t fslst;
|
grub_uint32_t fslst;
|
||||||
|
|
||||||
/* The other information is not important for us. */
|
grub_uint32_t unused[128 - 9];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_amiga_partition
|
struct grub_amiga_partition
|
||||||
|
@ -67,12 +67,24 @@ struct grub_amiga_partition
|
||||||
grub_uint32_t highcyl;
|
grub_uint32_t highcyl;
|
||||||
|
|
||||||
grub_uint32_t firstcyl;
|
grub_uint32_t firstcyl;
|
||||||
|
grub_uint32_t unused[128 - 44];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
static struct grub_partition_map grub_amiga_partition_map;
|
static struct grub_partition_map grub_amiga_partition_map;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static grub_uint32_t
|
||||||
|
amiga_partition_map_checksum (void *buf, grub_size_t sz)
|
||||||
|
{
|
||||||
|
grub_uint32_t *ptr = buf;
|
||||||
|
grub_uint32_t r = 0;
|
||||||
|
sz /= sizeof (grub_uint32_t);
|
||||||
|
for (; sz; sz--, ptr++)
|
||||||
|
r += grub_be_to_cpu32 (*ptr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
amiga_partition_map_iterate (grub_disk_t disk,
|
amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
int (*hook) (grub_disk_t disk,
|
int (*hook) (grub_disk_t disk,
|
||||||
|
@ -92,7 +104,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC,
|
if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC,
|
||||||
sizeof (rdsk.magic)) == 0)
|
sizeof (rdsk.magic)) == 0
|
||||||
|
&& amiga_partition_map_checksum (&rdsk, sizeof (rdsk)) == 0)
|
||||||
{
|
{
|
||||||
/* Found the first PART block. */
|
/* Found the first PART block. */
|
||||||
next = grub_be_to_cpu32 (rdsk.partitionlst);
|
next = grub_be_to_cpu32 (rdsk.partitionlst);
|
||||||
|
@ -114,7 +127,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC,
|
if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC,
|
||||||
sizeof (apart.magic)) != 0)
|
sizeof (apart.magic)) != 0
|
||||||
|
|| amiga_partition_map_checksum (&apart, sizeof (apart)) != 0)
|
||||||
return grub_error (GRUB_ERR_BAD_PART_TABLE,
|
return grub_error (GRUB_ERR_BAD_PART_TABLE,
|
||||||
"invalid Amiga partition map");
|
"invalid Amiga partition map");
|
||||||
/* Calculate the first block and the size of the partition. */
|
/* Calculate the first block and the size of the partition. */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue