diff --git a/ChangeLog b/ChangeLog index 5dbdd6a9c..e594931e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,871 @@ +2009-12-23 Felix Zielcke + + * commands/i386/pc/drivemap.c: Remove all trailing whitespace. + * commands/lspci.c: Likewise. + * commands/probe.c: Likewise. + * commands/xnu_uuid.c: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * fs/i386/pc/pxe.c: Likewise. + * gettext/gettext.c: Likewise. + * include/grub/efi/graphics_output.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * kern/env.c: Likewise. + * kern/i386/qemu/startup.S: Likewise. + * lib/i386/pc/biosnum.c: Likewise. + * lib/i386/relocator.c: Likewise. + * lib/i386/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/xnu.c: Likewise. + * normal/main.c: Likewise. + * normal/menu_text.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-mkconfig_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + * video/efi_gop.c: Likewise. + +2009-12-23 Vladimir Serbinenko + + * video/efi_gop.c (grub_video_gop_get_bitmask): Fix off-by-one in mask + size counting. + +2009-12-22 Felix Zielcke + + * util/grub-mkrescue.in (pkglib_DATA): Set to @pkglib_DATA@. + * genmk.rb (class SCRIPT): Modify the target file instead of source. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (grub_cmd_write): Support for mask parameter. + (GRUB_MOD_INIT(memrw)): Update help line. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (cmd_read_byte, cmd_read_word, cmd_read_dword): + Use grub_extcmd_t. All users updated. + (options): New variable. + (grub_cmd_read): Restructure for readability. Support "-v" option. + (grub_cmd_write): Restructure for readability. + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Prepend #{src} path with $(srcdir). + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Use sed to substitute @pkglib_DATA@ + with the actual contents of the correspondending make variable. + * util/grub-mkrescue.in (pkglib_DATA): New variable. + (process_input_dir): Copy all $pkglib_DATA files instead of explicitly + specifying `*.lst' and `efiemu??.o' + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Add round brackets + after function name. + Noticed by Rene Engelhard . + +2009-12-22 Vladimir Serbinenko + + * commands/lspci.c (grub_pci_classes): Add "USB Controller". + (options): New variable. + (iospace): Likewise. + (grub_lspci_iter): List IO spaces if "-i" was given. + (grub_cmd_lspci): Parse options. + (GRUB_MOD_INIT(lspci)): Use extcmd. + (GRUB_MOD_FINI(lspci)): Likewise. + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Remove non POSIX compliant + `function' keyword. + Patch by Tony Mancill . + +2009-12-22 Vladimir Serbinenko + + * bus/usb/uhci.c (grub_uhci_transfer): Set a limit transaction time. + (grub_uhci_portstatus): Likewise. + (grub_uhci_portstatus): Add necessary delay. + * bus/usb/usbhub.c (grub_usb_hub_add_dev): Fix loop-break condition. + +2009-12-21 Carles Pina i Estany + + * commands/acpi.c (options): Fix capitalizations and/or full stops. + (GRUB_MOD_INIT): Likewise. + * commands/boot.c (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (grub_cmd_cmp): Improve the help message. + * commands/echo.c (options): Fix capitalizations and/or full stops. + * commands/efi/loadbios.c (enable_rom_area): Likewise. + (enable_rom_area): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/gptsync.c (GRUB_MOD_INIT): Likewise. + * commands/halt.c (GRUB_MOD_INIT): Improve the help message. + * commands/handler.c (GRUB_MOD_INIT): Likewise. + * commands/hdparm.c (options): Fix capitalizations and/or full stops. + * commands/hexdump.c (options): Likewise. + * commands/i386/cpuid.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/drivemap.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/halt (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/pxecmd.c (options): Likewise. + * commands/i386/pc/vbetest.c (GRUB_MOD_INIT): Likewise. + * commands/ieee1275/suspend.c (GRUB_MOD_INIT): Likewise. + * commands/keystatus.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/loadenv.c (options): Likewise. + * commands/ls.c (options): Likewise. + * commands/lspci.c (GRUB_MOD_INIT): Likewise. + * commands/memrw.c (GRUB_MOD_INIT): Likewise. + * commands/minicmd.c (GRUB_MOD_INIT): Likewise. + * commands/parttool.c (helpmsg): Likewise. + * commands/probe.c (options): Likewise. + * commands/read.c (GRUB_MOD_INIT): Likewise. + * commands/reboot.c (GRUB_MOD_INIT): Likewise. + * commands/search.c (options): Likewise. + * commands/sleep.c (options): Likewise. + * commands/test.c (GRUB_MOD_INIT): Likewise. + * commands/true.c (GRUB_MOD_INIT): Likewise. + * commands/usbtest.c (GRUB_MOD_INIT): Likewise. + * commands/videotest.c (GRUB_MOD_INIT): Likewise. + * lib/arg.c (help_options): Likewise. + * Makefile.in ($(srcdir)/po/$(PACKAGE).pot): Pass -ctranslate to + `$(XGETTEXT)'. + * po/POTFILES: Add `commands/loadenv.c'. + +2009-12-21 Felix Zielcke + + * util/grub-mkrescue.in (process_input_dir): Copy `*.lst' files + instead of specifying them explicit. + +2009-12-21 Robert Millan + + * NEWS: Add grub-probe support for GNU/Hurd. + +2009-12-21 Robert Millan + + * NEWS: gettext was added after 1.97. + +2009-12-21 Robert Millan + + * util/mkisofs/msdos_partition.h: New file (based on + include/grub/msdos_partition.h). + * util/mkisofs/mkisofs.c (use_protective_msdos_label): New variable. + (OPTION_PROTECTIVE_MSDOS_LABEL): New macro. + (ld_options, main): Recognize --protective-msdos-label. + * util/mkisofs/mkisofs.h (use_protective_msdos_label): New declaration. + * util/mkisofs/write.c: Include `"msdos_partition.h"'. + (padblock_write): If `use_protective_msdos_label' is set, patch a + protective DOS-style label in the output image. + + * util/grub-mkrescue.in: Use --protective-msdos-label. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Do not zero-pad image for BIOS-based disk + boot. + +2009-12-21 Robert Millan + + * util/mkisofs/mkisofs.c (use_embedded_boot, boot_image_embed): New + variables. + (ld_options, main): Recognize `--embedded-boot'. + * util/mkisofs/mkisofs.h (use_embedded_boot, boot_image_embed): New + declarations. + * util/mkisofs/write.c (PADBLOCK_SIZE): New variable. + (padblock_size): Use `PADBLOCK_SIZE' instead of hardcoding 16. + (padblock_write): Likewise. Rewrite to support embedded boot image. + + * util/grub-mkrescue.in: When building i386-pc images, embed core.img + for BIOS-based disk boot instead of only ElTorito. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `configfile' and `sh' from i386-pc + build (not needed for bootstrap). + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `memdisk', `tar' and `search' modules + from i386-pc build (not needed for bootstrap). + Rewrite a pair of strings. + +2009-12-21 Robert Millan + + * normal/main.c (grub_normal_reader_init): Set left margin back to 3. + +2009-12-21 Vladimir Serbinenko + + * video/i386/pc/vbe.c (grub_video_vbe_fini): Set 'last_set_mode'. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_context_open): Mark exported variable for + reexport. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_export): Create nonexistent variables before + exporting. + +2009-12-20 Carles Pina i Estany + + * include/grub/auth.h: Include `'. + (GRUB_GET_PASSWORD): Gettextizze string. + * include/grub/normal.h (STANDARD_MARGIN): New macro, moved from + menu_text.c. + (grub_utf8_to_ucs4_alloc): Fix indentation. + (grub_print_ucs4): Likewise. + (grub_getstringwidth): Likewise. + (print_message_indented): New declaration. + * normal/auth.c: Include `'. + (grub_auth_check_authentication): Gettexttize string. + * normal/cmdline.c: Include `'. + (grub_cmdline_get): Gettextizze. + * normal/color.c: Include `'. + (grub_parse_color_name_pair): Gettexttize strings. + * normal/main.c (grub_normal_reader_init): Cleanup gettexttized + string (use `print_message_indented'). + * normal/menu_text.c (STANDARD_MARGIN): Moved from here to + `include/grub/normal.h'. + (print_message_indented): Renamed to ... + (grub_print_message_indented): ... this. Remove `static' qualifer (now + used in normal/main.c). + (print_message): Use `grub_print_message_indented' instead of + `print_message_indented'. + (print_timeout): Likewise. + * normal/misc.c: Include `' and `'. + (grub_normal_print_device_info): Gettexttize strings. + * po/POTFILES: Add `auth.c', `color.c' and `misc.c'. + +2009-12-20 Vladimir Serbinenko + + * kern/parser.c (grub_parser_split_cmdline): Fix incorrect counting + of arguments. Return number of tokens and not arguments. All users + updated. + +2009-12-20 Vladimir Serbinenko + + * util/i386/pc/grub-setup.c (setup): Don't install on non-GPT, + non-MSDOS paritions. + +2009-12-19 Vladimir Serbinenko + + * include/grub/types.h (UNUSED): Removed since it conflicts with + NetBSD headers. All users changed to direct __attribute__ ((unused)). + Reported by GrĂ©goire Sutre. + +2009-12-19 Carles Pina i Estany + + * include/grub/normal.h (grub_utf8_to_ucs4): New declaration. + (grub_print_ucs4_alloc): Likewise. + (grub_getstringwidth): Likewise. + * normal/main.c (grub_normal_init_page): Gettextize version string. + * normal/menu_text.c (grub_utf8_to_ucs4_alloc): New definition. + (getstringwidth): Renamed to ... + (grub_getstringwidth): ... this. Remove `static' qualifier (now used + in normal/main.c). Use `grub_utf8_to_ucs4_alloc'. + (grub_print_ucs4): Remove `static' qualifer (now used in + normal/main.c). + * po/POTFILES: Add normal/main.c. + +2009-12-19 Carles Pina i Estany + + * normal/menu_text.c (STANDARD_MARGIN): New macro. + (print_message_indented): Add `margin_left' and `margin_right' + parameters. + (print_message): Update `print_message_indented' calls. Adds '\n' to the + strings. + (print_timeout): Use `print_message_indented' to print the message. + Deletes `second_stage' parameter. + (run_menu): Update `print_timeout' calls. + +2009-12-18 Vladimir Serbinenko + + Fix console palette on OpenFirmware. + + * term/ieee1275/ofconsole.c (MAX): Removed. + (colors): Redone based on VGA palette. + (grub_ofconsole_setcolor): Discard brightness bit since only 8 + colors are supported. + (grub_ofconsole_init_output): Use ARRAY_SIZE instead of hardcoded size. + +2009-12-18 Vladimir Serbinenko + + Fix potential EfiEmu double prepare. + + * efiemu/main.c (prepared): New variable + (grub_efiemu_unload): Set prepare to '0'. + (grub_efiemu_prepare): Return if already prepared. Set prepared. + + set_virtual_address_map support. + + * include/grub/efi/efi.h (grub_efi_set_virtual_address_map): New + prototype. + * include/grub/efiemu/efiemu.h (grub_efiemu_write_sym_markers): New + prototype. + (grub_efiemu_crc32): Likewise. + (grub_efiemu_crc64): Likewise. + (grub_efiemu_set_virtual_address_map): Likewise. + * include/grub/autoefi.h (grub_autoefi_exit_boot_services): + New definition. + (grub_autoefi_set_virtual_address_map): Likewise. + * kern/efi/efi.c (grub_efi_set_virtual_address_map): New function. + * loader/i386/xnu.c (grub_xnu_boot): Call set_virtual_address_map. + Restructure flow to accomodate it. + * efiemu/prepare.c (grub_efiemu_prepare): Support set_virtual_address_map. + (grub_efiemu_crc): Recompute CRC32. + * efiemu/runtime/efiemu.c (ptv_relocated): Renamed to ... + (efiemu_ptv_relocated): ... this. Made global. All users updated. + * efiemu/symbols.c (relocated_handle): New variable. + (grub_efiemu_free_syms): Free relocated_handle. + (grub_efiemu_alloc_syms): Allocate relocated_handle. + (grub_efiemu_write_sym_markers): New function. + (grub_efiemu_set_virtual_address_map): Likewise. + + Newer XNU parameters. + + * include/grub/i386/xnu.h (GRUB_XNU_BOOTARGS_VERMINOR): Change to 5. + * include/grub/xnu.h (grub_xnu_extheader): Add nameaddr and namesize. + (grub_xnu_fill_devicetree): New prototype. + (grub_xnu_heap_real_start): New variable. + * loader/xnu.c (get_name_ptr): New function. + (grub_xnu_load_driver): Fill namelen and name. + + 64-bit xnu support. + + * conf/i386-efi.rmk (xnu_mod_SOURCES): Add 'loader/macho32.c' + and 'loader/macho64.c'. + * conf/i386-pc.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/i386/macho.h (grub_macho_thread64): New structure. + * include/grub/xnu.h (grub_xnu_is_64bit): New variable. + * include/grub/macho.h (grub_macho_segment64): New structure. + * include/grub/machoload.h (grub_macho32_size): Renamed from ... + (grub_macho_size32): ... to this. + (grub_macho32_get_entry_point): Renamed from ... + (grub_macho_get_entry_point32): ... to this. + (grub_macho_contains_macho64): New prototype. + (grub_macho_size64): Likewise. + (grub_macho_get_entry_point64): Likewise. + (grub_macho32_load): Renamed from ... + (grub_macho_load32): ... to this. + (grub_macho32_filesize): Renamed from ... + (grub_macho_filesize32): ... to this. + (grub_macho32_readfile): Renamed from ... + (grub_macho_readfile32): ... to this. + (grub_macho_filesize64): New prototype. + (grub_macho_readfile64): Likewise. + (grub_macho_parse32): Likewise. + (grub_macho_parse64): Likewise. + * loader/macho.c: Split into ... + * loader/machoXX.c: ... and this. Replace 32 with XX. + * loader/macho32.c: New file. + * loader/macho64.c: Likewise. + * loader/xnu.c (grub_xnu_is_64bit): New variable. + (grub_cmd_xnu_kernel): Make 32-bit only. + (grub_cmd_xnu_kernel64): New function. + (grub_xnu_load_driver): Support Mach-O 64. + (grub_cmd_xnu_mkext): Likewise. + * util/grub.d/30_os-prober.in (osx_entry): New function. + Generate entries for 64-bit boot too. + + Eliminate ad-hoc tree format in XNU and EfiEmu. + + * efiemu/main.c (grub_efiemu_prepare): Update comment. + * efiemu/pnvram.c: Rewritten to use environment variables. + All users updated. + + Inline utf16_to_utf8. + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add charset.mod + (charset_mod_SOURCES): New variable. + (charset_mod_CFLAGS): Likewise. + (charset_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + + Support for device properties. + + * include/grub/i386/xnu.h (grub_xnu_devprop_header): New structure. + (grub_xnu_devprop_device_header): Likewise. + (grub_xnu_devprop_device_descriptor): Likewise. + (grub_xnu_devprop_add_device): New prototype. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_remove_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (grub_cpu_xnu_init): Likewise. + (grub_cpu_xnu_fini): Likewise. + (grub_cpu_xnu_unload): Likewise. + * loader/i386/xnu.c (grub_xnu_devprop_device_descriptor): New structure. + (property_descriptor): Likewise. + (devices): New variable. + (grub_xnu_devprop_remove_property): New function. + (grub_xnu_devprop_add_device): Likewise. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_add_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (hextoval): Likewise. + (grub_cpu_xnu_fill_devprop): Likewise. + (grub_cmd_devprop_load): Likewise. + (grub_xnu_boot): Call grub_cpu_xnu_fill_devprop, + grub_xnu_fill_devicetree, grub_xnu_fill_devicetree + (cmd_devprop_load): New variable. + (grub_cpu_xnu_init): New function. + (grub_cpu_xnu_fini): Likewise. + * loader/i386/xnu.c (grub_xnu_unload): Call grub_cpu_xnu_unload. + * loader/xnu.c (grub_xnu_parse_devtree): Remove. + (grub_cmd_xnu_devtree): Likewise. + (hextoval): New function. + (unescape): Likewise. + (grub_xnu_fill_devicetree): Likewise. + + * util/grub.d/30_os-prober.in: Load devprop.bin. Don't load devtree.txt. + * util/i386/efi/grub-dumpdevtree: Generate devprop.bin. + +2009-12-18 Vladimir Serbinenko + + Workaround for broken ATI VBE. + + * video/i386/pc/vbe.c (last_set_mode): New variable. + (grub_vbe_set_video_mode): Set 'last_set_mode'. + (grub_vbe_get_video_mode): Use 'last_set_mode' if get_mode fails. + (grub_video_vbe_setup): Don't check for reserved flag. + +2009-12-17 Felix Zielcke + + * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in + the `find' command. + +2009-12-16 Vladimir Serbinenko + + UUID support for HFS. + + * fs/hfs.c (grub_hfs_uuid): New function. + (grub_hfs_fs): New value .uuid. + * include/grub/hfs.h (grub_hfs_sblock): New field 'num_serial'. + +2009-12-14 Felix Zielcke + + Fix a segfault with parsing unknown long options. + + * util/grub-mkrelpath.c (options): Zero terminate it. + +2009-12-13 Carles Pina i Estany + + * include/grub/misc.h (grub_puts): New declaration. + (grub_puts_): Likewise. + * kern/mis.c (grub_puts): New definition. + (grub_puts_): Likewise. + +2009-12-13 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + +2009-12-13 Robert Millan + + * loader/i386/multiboot_elfxx.c + (CONCAT(grub_multiboot_load_elf, XX)): Fix `grub_multiboot_payload_eip' + initialization. + +2009-12-13 Vladimir Serbinenko + + Relocator framework + + * loader/i386/xnu_helper.S: Removed. All users updated. + * conf/i386.rmk (pkglib_MODULES): Add relocator.mod. + (relocator_mod_SOURCES): New variable. + (relocator_mod_CFLAGS): Likewise. + (relocator_mod_LDFLAGS): Likewise. + (relocator_mod_ASFLAGS): Likewise. + * conf/x86_64.rmk: Likewise. + * include/grub/i386/multiboot.h (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_forward_relocator_end): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_backward_relocator_end): Likewise. + (grub_multiboot_payload_eip): New variable. + (grub_multiboot_payload_orig): Likewise. + * include/grub/i386/pc/memory.h: Include grub/i386/memory.h. + (GRUB_MEMORY_MACHINE_CR0_PE_ON): Move from here ... + * include/grub/i386/memory.h + (GRUB_MEMORY_CPU_CR0_PE_ON): ... to here + (GRUB_MEMORY_CPU_CR4_PAE_ON): New definition. + (GRUB_MEMORY_CPU_CR0_PAGING_ON): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR_ON): Likewise. + * include/grub/i386/relocator.h: New file. + * include/grub/x86_64/relocator.h: Likewise. + * include/grub/i386/xnu.h: Include grub/cpu/relocator.h. + (XNU_RELOCATOR): New macro. + (grub_xnu_launcher_start): Remove. + (grub_xnu_launcher_end): Likewise. + * include/grub/xnu.h (grub_xnu_boot_resume): New prototype. + (grub_xnu_heap_real_start): Remove. + (grub_xnu_heap_start): Change to void *. All users updated. + * kern/i386/realmode.S (real_to_prot): Use GRUB_MEMORY_CPU_CR0_PE_ON. + * lib/i386/relocator.c: New file. + * lib/i386/relocator_asm.S: Likewise. + * lib/i386/relocator_backward.S: Likewise. + * lib/mips/relocator.c: Likewise. + * lib/mips/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/multiboot.c: Include grub/i386/relocator.h. + (entry): Removed. + (playground): Likewise. + (grub_multiboot_payload_orig): New variable. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_eip): Likewise. + (grub_multiboot_payload_esp): Likewise. + (grub_multiboot_boot): Use grub_relocator32_boot. + (grub_multiboot_unload): Free relocators. + (grub_multiboot): Setup stack. Use relocators. + * loader/i386/multiboot_elfxx.c: Include grub/i386/relocator.h. + (grub_multiboot_load_elfXX): Use relocators. + * loader/i386/multiboot_helper.S (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_real_boot): Likewise. + * loader/i386/xnu.c (grub_xnu_heap_will_be_at): New variable. + (grub_xnu_entry_point): Likewise. + (grub_xnu_arg1): Likewise. + (grub_xnu_stack): Likewise. + (grub_xnu_launch): Removed. + (grub_xnu_boot_resume): New function. + (grub_xnu_boot): Use relocators. + * loader/i386/xnu_helper.S: Removed. + * loader/xnu.c (grub_xnu_heap_start): New variable. + (grub_xnu_heap_size): Likewise. + (grub_xnu_heap_malloc): Use relocators. + * loader/xnu_resume.c (grub_xnu_resume): Use relocators. + +2009-12-13 Vladimir Serbinenko + + * kern/i386/pc/startup.S (multiboot_entry): Setup stack before calling + anything. + +2009-12-13 Carles Pina i Estany + + * script/execute.c (grub_script_execute_cmdline): Set grub_errno to + GRUB_ERR_NONE before calling grub_env_set. + +2009-12-12 Robert Millan + + * gendistlist.sh (EXTRA_DISTFILES): Add `genvideolist.sh'. + * genmk.rb (video): New variable. + (CLEANFILES, VIDEOFILES): Add #{video}. + (#{video}): New target rule. + * genvideolist.sh: New file. + * Makefile.in (pkglib_DATA): Add video.lst. + (video.lst): New target rule. + * util/grub-mkconfig.in: Initialize ${GRUB_VIDEO_BACKEND} using + `video.lst'. + * util/grub.d/30_os-prober.in: Replace `vbe' with + ${GRUB_VIDEO_BACKEND}. + +2009-12-11 Robert Millan + + * THANKS: Add David Miller. + +2009-12-11 Vladimir Serbinenko + + libpciaccess support. + + * Makefile.in (LIBPCIACCESS): New variable. + (enable_grub_emu_pci): Likewise. + * conf/any-emu.rmk (grub_emu_SOURCES) [enable_grub_emu_pci]: Add + util/pci.c and commands/lspci.c. + (grub_emu_LDFLAGS) [enable_grub_emu_pci]: Add $(LIBPCIACCESS). + * configure.ac (grub-emu-pci): New option. + * include/grub/i386/pci.h (grub_pci_device_map_range): New function. + (grub_pci_device_unmap_range): Likewise. + * include/grub/pci.h [GRUB_UTIL]: Include grub/pciutils.h. + (grub_pci_device) [!GRUB_UTIL]: New structure. All users updated. + (grub_pci_address_t) [!GRUB_UTIL]: New type. + (grub_pci_device_t) [!GRUB_UTIL]: Likewise. + (grub_pci_get_bus) [!GRUB_UTIL]: New function. + (grub_pci_get_device) [!GRUB_UTIL]: Likewise. + (grub_pci_get_function) [!GRUB_UTIL]: Likewise. + * include/grub/pciutils.h: New file. + * util/pci.c: Likewise. + +2009-12-11 Felix Zielcke + + * util/misc.c: Don't include twice. + +2009-12-10 Felix Zielcke + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Show the disk + name in an error message. + (grub_biosdisk_rw): Likewise. + +2009-12-10 Vladimir Serbinenko + + Eliminate NTFS 4Gib barrier. + + * fs/ntfs.c (read_attr): Use grub_disk_addr_t and grub_size_t. + (read_run_data): Likewise. + (grub_ntfs_read_run_list): Likewise. + (grub_ntfs_read_block): Likewise. + (grub_ntfs_iterate_dir): Likewise. + (read_mft): Likewise. + (read_data): Likewise. + Use COM_LOG_LEN. + * fs/ntfscomp.c (read_block): Cast ctx->target_vcn & 0xF to unsigned + to avoid 64-bit division + * include/grub/ntfs.h (COM_LOG_LEN): New definition. + (grub_ntfs_rlst): Use grub_disk_addr_t. + +2009-12-10 Vladimir Serbinenko + + Eliminate grub-fstest 4Gib barrier. + + * util/grub-fstest.c (skip, leng): Use grub_disk_addr_t. + (read_file): Fix error reporting. + +2009-12-10 Vladimir Serbinenko + + Eliminate hexdump 4Gib barrier. + + * commands/hexdump.c (grub_cmd_hexdump): Use grub_disk_addr_t. + * lib/arg.c (grub_arg_parse): Use grub_strtoull. + +2009-12-10 Vladimir Serbinenko + + * kern/device.c (grub_device_iterate): Ignore errors during first scan. + Fixes amarsh bug. + +2009-12-09 Bruce Dubbs + + Remove miscellaneous files in distclean target. + + * Makefile.in: Remove docs/{grub.info,version.texi,stamp-vti} + +2009-12-09 Colin Watson + + * util/grub-mkconfig_lib.in: Don't set grub_probe or grub_mkrelpath + if they're already set. This resolves the conflict between my + grub-install change on 2009-10-06 and Felix' change on 2009-11-11, + fixing the --grub-probe option again. + * util/sparc64/ieee1275/grub-install.in: Revert the last piece of my + change on 2009-10-06, so that we now once again source + `${libdir}/grub/grub-mkconfig_lib' after options have been parsed. + +2009-12-08 Robert Millan + + * conf/common.rmk [sparc64-ieee1275] (grub_mkdevicemap_SOURCES): Use + `util/ieee1275/ofpath.c' and `util/ieee1275/devicemap.c' instead of + `util/devicemap.c'. + +2009-12-08 Carles Pina i Estany + + * include/grub/misc.h (grub_printf_): New declaration. + * kern/misc.c (grub_printf_): New definition. + * normal/main.c (grub_normal_reader_init): Use `grub_printf_' and `N_' + instead of `grub_printf' and `_'. + * normal/menu_entry.c (store_completion): Likewise. + (run): Likewise. + (grub_menu_entry_run): Likewise. + * normal/menu_text.c (grub_wait_after_message): Likewise. + (notify_booting): Likewise. + (notify_fallback): Likewise. + (notify_execution_failure): Likewise. + +2009-12-07 Colin Watson + + * configure.ac: Check for vasprintf. + * util/misc.c (asprintf): Move allocation from here ... + (vasprintf): ... to here. New function. + (xasprintf): New function. + * include/grub/util/misc.h (vasprintf, xasprintf): Add + prototypes. + * util/getroot.c (grub_util_get_grub_dev): Use xasprintf. + * util/grub-mkfont.c (write_font): Likewise. + * util/grub-probe.c (probe): Likewise. + * util/hostdisk.c (make_device_name): Likewise. + +2009-12-06 David S. Miller + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Recognize + anything even prefixed with 'cdrom' as a cdrom. + +2009-12-06 Felix Zielcke + + * util/misc.c (make_system_path_relative_to_its_root): Correctly cope with + mount points. + +2009-12-05 Carles Pina i Estany + + * gettext/gettext.c: Include `'. Define grub_gettext_msg, + grub_gettext_msg_list. + (grub_gettext_gettranslation_from_position): Return const char * + and not char *. + (grub_gettext_translate): Add the translated strings into a list, + returns from the list if existing there. + (grub_gettext_init_ext): Add \n at the end of grub_dprintf string. + (grub_gettext_delete_list): Delete the list. + (grub_gettext_env_write_lang): Call grub_gettext_delete_list when + lang environment variable is changed. + (GRUB_MOD_FINI): Call grub_gettext_delete_list. + +2009-12-05 Vladimir Serbinenko + + Rename kernel.mod to kernel.img. + + * conf/i386-efi.rmk (pkglib_MODULES): Change kernel.mod to kernel.img. + (kernel_mod_EXPORTS): Rename to ... + (kernel_img_EXPORTS): ... this. + (kernel_mod_SOURCES): Rename to ... + (kernel_img_SOURCES): ... this. + (kernel_mod_HEADERS): Rename to ... + (kernel_img_HEADERS): ... this. All users updated. + (kernel_mod_CFLAGS): Rename to ... + (kernel_img_CFLAGS): ... this. + (kernel_mod_ASFLAGS): Rename to ... + (kernel_img_ASFLAGS): ... this. + (kernel_mod_LDFLAGS): Rename to ... + (kernel_img_LDFLAGS): ... this. + * conf/x86_64-efi.rmk: Likewise. + * util/i386/efi/grub-mkimage.c (read_kernel_module): Rename to ... + (read_kernel_image): ... this. All users updated. + (read_kernel_image): Read "kernel.img" instead of "kernel.mod". + +2009-12-05 Carles Pina i Estany + + * normal/menu_text.c (grub_color_menu_high): Gettexttize string. + (print_spaces): New function. + (grub_print_ucs4): New function. + (getstringwidth): New function. + (print_message_indented): New function. + (print_message): Gettexttize strings using print_message_indented. + (run_menu): Replaces grub_printf by print_spaces and dynamic terminal + width. + (get_entry_number): Gettextize and uses dynamic terminal width. + (notify_booting, notify_fallback, notify_execution_failure): + Gettextize. + * normal/menu_entry.c (store_completion): Cleanup the gettextized + string. + (run): Likewise. + (grub_menu_entry_run): Likewise. + * PO/POTFILES: Add normal/menu_entry.c. + +2009-12-05 Vladimir Serbinenko + + * configure.ac (TARGET_ASFLAGS): Add "-D". + +2009-12-05 Carles Pina i Estany + + * util/grub-install.in: Install gettext .mo files. + * util/grub-mkrescue.in (process_input_dir): Copy gettext .mo files. + +2009-12-05 Carles Pina i Estany + + * gettext/gettext.c (grub_gettext_init_ext): Replace grub_printf with + grub_dprintf. + +2009-12-05 Robert Millan + + * kern/ieee1275/openfw.c (grub_reboot): Disable for i386. The + non-firmware-dependant one in realmode.S takes precedence. + +2009-12-04 Robert Millan + + * commands/halt.c: Replace misc arch-specific headers with + `'. + * commands/reboot.c: Likewise. + * commands/i386/pc/halt.c: Replace `' with + `'. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Remove `cpu/reboot.h'. + (halt_mod_SOURCES): Move `kern/i386/halt.c' from here ... + (kernel_img_SOURCES): ... to here. + + * include/grub/efi/efi.h (grub_reboot, grub_halt): Remove prototypes. + * include/grub/i386/pc/init.h: Likewise. + * include/grub/powerpc/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + + * include/grub/misc.h (grub_reboot, grub_halt): New prototypes. + + * include/grub/i386/halt.h: Remove. + * include/grub/i386/reboot.h: Likewise. + + * kern/i386/halt.c: Remove `'. + +2009-12-03 David S. Miller + + * conf/sparc64-ieee1275.rmk (grub_mkimage_SOURCES, + grub_setup_SOURCES, grub_ofpathname_SOURCES): Add gnulib/progname.c + * util/sparc64/ieee1275/grub-mkimage.c: Include and + "progname.h" + * util/sparc64/ieee1275/grub-ofpathname.c: Likewise. + * util/sparc64/ieee1275/grub-setup.c: Likewise. + (usage): Add missing comma in printf. + +2009-12-02 Robert Millan + + Use the same reboot approach on i386 coreboot and qemu as we do on + BIOS. + + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add `cpu/reboot.h'. + (reboot_mod_SOURCES): Remove `kern/i386/reboot.c'. + * kern/i386/reboot.c: Remove. + * include/grub/i386/reboot.h (grub_reboot): Export function. + * kern/i386/pc/startup.S (grub_reboot): Move from here ... + * kern/i386/realmode.S (grub_reboot): ... to here. Jump to + 0xf000:0xfff0 instead of 0xffff:0x0000. + [!GRUB_MACHINE_PCBIOS] (prot_to_real): Do not restore interrupts. + * kern/i386/qemu/startup.S: Include `"../realmode.S"'. + +2009-11-30 Robert Millan + + Fix $srcdir != $objdir build. + + * Makefile.in (po/%.po): Rewrite as ... + ($(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po)): ... this. + 2009-11-29 Samuel Thibault Fix GNU/Hurd grub-install crash. @@ -187,7 +1055,7 @@ * include/grub/i18n.h: ... to here * include/grub/i18n.h: ... to here. * kern/misc.c: Include - (grub_gettext_dummy): Move above user. + (grub_gettext_dummy): Move above user. 2009-11-24 Felix Zielcke diff --git a/Makefile.in b/Makefile.in index 3d9f5db3b..7f87cf40b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -110,12 +110,14 @@ AWK = @AWK@ LIBCURSES = @LIBCURSES@ LIBUSB = @LIBUSB@ LIBSDL = @LIBSDL@ +LIBPCIACCESS = @LIBPCIACCESS@ YACC = @YACC@ FONT_SOURCE = @FONT_SOURCE@ # Options. enable_grub_emu_usb = @enable_grub_emu_usb@ enable_grub_emu_sdl = @enable_grub_emu_sdl@ +enable_grub_emu_pci = @enable_grub_emu_pci@ enable_grub_fstest = @enable_grub_fstest@ enable_grub_pe2elf = @enable_grub_pe2elf@ enable_grub_mkfont = @enable_grub_mkfont@ @@ -141,7 +143,9 @@ CLEANFILES = MOSTLYCLEANFILES = DISTCLEANFILES = config.status config.cache config.log config.h \ Makefile stamp-h include/grub/cpu include/grub/machine \ - gensymlist.sh genkernsyms.sh build_env.mk + gensymlist.sh genkernsyms.sh build_env.mk \ + docs/grub.info docs/version.texi docs/stamp-vti + MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES)) \ $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS) @@ -167,7 +171,7 @@ endif ### General targets. CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo -pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst +pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk cat $(DEFSYMFILES) /dev/null \ | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \ @@ -188,6 +192,9 @@ handler.lst: $(HANDLERFILES) parttool.lst: $(PARTTOOLFILES) cat $^ /dev/null | sort | uniq > $@ +video.lst: $(VIDEOFILES) + cat $^ /dev/null | sort | uniq > $@ + ifneq (true, $(MAKEINFO)) info_INFOS += docs/grub.info endif @@ -479,10 +486,10 @@ genkernsyms.sh: genkernsyms.sh.in config.status $(SHELL) ./config.status $(srcdir)/po/$(PACKAGE).pot: po/POTFILES po/POTFILES-shell - cd $(srcdir) && $(XGETTEXT) --from-code=utf-8 -o $@ -f $< --keyword=_ --keyword=N_ - cd $(srcdir) && $(XGETTEXT) --from-code=utf-8 -o $@ -f po/POTFILES-shell -j --language=Shell + cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o $@ -f $< --keyword=_ --keyword=N_ + cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o $@ -f po/POTFILES-shell -j --language=Shell -po/%.po: po/$(PACKAGE).pot +$(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): po/$(PACKAGE).pot $(MSGMERGE) -U $@ $^ po/%.mo: po/%.po diff --git a/NEWS b/NEWS index bf7492c6d..cc725fd3b 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,11 @@ -New in 1.97 - : +New in 1.98: + +* Add grub-probe support for GNU/Hurd. * Add support for gettext. +New in 1.97: + * Add support for loading XNU (MacOS X kernel). * ACPI override support. diff --git a/THANKS b/THANKS index 5ce190944..82b4bc838 100644 --- a/THANKS +++ b/THANKS @@ -8,6 +8,7 @@ generally assist in the GRUB 2 maintainership process: Andrey Shuvikov Bibo Mao +David Miller Guillem Jover Harley D. Eades III Hitoshi Ozeki diff --git a/bus/pci.c b/bus/pci.c index 2c29c03ab..fe4cad181 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -21,41 +21,40 @@ #include grub_pci_address_t -grub_pci_make_address (int bus, int device, int function, int reg) +grub_pci_make_address (grub_pci_device_t dev, int reg) { - return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (reg << 2); + return (1 << 31) | (dev.bus << 16) | (dev.device << 11) + | (dev.function << 8) | (reg << 2); } void grub_pci_iterate (grub_pci_iteratefunc_t hook) { - int bus; - int dev; - int func; + grub_pci_device_t dev; grub_pci_address_t addr; grub_pci_id_t id; grub_uint32_t hdr; - for (bus = 0; bus < 256; bus++) + for (dev.bus = 0; dev.bus < 256; dev.bus++) { - for (dev = 0; dev < 32; dev++) + for (dev.device = 0; dev.device < 32; dev.device++) { - for (func = 0; func < 8; func++) + for (dev.function = 0; dev.function < 8; dev.function++) { - addr = grub_pci_make_address (bus, dev, func, 0); + addr = grub_pci_make_address (dev, 0); id = grub_pci_read (addr); /* Check if there is a device present. */ if (id >> 16 == 0xFFFF) continue; - if (hook (bus, dev, func, id)) + if (hook (dev, id)) return; /* Probe only func = 0 if the device if not multifunction */ - if (func == 0) + if (dev.function == 0) { - addr = grub_pci_make_address (bus, dev, func, 3); + addr = grub_pci_make_address (dev, 3); hdr = grub_pci_read (addr); if (!(hdr & 0x800000)) break; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 32fb7cf91..5fe9c9507 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -113,7 +113,7 @@ grub_ohci_writereg32 (struct grub_ohci *o, /* Iterate over all PCI devices. Determine if a device is an OHCI controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR -grub_ohci_pci_iter (int bus, int device, int func, +grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__((unused))) { grub_uint32_t class_code; @@ -126,7 +126,7 @@ grub_ohci_pci_iter (int bus, int device, int func, grub_uint32_t revision; grub_uint32_t frame_interval; - addr = grub_pci_make_address (bus, device, func, 2); + addr = grub_pci_make_address (dev, 2); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -138,7 +138,7 @@ grub_ohci_pci_iter (int bus, int device, int func, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (bus, device, func, 4); + addr = grub_pci_make_address (dev, 4); base = grub_pci_read (addr); #if 0 diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 88ff5b3d8..e83fccc1d 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -138,7 +137,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, /* Iterate over all PCI devices. Determine if a device is an UHCI controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR -grub_uhci_pci_iter (int bus, int device, int func, +grub_uhci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__((unused))) { grub_uint32_t class_code; @@ -151,7 +150,7 @@ grub_uhci_pci_iter (int bus, int device, int func, struct grub_uhci *u; int i; - addr = grub_pci_make_address (bus, device, func, 2); + addr = grub_pci_make_address (dev, 2); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -163,7 +162,7 @@ grub_uhci_pci_iter (int bus, int device, int func, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (bus, device, func, 8); + addr = grub_pci_make_address (dev, 8); base = grub_pci_read (addr); /* Stop if there is no IO space base address defined. */ if (! (base & 1)) @@ -435,6 +434,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, grub_uhci_td_t td_prev = NULL; grub_usb_err_t err = GRUB_USB_ERR_NONE; int i; + grub_uint64_t endtime; /* Allocate a queue head for the transfer queue. */ qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL); @@ -483,6 +483,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Wait until either the transaction completed or an error occurred. */ + endtime = grub_get_time_ms () + 1000; for (;;) { grub_uhci_td_t errtd; @@ -534,6 +535,13 @@ grub_uhci_transfer (grub_usb_controller_t dev, updated. */ grub_dprintf ("uhci", "transaction fallthrough\n"); } + if (grub_get_time_ms () > endtime) + { + err = GRUB_USB_ERR_STALL; + grub_dprintf ("uhci", "transaction timed out\n"); + goto fail; + } + grub_cpu_idle (); } grub_dprintf ("uhci", "transaction complete\n"); @@ -573,6 +581,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, struct grub_uhci *u = (struct grub_uhci *) dev->data; int reg; unsigned int status; + grub_uint64_t endtime; grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); @@ -595,6 +604,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, status = grub_uhci_readreg16 (u, reg); grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); grub_dprintf ("uhci", "reset completed\n"); + grub_millisleep (10); /* Enable the port. */ grub_uhci_writereg16 (u, reg, enable << 2); @@ -602,7 +612,10 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_dprintf ("uhci", "waiting for the port to be enabled\n"); - while (! (grub_uhci_readreg16 (u, reg) & (1 << 2))); + endtime = grub_get_time_ms () + 1000; + while (! (grub_uhci_readreg16 (u, reg) & (1 << 2))) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "UHCI Timed out"); status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", ">3detect=0x%02x\n", status); diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 310b8cc6a..8289185da 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -155,42 +155,6 @@ grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr) return NULL; } -grub_usb_err_t -grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, - char **string) -{ - struct grub_usb_desc_str descstr; - struct grub_usb_desc_str *descstrp; - grub_usb_err_t err; - - /* Only get the length. */ - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, 1, (char *) &descstr); - if (err) - return err; - - descstrp = grub_malloc (descstr.length); - if (! descstrp) - return GRUB_USB_ERR_INTERNAL; - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, descstr.length, (char *) descstrp); - - *string = grub_malloc (descstr.length / 2); - if (! *string) - { - grub_free (descstrp); - return GRUB_USB_ERR_INTERNAL; - } - - grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); - (*string)[descstr.length / 2 - 1] = '\0'; - grub_free (descstrp); - - return GRUB_USB_ERR_NONE; -} - grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev) { diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 6881ce000..a22ca60c2 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -48,7 +48,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed) if (! grub_usb_devs[i]) break; } - if (grub_usb_devs[i]) + if (i == 128) { grub_error (GRUB_ERR_IO, "Can't assign address to USB device"); return NULL; @@ -60,6 +60,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed) | GRUB_USB_REQTYPE_TARGET_DEV), GRUB_USB_REQ_SET_ADDRESS, i, 0, 0, NULL); + dev->addr = i; dev->initialized = 1; grub_usb_devs[i] = dev; diff --git a/commands/acpi.c b/commands/acpi.c index 1a7bf8018..c9acf5abe 100644 --- a/commands/acpi.c +++ b/commands/acpi.c @@ -36,23 +36,23 @@ static const struct grub_arg_option options[] = { {"exclude", 'x', 0, - "Don't load host tables specified by comma-separated list", + "Don't load host tables specified by comma-separated list.", 0, ARG_TYPE_STRING}, {"load-only", 'n', 0, - "Load only tables specified by comma-separated list", 0, ARG_TYPE_STRING}, - {"v1", '1', 0, "Expose v1 tables", 0, ARG_TYPE_NONE}, - {"v2", '2', 0, "Expose v2 and v3 tables", 0, ARG_TYPE_NONE}, - {"oemid", 'o', 0, "Set OEMID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING}, + "Load only tables specified by comma-separated list.", 0, ARG_TYPE_STRING}, + {"v1", '1', 0, "Expose v1 tables.", 0, ARG_TYPE_NONE}, + {"v2", '2', 0, "Expose v2 and v3 tables.", 0, ARG_TYPE_NONE}, + {"oemid", 'o', 0, "Set OEMID of RSDP, XSDT and RSDT.", 0, ARG_TYPE_STRING}, {"oemtable", 't', 0, - "Set OEMTABLE ID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING}, + "Set OEMTABLE ID of RSDP, XSDT and RSDT.", 0, ARG_TYPE_STRING}, {"oemtablerev", 'r', 0, - "Set OEMTABLE revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT}, + "Set OEMTABLE revision of RSDP, XSDT and RSDT.", 0, ARG_TYPE_INT}, {"oemtablecreator", 'c', 0, - "Set creator field of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING}, + "Set creator field of RSDP, XSDT and RSDT.", 0, ARG_TYPE_STRING}, {"oemtablecreatorrev", 'd', 0, - "Set creator revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT}, - {"no-ebda", 'e', 0, "Don't update EBDA. May fix failures or hangs on some" - " BIOSes but makes it ineffective with OS not receiving RSDP from GRUB", + "Set creator revision of RSDP, XSDT and RSDT.", 0, ARG_TYPE_INT}, + {"no-ebda", 'e', 0, "Don't update EBDA. May fix failures or hangs on some." + " BIOSes but makes it ineffective with OS not receiving RSDP from GRUB.", 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -763,7 +763,7 @@ GRUB_MOD_INIT(acpi) "--load-only=table1,table2] filename1 " " [filename2] [...]", "Load host acpi tables and tables " - "specified by arguments", + "specified by arguments.", options); } diff --git a/commands/boot.c b/commands/boot.c index e77b5ceb8..fe0453b8a 100644 --- a/commands/boot.c +++ b/commands/boot.c @@ -186,7 +186,7 @@ GRUB_MOD_INIT(boot) { cmd_boot = grub_register_command ("boot", grub_cmd_boot, - 0, "boot an operating system"); + 0, "Boot an operating system."); } GRUB_MOD_FINI(boot) diff --git a/commands/cmp.c b/commands/cmp.c index 1258b1d63..8a4b4158b 100644 --- a/commands/cmp.c +++ b/commands/cmp.c @@ -40,7 +40,7 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); - grub_printf ("Compare `%s' and `%s':\n", args[0], + grub_printf ("Compare file `%s' with `%s':\n", args[0], args[1]); file1 = grub_gzfile_open (args[0], 1); @@ -49,7 +49,7 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), goto cleanup; if (grub_file_size (file1) != grub_file_size (file2)) - grub_printf ("Differ in size: %llu [%s], %llu [%s]\n", + grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n", (unsigned long long) grub_file_size (file1), args[0], (unsigned long long) grub_file_size (file2), args[1]); else @@ -76,7 +76,7 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), { if (buf1[i] != buf2[i]) { - grub_printf ("Differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n", + grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n", (unsigned long long) (i + pos), buf1[i], args[0], buf2[i], args[1]); goto cleanup; diff --git a/commands/echo.c b/commands/echo.c index 69aa3be3c..c9daf62f1 100644 --- a/commands/echo.c +++ b/commands/echo.c @@ -23,8 +23,8 @@ static const struct grub_arg_option options[] = { - {0, 'n', 0, "do not output the trailing newline", 0, 0}, - {0, 'e', 0, "enable interpretation of backslash escapes", 0, 0}, + {0, 'n', 0, "Do not output the trailing newline.", 0, 0}, + {0, 'e', 0, "Enable interpretation of backslash escapes.", 0, 0}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c index f97d83787..685662237 100644 --- a/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -38,11 +38,11 @@ static struct grub_video_patch }; static int NESTED_FUNC_ATTR -scan_card (int bus, int dev, int func, grub_pci_id_t pciid) +scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index 9967bb122..d7ad42690 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -41,15 +41,16 @@ enable_rom_area (void) { grub_pci_address_t addr; grub_uint32_t *rom_ptr; + grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; rom_ptr = (grub_uint32_t *) VBIOS_ADDR; if (*rom_ptr != BLANK_MEM) { - grub_printf ("ROM image present.\n"); + grub_printf ("ROM image is present.\n"); return 0; } - addr = grub_pci_make_address (0, 0, 0, 36); + addr = grub_pci_make_address (dev, 36); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); grub_pci_write_byte (addr++, 0x33); @@ -62,7 +63,7 @@ enable_rom_area (void) *rom_ptr = 0; if (*rom_ptr != 0) { - grub_printf ("Can\'t enable rom area.\n"); + grub_printf ("Can\'t enable ROM area.\n"); return 0; } @@ -73,8 +74,9 @@ static void lock_rom_area (void) { grub_pci_address_t addr; + grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - addr = grub_pci_make_address (0, 0, 0, 36); + addr = grub_pci_make_address (dev, 36); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); grub_pci_write_byte (addr++, 0x11); @@ -199,7 +201,7 @@ static grub_command_t cmd_fakebios, cmd_loadbios; GRUB_MOD_INIT(loadbios) { cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios, - 0, "fake bios."); + 0, "Fake bios."); cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, "loadbios BIOS_DUMP [INT10_DUMP]", diff --git a/commands/gptsync.c b/commands/gptsync.c index a603746a2..8315faa53 100644 --- a/commands/gptsync.c +++ b/commands/gptsync.c @@ -246,7 +246,7 @@ GRUB_MOD_INIT(gptsync) "of hybrid mbr. Up to 3 partitions are " "allowed. TYPE is an MBR type. " "+ means that partition is active. " - "Only one partition can be active"); + "Only one partition can be active."); } GRUB_MOD_FINI(gptsync) diff --git a/commands/halt.c b/commands/halt.c index 9a42938b4..09431d3cb 100644 --- a/commands/halt.c +++ b/commands/halt.c @@ -19,15 +19,7 @@ #include #include - -#if defined(GRUB_MACHINE_IEEE1275) -#include -#elif defined(GRUB_MACHINE_EFI) -#include -#else -/* Platforms shipping standalone halt, such as coreboot. */ -#include -#endif +#include static grub_err_t grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)), @@ -43,8 +35,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(halt) { cmd = grub_register_command ("halt", grub_cmd_halt, - 0, "halts the computer. This command does not" - " work on all firmware."); + 0, "Halts the computer. This command does not" + " work on all firmware implementations."); } GRUB_MOD_FINI(halt) diff --git a/commands/handler.c b/commands/handler.c index 2070c391c..d65a703e4 100644 --- a/commands/handler.c +++ b/commands/handler.c @@ -96,15 +96,15 @@ GRUB_MOD_INIT(handler) cmd_handler = grub_register_command ("handler", grub_cmd_handler, "handler [class [handler]]", - "List or select a handler"); + "List or select a handler."); cmd_terminal_input = grub_register_command ("terminal_input", grub_cmd_handler, "terminal_input [handler]", - "List or select a handler"); + "List or select an input terminal."); cmd_terminal_output = grub_register_command ("terminal_output", grub_cmd_handler, "terminal_output [handler]", - "List or select a handler"); + "List or select an output terminal."); } GRUB_MOD_FINI(handler) diff --git a/commands/hdparm.c b/commands/hdparm.c index 389954c45..458a447c7 100644 --- a/commands/hdparm.c +++ b/commands/hdparm.c @@ -26,27 +26,27 @@ #include static const struct grub_arg_option options[] = { - {"apm", 'B', 0, "set Advanced Power Management\n" - "(1=low, ..., 254=high, 255=off)", + {"apm", 'B', 0, "Set Advanced Power Management\n" + "(1=low, ..., 254=high, 255=off).", 0, ARG_TYPE_INT}, - {"power", 'C', 0, "check power mode", 0, ARG_TYPE_NONE}, - {"security-freeze", 'F', 0, "freeze ATA security settings until reset", + {"power", 'C', 0, "Check power mode.", 0, ARG_TYPE_NONE}, + {"security-freeze", 'F', 0, "Freeze ATA security settings until reset.", 0, ARG_TYPE_NONE}, - {"health", 'H', 0, "check SMART health status", 0, ARG_TYPE_NONE}, - {"aam", 'M', 0, "set Automatic Acoustic Management\n" - "(0=off, 128=quiet, ..., 254=fast)", + {"health", 'H', 0, "Check SMART health status.", 0, ARG_TYPE_NONE}, + {"aam", 'M', 0, "Set Automatic Acoustic Management\n" + "(0=off, 128=quiet, ..., 254=fast).", 0, ARG_TYPE_INT}, - {"standby-timeout", 'S', 0, "set standby timeout\n" - "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)", + {"standby-timeout", 'S', 0, "Set standby timeout\n" + "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...).", 0, ARG_TYPE_INT}, - {"standby", 'y', 0, "set drive to standby mode", 0, ARG_TYPE_NONE}, - {"sleep", 'Y', 0, "set drive to sleep mode", 0, ARG_TYPE_NONE}, - {"identify", 'i', 0, "print drive identity and settings", + {"standby", 'y', 0, "Set drive to standby mode.", 0, ARG_TYPE_NONE}, + {"sleep", 'Y', 0, "Set drive to sleep mode.", 0, ARG_TYPE_NONE}, + {"identify", 'i', 0, "Print drive identity and settings.", 0, ARG_TYPE_NONE}, - {"dumpid", 'I', 0, "dump contents of ATA IDENTIFY sector", + {"dumpid", 'I', 0, "Dump contents of ATA IDENTIFY sector.", 0, ARG_TYPE_NONE}, - {"smart", -1, 0, "disable/enable SMART (0/1)", 0, ARG_TYPE_INT}, - {"quiet", 'q', 0, "do not print messages", 0, ARG_TYPE_NONE}, + {"smart", -1, 0, "Disable/enable SMART (0/1).", 0, ARG_TYPE_INT}, + {"quiet", 'q', 0, "Do not print messages.", 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/hexdump.c b/commands/hexdump.c index f59ba363c..727deecbf 100644 --- a/commands/hexdump.c +++ b/commands/hexdump.c @@ -26,9 +26,9 @@ #include static const struct grub_arg_option options[] = { - {"skip", 's', 0, "skip offset bytes from the beginning of file.", 0, + {"skip", 's', 0, "Skip offset bytes from the beginning of file.", 0, ARG_TYPE_INT}, - {"length", 'n', 0, "read only length bytes", 0, ARG_TYPE_INT}, + {"length", 'n', 0, "Read only LENGTH bytes.", 0, ARG_TYPE_INT}, {0, 0, 0, 0, 0, 0} }; @@ -38,18 +38,18 @@ grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args) struct grub_arg_list *state = cmd->state; char buf[GRUB_DISK_SECTOR_SIZE * 4]; grub_ssize_t size, length; - grub_addr_t skip; + grub_disk_addr_t skip; int namelen; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); namelen = grub_strlen (args[0]); - skip = (state[0].set) ? grub_strtoul (state[0].arg, 0, 0) : 0; + skip = (state[0].set) ? grub_strtoull (state[0].arg, 0, 0) : 0; length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256; if (!grub_strcmp (args[0], "(mem)")) - hexdump (skip, (char *) skip, length); + hexdump (skip, (char *) (grub_addr_t) skip, length); else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')')) { grub_disk_t disk; diff --git a/commands/i386/cpuid.c b/commands/i386/cpuid.c index a8bbfe69b..8097e7372 100644 --- a/commands/i386/cpuid.c +++ b/commands/i386/cpuid.c @@ -33,7 +33,7 @@ static const struct grub_arg_option options[] = { - {"long-mode", 'l', 0, "check for long mode flag (default)", 0, 0}, + {"long-mode", 'l', 0, "Check for long mode flag (default).", 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -88,7 +88,7 @@ done: #endif cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH, - "cpuid [-l]", "Check for CPU features", options); + "cpuid [-l]", "Check for CPU features.", options); } GRUB_MOD_FINI(cpuid) diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c index 52424c3d1..7d1420eea 100644 --- a/commands/i386/pc/drivemap.c +++ b/commands/i386/pc/drivemap.c @@ -33,9 +33,9 @@ static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13); /* Remember to update enum opt_idxs accordingly. */ static const struct grub_arg_option options[] = { - {"list", 'l', 0, "show the current mappings", 0, 0}, - {"reset", 'r', 0, "reset all mappings to the default values", 0, 0}, - {"swap", 's', 0, "perform both direct and reverse mappings", 0, 0}, + {"list", 'l', 0, "Show the current mappings.", 0, 0}, + {"reset", 'r', 0, "Reset all mappings to the default values.", 0, 0}, + {"swap", 's', 0, "Perform both direct and reverse mappings.", 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -370,7 +370,7 @@ grub_get_root_biosnumber_drivemap (void) return grub_strtoul (biosnum, 0, 0); dev = grub_device_open (0); - if (dev && dev->disk && dev->disk->dev + if (dev && dev->disk && dev->disk->dev && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) { drivemap_node_t *curnode = map_head; @@ -404,7 +404,7 @@ GRUB_MOD_INIT (drivemap) GRUB_COMMAND_FLAG_BOTH, "drivemap" " -l | -r | [-s] grubdev osdisk", - "Manage the BIOS drive mappings", + "Manage the BIOS drive mappings.", options); drivemap_hook = grub_loader_register_preboot_hook (&install_int13_handler, diff --git a/commands/i386/pc/halt.c b/commands/i386/pc/halt.c index add8631a8..befd58804 100644 --- a/commands/i386/pc/halt.c +++ b/commands/i386/pc/halt.c @@ -18,12 +18,12 @@ */ #include -#include +#include #include static const struct grub_arg_option options[] = { - {"no-apm", 'n', 0, "do not use APM to halt the computer", 0, 0}, + {"no-apm", 'n', 0, "Do not use APM to halt the computer.", 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -47,7 +47,7 @@ GRUB_MOD_INIT(halt) { cmd = grub_register_extcmd ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH, "halt [-n]", - "Halt the system, if possible using APM", + "Halt the system, if possible using APM.", options); } diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 23150ea1f..6020b825a 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -207,7 +207,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(play) { cmd = grub_register_command ("play", grub_cmd_play, - "play FILE", "Play a tune"); + "play FILE", "Play a tune."); } GRUB_MOD_FINI(play) diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c index df538704c..1817898c9 100644 --- a/commands/i386/pc/pxecmd.c +++ b/commands/i386/pc/pxecmd.c @@ -25,9 +25,9 @@ static const struct grub_arg_option options[] = { - {"info", 'i', 0, "show PXE information.", 0, 0}, - {"bsize", 'b', 0, "set PXE block size", 0, ARG_TYPE_INT}, - {"unload", 'u', 0, "unload PXE stack.", 0, 0}, + {"info", 'i', 0, "Show PXE information.", 0, 0}, + {"bsize", 'b', 0, "Set PXE block size.", 0, ARG_TYPE_INT}, + {"unload", 'u', 0, "Unload PXE stack.", 0, 0}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c index 314320d07..4050c869e 100644 --- a/commands/i386/pc/vbetest.c +++ b/commands/i386/pc/vbetest.c @@ -168,7 +168,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(vbetest) { cmd = grub_register_command ("vbetest", grub_cmd_vbetest, - 0, "Test VESA BIOS Extension 2.0+ support"); + 0, "Test VESA BIOS Extension 2.0+ support."); } GRUB_MOD_FINI(vbetest) diff --git a/commands/ieee1275/suspend.c b/commands/ieee1275/suspend.c index 028dd3cd8..fd538f8ea 100644 --- a/commands/ieee1275/suspend.c +++ b/commands/ieee1275/suspend.c @@ -39,7 +39,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(ieee1275_suspend) { cmd = grub_register_command ("suspend", grub_cmd_suspend, - 0, "Return to Open Firmware prompt"); + 0, "Return to Open Firmware prompt."); } GRUB_MOD_FINI(ieee1275_suspend) diff --git a/commands/keystatus.c b/commands/keystatus.c index 28ceb2d0b..0a4667645 100644 --- a/commands/keystatus.c +++ b/commands/keystatus.c @@ -24,9 +24,9 @@ static const struct grub_arg_option options[] = { - {"shift", 's', 0, "check Shift key", 0, 0}, - {"ctrl", 'c', 0, "check Control key", 0, 0}, - {"alt", 'a', 0, "check Alt key", 0, 0}, + {"shift", 's', 0, "Check Shift key.", 0, 0}, + {"ctrl", 'c', 0, "Check Control key.", 0, 0}, + {"alt", 'a', 0, "Check Alt key.", 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -71,7 +71,7 @@ GRUB_MOD_INIT(keystatus) cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus, GRUB_COMMAND_FLAG_BOTH, "keystatus [--shift] [--ctrl] [--alt]", - "Check key modifier status", + "Check key modifier status.", options); } diff --git a/commands/loadenv.c b/commands/loadenv.c index c60eb835c..c10dd0e27 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -29,7 +29,7 @@ static const struct grub_arg_option options[] = { - {"file", 'f', 0, "specify filename", 0, ARG_TYPE_PATHNAME}, + {"file", 'f', 0, "Specify filename.", 0, ARG_TYPE_PATHNAME}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/ls.c b/commands/ls.c index 15b4c6bab..6eaa1d59e 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -33,9 +33,9 @@ static const struct grub_arg_option options[] = { - {"long", 'l', 0, "show a long list with more detailed information", 0, 0}, - {"human-readable", 'h', 0, "print sizes in a human readable format", 0, 0}, - {"all", 'a', 0, "list all files", 0, 0}, + {"long", 'l', 0, "Show a long list with more detailed information.", 0, 0}, + {"human-readable", 'h', 0, "Print sizes in a human readable format.", 0, 0}, + {"all", 'a', 0, "List all files.", 0, 0}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/lspci.c b/commands/lspci.c index 5b3360a37..fbade98c1 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include struct grub_pci_classname { @@ -84,6 +84,7 @@ static const struct grub_pci_classname grub_pci_classes[] = { 11, 0x30, "MIPS Processor" }, { 11, 0x40, "Co-Processor" }, { 11, 0x80, "Unknown Processor" }, + { 12, 3, "USB Controller" }, { 12, 0x80, "Serial Bus Controller" }, { 13, 0x80, "Wireless Controller" }, { 14, 0, "I2O" }, @@ -114,16 +115,26 @@ grub_pci_get_class (int class, int subclass) return 0; } +static const struct grub_arg_option options[] = + { + {"iospace", 'i', 0, "show I/O spaces", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static int iospace; + static int NESTED_FUNC_ATTR -grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid) +grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_uint32_t class; const char *sclass; grub_pci_address_t addr; + int reg; - grub_printf ("%02x:%02x.%x %04x:%04x", bus, dev, func, pciid & 0xFFFF, - pciid >> 16); - addr = grub_pci_make_address (bus, dev, func, 2); + grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev), + grub_pci_get_device (dev), grub_pci_get_function (dev), + pciid & 0xFFFF, pciid >> 16); + addr = grub_pci_make_address (dev, 2); class = grub_pci_read (addr); /* Lookup the class name, if there isn't a specific one, @@ -142,27 +153,75 @@ grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid) grub_printf ("\n"); + if (iospace) + { + reg = 4; + while (reg < 10) + { + grub_uint64_t space; + addr = grub_pci_make_address (dev, reg); + space = grub_pci_read (addr); + + reg++; + + if (space == 0) + continue; + + switch (space & GRUB_PCI_ADDR_SPACE_MASK) + { + case GRUB_PCI_ADDR_SPACE_IO: + grub_printf ("\tIO space %d at 0x%llx\n", (reg - 1) - 4, + (unsigned long long) + (space & GRUB_PCI_ADDR_IO_MASK)); + break; + case GRUB_PCI_ADDR_SPACE_MEMORY: + if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK) + == GRUB_PCI_ADDR_MEM_TYPE_64) + { + addr = grub_pci_make_address (dev, reg); + space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; + reg++; + grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", + (reg - 2) - 4, (unsigned long long) + (space & GRUB_PCI_ADDR_MEM_MASK), + space & GRUB_PCI_ADDR_MEM_PREFETCH + ? "prefetchable" : "non-prefetchable"); + + } + else + grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", + (reg - 1) - 4, (unsigned long long) + (space & GRUB_PCI_ADDR_MEM_MASK), + space & GRUB_PCI_ADDR_MEM_PREFETCH + ? "prefetchable" : "non-prefetchable"); + break; + } + } + } + + return 0; } static grub_err_t -grub_cmd_lspci (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_lspci (grub_extcmd_t cmd, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { + iospace = cmd->state[0].set; grub_pci_iterate (grub_lspci_iter); return GRUB_ERR_NONE; } -static grub_command_t cmd; +static grub_extcmd_t cmd; -GRUB_MOD_INIT(pci) +GRUB_MOD_INIT(lspci) { - cmd = grub_register_command ("lspci", grub_cmd_lspci, - 0, "List PCI devices"); + cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH, + "lspci [-i]", "List PCI devices.", options); } -GRUB_MOD_FINI(pci) +GRUB_MOD_FINI(lspci) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/commands/memrw.c b/commands/memrw.c index adffb7fc8..eada1d232 100644 --- a/commands/memrw.c +++ b/commands/memrw.c @@ -19,29 +19,53 @@ #include #include -#include +#include +#include -static grub_command_t cmd_read_byte, cmd_read_word, cmd_read_dword; +static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; +static const struct grub_arg_option options[] = + { + {0, 'v', 0, "Save read value into variable VARNAME.", + "VARNAME", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + + static grub_err_t -grub_cmd_read (grub_command_t cmd, int argc, char **argv) +grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) { grub_target_addr_t addr; - grub_uint32_t value; + grub_uint32_t value = 0; + char buf[sizeof ("XXXXXXXX")]; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); - if (cmd->name[5] == 'd') - value = *((grub_uint32_t *) addr); - else if (cmd->name[5] == 'w') - value = *((grub_uint16_t *) addr); - else - value = *((grub_uint8_t *) addr); + switch (cmd->cmd->name[sizeof ("read_") - 1]) + { + case 'd': + value = *((volatile grub_uint32_t *) addr); + break; - grub_printf ("0x%x\n", value); + case 'w': + value = *((volatile grub_uint16_t *) addr); + break; + + case 'b': + value = *((volatile grub_uint8_t *) addr); + break; + } + + if (cmd->state[0].set) + { + grub_sprintf (buf, "%x", value); + grub_env_set (cmd->state[0].arg, buf); + } + else + grub_printf ("0x%x\n", value); return 0; } @@ -51,18 +75,42 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) { grub_target_addr_t addr; grub_uint32_t value; + grub_uint32_t mask = 0xffffffff; - if (argc != 2) + if (argc != 2 && argc != 3) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); value = grub_strtoul (argv[1], 0, 0); - if (cmd->name[6] == 'd') - *((grub_uint32_t *) addr) = value; - else if (cmd->name[6] == 'w') - *((grub_uint16_t *) addr) = (grub_uint16_t) value; - else - *((grub_uint8_t *) addr) = (grub_uint8_t) value; + if (argc == 3) + mask = grub_strtoul (argv[2], 0, 0); + value &= mask; + switch (cmd->name[sizeof ("write_") - 1]) + { + case 'd': + if (mask != 0xffffffff) + *((volatile grub_uint32_t *) addr) + = (*((volatile grub_uint32_t *) addr) & ~mask) | value; + else + *((volatile grub_uint32_t *) addr) = value; + break; + + case 'w': + if ((mask & 0xffff) != 0xffff) + *((volatile grub_uint16_t *) addr) + = (*((volatile grub_uint16_t *) addr) & ~mask) | value; + else + *((volatile grub_uint16_t *) addr) = value; + break; + + case 'b': + if ((mask & 0xff) != 0xff) + *((volatile grub_uint8_t *) addr) + = (*((volatile grub_uint8_t *) addr) & ~mask) | value; + else + *((volatile grub_uint8_t *) addr) = value; + break; + } return 0; } @@ -70,30 +118,30 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) GRUB_MOD_INIT(memrw) { cmd_read_byte = - grub_register_command ("read_byte", grub_cmd_read, - "read_byte ADDR", "read byte."); + grub_register_extcmd ("read_byte", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "read_byte ADDR", "Read byte from ADDR.", options); cmd_read_word = - grub_register_command ("read_word", grub_cmd_read, - "read_word ADDR", "read word."); + grub_register_extcmd ("read_word", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "read_word ADDR", "Read word from ADDR.", options); cmd_read_dword = - grub_register_command ("read_dword", grub_cmd_read, - "read_dword ADDR", "read dword."); + grub_register_extcmd ("read_dword", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "read_dword ADDR", "Read dword from ADDR.", options); cmd_write_byte = grub_register_command ("write_byte", grub_cmd_write, - "write_byte ADDR VALUE", "write byte."); + "write_byte ADDR VALUE [MASK]", "Write byte VALUE to ADDR."); cmd_write_word = grub_register_command ("write_word", grub_cmd_write, - "write_word ADDR VALUE", "write word."); + "write_word ADDR VALUE [MASK]", "Write word VALUE to ADDR."); cmd_write_dword = grub_register_command ("write_dword", grub_cmd_write, - "write_dword ADDR VALUE", "write dword."); + "write_dword ADDR VALUE [MASK]", "Write dword VALUE to ADDR."); } GRUB_MOD_FINI(memrw) { - grub_unregister_command (cmd_read_byte); - grub_unregister_command (cmd_read_word); - grub_unregister_command (cmd_read_dword); + grub_unregister_extcmd (cmd_read_byte); + grub_unregister_extcmd (cmd_read_word); + grub_unregister_extcmd (cmd_read_dword); grub_unregister_command (cmd_write_byte); grub_unregister_command (cmd_write_word); grub_unregister_command (cmd_write_dword); diff --git a/commands/minicmd.c b/commands/minicmd.c index 7a1695838..ee7f6b4c3 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -353,28 +353,28 @@ GRUB_MOD_INIT(minicmd) { cmd_cat = grub_register_command ("cat", grub_mini_cmd_cat, - "cat FILE", "show the contents of a file"); + "cat FILE", "Show the contents of a file."); cmd_help = grub_register_command ("help", grub_mini_cmd_help, - 0, "show this message"); + 0, "Show this message."); cmd_root = grub_register_command ("root", grub_mini_cmd_root, - "root [DEVICE]", "set the root device"); + "root [DEVICE]", "Set the root device."); cmd_dump = grub_register_command ("dump", grub_mini_cmd_dump, - "dump ADDR", "dump memory"); + "dump ADDR", "Dump memory."); cmd_rmmod = grub_register_command ("rmmod", grub_mini_cmd_rmmod, - "rmmod MODULE", "remove a module"); + "rmmod MODULE", "Remove a module."); cmd_lsmod = grub_register_command ("lsmod", grub_mini_cmd_lsmod, - 0, "show loaded modules"); + 0, "Show loaded modules."); cmd_exit = grub_register_command ("exit", grub_mini_cmd_exit, - 0, "exit from GRUB"); + 0, "Exit from GRUB."); cmd_clear = grub_register_command ("clear", grub_mini_cmd_clear, - 0, "clear the screen"); + 0, "Clear the screen."); } GRUB_MOD_FINI(minicmd) diff --git a/commands/parttool.c b/commands/parttool.c index 8c985fc4b..473652cec 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -34,9 +34,9 @@ static struct grub_parttool *parts = 0; static int curhandle = 0; static grub_dl_t mymod; static char helpmsg[] = - "perform COMMANDS on partition.\n" + "Perform COMMANDS on partition.\n" "Use \"parttool PARTITION help\" for the list " - "of available commands"; + "of available commands."; int grub_parttool_register(const char *part_name, diff --git a/commands/probe.c b/commands/probe.c index fabdb2a4a..fb196275f 100644 --- a/commands/probe.c +++ b/commands/probe.c @@ -31,15 +31,15 @@ #include #include -static const struct grub_arg_option options[] = +static const struct grub_arg_option options[] = { {"set", 's', GRUB_ARG_OPTION_OPTIONAL, - "set a variable to return value", "VAR", ARG_TYPE_STRING}, - {"driver", 'd', 0, "determine driver", 0, 0}, - {"partmap", 'p', 0, "determine partition map type", 0, 0}, - {"fs", 'f', 0, "determine filesystem type", 0, 0}, - {"fs-uuid", 'u', 0, "determine filesystem UUID", 0, 0}, - {"label", 'l', 0, "determine filesystem label", 0, 0}, + "Set a variable to return value.", "VAR", ARG_TYPE_STRING}, + {"driver", 'd', 0, "Determine driver.", 0, 0}, + {"partmap", 'p', 0, "Determine partition map type.", 0, 0}, + {"fs", 'f', 0, "Determine filesystem type.", 0, 0}, + {"fs-uuid", 'u', 0, "Determine filesystem UUID.", 0, 0}, + {"label", 'l', 0, "Determine filesystem label.", 0, 0}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/read.c b/commands/read.c index 82b30b461..270b7bd77 100644 --- a/commands/read.c +++ b/commands/read.c @@ -62,7 +62,7 @@ grub_getline (void) } static grub_err_t -grub_cmd_read (grub_command_t cmd UNUSED, int argc, char **args) +grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { char *line = grub_getline (); if (! line) @@ -80,7 +80,7 @@ GRUB_MOD_INIT(read) { cmd = grub_register_command ("read", grub_cmd_read, "read [ENVVAR]", - "Set variable with user input"); + "Set variable with user input."); } GRUB_MOD_FINI(read) diff --git a/commands/reboot.c b/commands/reboot.c index 0b553b710..2add295ef 100644 --- a/commands/reboot.c +++ b/commands/reboot.c @@ -19,18 +19,7 @@ #include #include - -#if defined(GRUB_MACHINE_IEEE1275) -#include -#elif defined(GRUB_MACHINE_EFI) -#include -#elif defined(GRUB_MACHINE_PCBIOS) -#include -#else -/* Platforms shipping standalone reboot, such as coreboot. */ -#include -#endif - +#include static grub_err_t grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)), @@ -46,7 +35,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(reboot) { cmd = grub_register_command ("reboot", grub_cmd_reboot, - 0, "Reboot the computer"); + 0, "Reboot the computer."); } GRUB_MOD_FINI(reboot) diff --git a/commands/search.c b/commands/search.c index 0cfd0ebbc..2907daa9f 100644 --- a/commands/search.c +++ b/commands/search.c @@ -29,11 +29,11 @@ static const struct grub_arg_option options[] = { - {"file", 'f', 0, "search devices by a file", 0, 0}, - {"label", 'l', 0, "search devices by a filesystem label", 0, 0}, - {"fs-uuid", 'u', 0, "search devices by a filesystem UUID", 0, 0}, - {"set", 's', GRUB_ARG_OPTION_OPTIONAL, "set a variable to the first device found", "VAR", ARG_TYPE_STRING}, - {"no-floppy", 'n', 0, "do not probe any floppy drive", 0, 0}, + {"file", 'f', 0, "Search devices by a file.", 0, 0}, + {"label", 'l', 0, "Search devices by a filesystem label.", 0, 0}, + {"fs-uuid", 'u', 0, "Search devices by a filesystem UUID.", 0, 0}, + {"set", 's', GRUB_ARG_OPTION_OPTIONAL, "Set a variable to the first device found.", "VAR", ARG_TYPE_STRING}, + {"no-floppy", 'n', 0, "Do not probe any floppy drive.", 0, 0}, {0, 0, 0, 0, 0, 0} }; diff --git a/commands/sleep.c b/commands/sleep.c index c9d533369..9207b60a7 100644 --- a/commands/sleep.c +++ b/commands/sleep.c @@ -27,8 +27,8 @@ static const struct grub_arg_option options[] = { - {"verbose", 'v', 0, "verbose countdown", 0, 0}, - {"interruptible", 'i', 0, "interruptible with ESC", 0, 0}, + {"verbose", 'v', 0, "Verbose countdown.", 0, 0}, + {"interruptible", 'i', 0, "Interruptible with ESC.", 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -106,7 +106,7 @@ GRUB_MOD_INIT(sleep) { cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH, "sleep NUMBER_OF_SECONDS", - "Wait for a specified number of seconds", + "Wait for a specified number of seconds.", options); } diff --git a/commands/test.c b/commands/test.c index 9c813c820..84b4279ea 100644 --- a/commands/test.c +++ b/commands/test.c @@ -420,9 +420,9 @@ static grub_command_t cmd_1, cmd_2; GRUB_MOD_INIT(test) { cmd_1 = grub_register_command ("[", grub_cmd_test, - "[ EXPRESSION ]", "Evaluate an expression"); + "[ EXPRESSION ]", "Evaluate an expression."); cmd_2 = grub_register_command ("test", grub_cmd_test, - "test EXPRESSION", "Evaluate an expression"); + "test EXPRESSION", "Evaluate an expression."); } GRUB_MOD_FINI(test) diff --git a/commands/true.c b/commands/true.c index 16ca31579..ef9f65889 100644 --- a/commands/true.c +++ b/commands/true.c @@ -43,10 +43,10 @@ GRUB_MOD_INIT(true) { cmd_true = grub_register_command ("true", grub_cmd_true, - 0, "do nothing, successfully"); + 0, "Do nothing, successfully."); cmd_false = grub_register_command ("false", grub_cmd_false, - 0, "do nothing, unsuccessfully"); + 0, "Do nothing, unsuccessfully."); } GRUB_MOD_FINI(true) diff --git a/commands/usbtest.c b/commands/usbtest.c index 018c1a25b..df124ca18 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -59,18 +60,60 @@ static const char *usb_devspeed[] = "High" }; +static grub_usb_err_t +grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, + char **string) +{ + struct grub_usb_desc_str descstr; + struct grub_usb_desc_str *descstrp; + grub_usb_err_t err; + + /* Only get the length. */ + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, 1, (char *) &descstr); + if (err) + return err; + + descstrp = grub_malloc (descstr.length); + if (! descstrp) + return GRUB_USB_ERR_INTERNAL; + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, descstr.length, (char *) descstrp); + + *string = grub_malloc (descstr.length / 2); + if (! *string) + { + grub_free (descstrp); + return GRUB_USB_ERR_INTERNAL; + } + + grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); + (*string)[descstr.length / 2 - 1] = '\0'; + grub_free (descstrp); + + return GRUB_USB_ERR_NONE; +} + static void usb_print_str (const char *description, grub_usb_device_t dev, int idx) { char *name; + grub_usb_err_t err; /* XXX: LANGID */ if (! idx) return; - grub_usb_get_string (dev, idx, 0x0409, &name); - grub_printf ("%s: `%s'\n", description, name); - grub_free (name); + err = grub_usb_get_string (dev, idx, 0x0409, &name); + if (err) + grub_printf ("Error %d retrieving %s\n", err, description); + else + { + grub_printf ("%s: `%s'\n", description, name); + grub_free (name); + } } static int @@ -152,7 +195,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(usbtest) { cmd = grub_register_command ("usb", grub_cmd_usbtest, - 0, "Test USB support"); + 0, "Test USB support."); } GRUB_MOD_FINI(usbtest) diff --git a/commands/videotest.c b/commands/videotest.c index fe504ee7b..33b46e229 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -181,7 +181,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(videotest) { cmd = grub_register_command ("videotest", grub_cmd_videotest, - 0, "Test video subsystem"); + 0, "Test video subsystem."); } GRUB_MOD_FINI(videotest) diff --git a/commands/xnu_uuid.c b/commands/xnu_uuid.c index 06e88e560..85c0e9ce4 100644 --- a/commands/xnu_uuid.c +++ b/commands/xnu_uuid.c @@ -1,4 +1,4 @@ -/* xnu_uuid.c - transform 64-bit serial number +/* xnu_uuid.c - transform 64-bit serial number to 128-bit uuid suitable for xnu. */ /* * GRUB -- GRand Unified Bootloader @@ -38,10 +38,10 @@ struct tohash grub_uint64_t serial; } __attribute__ ((packed)); -/* This prefix is used by xnu and boot-132 to hash +/* This prefix is used by xnu and boot-132 to hash together with volume serial. */ -static grub_uint8_t hash_prefix[16] - = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6, +static grub_uint8_t hash_prefix[16] + = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6, 0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC}; #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) @@ -237,7 +237,7 @@ md5_write( void *context, const void *inbuf_arg , grub_size_t inlen) } // _gcry_burn_stack (80+6*sizeof(void*)); - while( inlen >= 64 ) + while( inlen >= 64 ) { transform( hd, inbuf ); hd->count = 0; diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 69c01f298..76ca8e30e 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -78,6 +78,11 @@ grub_emu_SOURCES += util/sdl.c grub_emu_LDFLAGS += $(LIBSDL) endif +ifeq ($(enable_grub_emu_pci), yes) +grub_emu_SOURCES += util/pci.c commands/lspci.c +grub_emu_LDFLAGS += $(LIBPCIACCESS) +endif + grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ DISTCLEANFILES += grub_emu_init.lst diff --git a/conf/common.rmk b/conf/common.rmk index b6a61f189..f7d982f42 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -3,7 +3,13 @@ sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/devicemap.c util/misc.c + util/misc.c + +ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) +grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c +else +grub_mkdevicemap_SOURCES += util/devicemap.c +endif # For grub-mkelfimage. bin_UTILITIES += grub-mkelfimage @@ -686,3 +692,8 @@ pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += charset.mod +charset_mod_SOURCES = lib/charset.c +charset_mod_CFLAGS = $(COMMON_CFLAGS) +charset_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index ccc326f5c..8b69f7796 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -18,6 +18,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ kern/i386/multiboot_mmap.c \ + kern/i386/halt.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -61,6 +62,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ kern/i386/qemu/mmap.c \ + kern/i386/halt.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -107,7 +109,7 @@ pkglib_MODULES = linux.mod multiboot.mod \ lsmmap.mod mmap.mod # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -124,12 +126,12 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) # For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c +reboot_mod_SOURCES = commands/reboot.c reboot_mod_CFLAGS = $(COMMON_CFLAGS) reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) # For halt.mod. -halt_mod_SOURCES = commands/halt.c kern/i386/halt.c +halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c135ded4e..3a219e71b 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -30,14 +30,14 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. -pkglib_MODULES = kernel.mod chain.mod appleldr.mod \ +pkglib_MODULES = kernel.img chain.mod appleldr.mod \ linux.mod halt.mod reboot.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod -# For kernel.mod. -kernel_mod_EXPORTS = no -kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ +# For kernel.img. +kernel_img_EXPORTS = no +kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ @@ -48,26 +48,26 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c -kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h -kernel_mod_CFLAGS = $(COMMON_CFLAGS) -kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) -kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) MOSTLYCLEANFILES += symlist.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -154,8 +154,8 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 8d9577844..2a90fd2be 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -60,7 +60,7 @@ pkglib_MODULES = halt.mod reboot.mod suspend.mod \ date.mod datehook.mod lsmmap.mod mmap.mod # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 7e54b3b67..4ae753776 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -128,7 +128,7 @@ pkglib_MODULES = biosdisk.mod chain.mod \ efiemu.mod mmap.mod acpi.mod drivemap.mod # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -183,8 +183,8 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/i386.rmk b/conf/i386.rmk index bf102a9b6..c3f036d0f 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -15,6 +15,12 @@ vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 85b1fa211..122455280 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -66,7 +66,7 @@ pkglib_MODULES = halt.mod \ lsmmap.mod # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8c8bf27e6..4e90a4d35 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -63,7 +63,7 @@ sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \ - util/resolve.c + util/resolve.c gnulib/progname.c # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h @@ -82,12 +82,12 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ partmap/sun.c partmap/acorn.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c \ + util/raid.c util/lvm.c gnulib/progname.c \ grub_setup_init.c # For grub-ofpathname. grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c + util/ieee1275/ofpath.c util/misc.c gnulib/progname.c # Scripts. sbin_SCRIPTS = grub-install @@ -103,7 +103,7 @@ pkglib_MODULES = halt.mod \ lsmmap.mod # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 22ed2d639..a82b35222 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -29,14 +29,14 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. -pkglib_MODULES = kernel.mod chain.mod appleldr.mod \ +pkglib_MODULES = kernel.img chain.mod appleldr.mod \ halt.mod reboot.mod linux.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod ata.mod -# For kernel.mod. -kernel_mod_EXPORTS = no -kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ +# For kernel.img. +kernel_img_EXPORTS = no +kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -47,27 +47,27 @@ kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \ term/efi/console.c disk/efi/efidisk.c -kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ handler.h command.h i18n.h -kernel_mod_CFLAGS = $(COMMON_CFLAGS) -kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) -kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) MOSTLYCLEANFILES += symlist.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) # For boot.mod. -pkglib_MODULES += boot.mod +pkglib_MODULES += boot.mod boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -160,10 +160,16 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/configure.ac b/configure.ac index e1ee38105..935dd273f 100644 --- a/configure.ac +++ b/configure.ac @@ -122,6 +122,7 @@ case "$platform" in emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;; esac CFLAGS="$CFLAGS $machine_CFLAGS" +TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" TARGET_CFLAGS="$TARGET_CFLAGS $machine_CFLAGS" AC_SUBST(host_cpu) @@ -193,7 +194,7 @@ else fi # Check for functions. -AC_CHECK_FUNCS(posix_memalign memalign asprintf) +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) # For grub-mkisofs AC_HEADER_MAJOR @@ -529,6 +530,10 @@ AC_ARG_ENABLE([grub-emu-sdl], [AS_HELP_STRING([--enable-grub-emu-sdl], [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) +AC_ARG_ENABLE([grub-emu-pci], + [AS_HELP_STRING([--enable-grub-emu-pci], + [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) + if test "$platform" = emu; then missing_ncurses= [# Check for curses libraries.] @@ -550,6 +555,11 @@ fi if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi + +if test x"$enable_grub_emu_pci" = xyes ; then + grub_emu_usb_excuse="conflicts with PCI support" +fi + [if [ x"$grub_emu_usb_excuse" = x ]; then # Check for libusb libraries.] AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"], @@ -579,11 +589,13 @@ AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"], [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]]) AC_SUBST([LIBSDL]) [fi] + [if [ x"$grub_emu_sdl_excuse" = x ]; then # Check for headers.] AC_CHECK_HEADERS([SDL/SDL.h], [], [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]]) [fi] + if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then AC_MSG_ERROR([SDL support for grub-emu was explicitely requested but can't be compiled]) fi @@ -593,8 +605,36 @@ else enable_grub_emu_sdl=no fi +if test x"$enable_grub_emu_pci" != xyes ; then + grub_emu_pci_excuse="not enabled" +fi + +if test x"$enable_grub_emu_usb" = xyes ; then + grub_emu_pci_excuse="conflicts with USB support" +fi + +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for libpci libraries.] + AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], + [grub_emu_pci_excuse=["need libpciaccess library"]]) + AC_SUBST([LIBPCIACCESS]) +[fi] +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([pci/pci.h], [], + [grub_emu_pci_excuse=["need libpciaccess headers"]]) +[fi] + +if test x"$grub_emu_pci_excuse" = x ; then +enable_grub_emu_pci=yes +else + +enable_grub_emu_pci=no +fi + AC_SUBST([enable_grub_emu_sdl]) AC_SUBST([enable_grub_emu_usb]) +AC_SUBST([enable_grub_emu_pci]) fi AC_ARG_ENABLE([grub-fstest], @@ -674,6 +714,11 @@ echo SDL support for grub-emu: Yes else echo SDL support for grub-emu: No "($grub_emu_sdl_excuse)" fi +if [ x"$grub_emu_pci_excuse" = x ]; then +echo PCI support for grub-emu: Yes +else +echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" +fi fi if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes diff --git a/disk/ata.c b/disk/ata.c index 11489828f..af8c87180 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -388,7 +388,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) } static int NESTED_FUNC_ATTR -grub_ata_pciinit (int bus, int device, int func, +grub_ata_pciinit (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__((unused))) { static int compat_use[2] = { 0 }; @@ -402,7 +402,7 @@ grub_ata_pciinit (int bus, int device, int func, static int controller = 0; /* Read class. */ - addr = grub_pci_make_address (bus, device, func, 2); + addr = grub_pci_make_address (dev, 2); class = grub_pci_read (addr); /* Check if this class ID matches that of a PCI IDE Controller. */ @@ -429,9 +429,9 @@ grub_ata_pciinit (int bus, int device, int func, { /* Read the BARs, which either contain a mmapped IO address or the IO port address. */ - addr = grub_pci_make_address (bus, device, func, 4 + 2 * i); + addr = grub_pci_make_address (dev, 4 + 2 * i); bar1 = grub_pci_read (addr); - addr = grub_pci_make_address (bus, device, func, 5 + 2 * i); + addr = grub_pci_make_address (dev, 5 + 2 * i); bar2 = grub_pci_read (addr); /* Check if the BARs describe an IO region. */ @@ -444,7 +444,8 @@ grub_ata_pciinit (int bus, int device, int func, grub_dprintf ("ata", "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n", - bus, device, func, compat, rega, regb); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), compat, rega, regb); if (rega && regb) { diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 0a6137fad..af184b1ba 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -169,7 +169,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) else { grub_free (data); - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get C/H/S values"); + return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name); } } @@ -252,7 +252,7 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, 1024 /* cylinders */ * 256 /* heads */ * 63 /* spt */) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name); soff = ((grub_uint32_t) sector) % data->sectors + 1; head = ((grub_uint32_t) sector) / data->sectors; @@ -260,7 +260,7 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, coff = head / data->heads; if (coff >= data->cylinders) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name); if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive, coff, hoff, soff, size, segment)) @@ -268,9 +268,9 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, switch (cmd) { case GRUB_BIOSDISK_READ: - return grub_error (GRUB_ERR_READ_ERROR, "biosdisk read error"); + return grub_error (GRUB_ERR_READ_ERROR, "%s read error", disk->name); case GRUB_BIOSDISK_WRITE: - return grub_error (GRUB_ERR_WRITE_ERROR, "biosdisk write error"); + return grub_error (GRUB_ERR_WRITE_ERROR, "%s write error", disk->name); } } } diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index ca257d6d1..a33d729e3 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -107,7 +107,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name)) } if (! grub_strcmp (alias->type, "block") && - grub_strcmp (alias->name, "cdrom")) + grub_strncmp (alias->name, "cdrom", 5)) ret = hook (alias->name); return ret; } diff --git a/efiemu/main.c b/efiemu/main.c index b5608e666..05787284d 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -39,6 +39,7 @@ grub_efi_system_table64_t *grub_efiemu_system_table64 = 0; static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0; /* Linked list of configuration tables */ static struct grub_efiemu_configuration_table *efiemu_config_tables = 0; +static int prepared = 0; /* Free all allocated space */ grub_err_t @@ -70,6 +71,8 @@ grub_efiemu_unload (void) } efiemu_prepare_hooks = 0; + prepared = 0; + return GRUB_ERR_NONE; } @@ -277,14 +280,19 @@ grub_efiemu_prepare (void) { grub_err_t err; + if (prepared) + return GRUB_ERR_NONE; + grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n", 8 * grub_efiemu_sizeof_uintn_t ()); err = grub_efiemu_autocore (); - /* Create NVRAM if not yet done. */ + /* Create NVRAM. */ grub_efiemu_pnvram (); + prepared = 1; + if (grub_efiemu_sizeof_uintn_t () == 4) return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables); else @@ -316,9 +324,6 @@ grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload; -void -grub_efiemu_pnvram_cmd_register (void); - GRUB_MOD_INIT(efiemu) { cmd_loadcore = grub_register_command ("efiemu_loadcore", @@ -332,7 +337,6 @@ GRUB_MOD_INIT(efiemu) cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload, "efiemu_unload", "Unload EFI emulator"); - grub_efiemu_pnvram_cmd_register (); } GRUB_MOD_FINI(efiemu) @@ -340,5 +344,4 @@ GRUB_MOD_FINI(efiemu) grub_unregister_command (cmd_loadcore); grub_unregister_command (cmd_prepare); grub_unregister_command (cmd_unload); - grub_efiemu_pnvram_cmd_unregister (); } diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c index 04ad6e284..7af01c055 100644 --- a/efiemu/pnvram.c +++ b/efiemu/pnvram.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,62 +35,184 @@ static int timezone_handle = 0; static int accuracy_handle = 0; static int daylight_handle = 0; -/* Temporary place */ -static grub_uint8_t *nvram; static grub_size_t nvramsize; -static grub_uint32_t high_monotonic_count; -static grub_int16_t timezone; -static grub_uint8_t daylight; -static grub_uint32_t accuracy; - -static const struct grub_arg_option options[] = { - {"size", 's', 0, "number of bytes to reserve for pseudo NVRAM", 0, - ARG_TYPE_INT}, - {"high-monotonic-count", 'm', 0, - "Initial value of high monotonic count", 0, ARG_TYPE_INT}, - {"timezone", 't', 0, - "Timezone, offset in minutes from GMT", 0, ARG_TYPE_INT}, - {"accuracy", 'a', 0, - "Accuracy of clock, in 1e-12 units", 0, ARG_TYPE_INT}, - {"daylight", 'd', 0, - "Daylight value, as per EFI specifications", 0, ARG_TYPE_INT}, - {0, 0, 0, 0, 0, 0} -}; /* Parse signed value */ static int -grub_strtosl (char *arg, char **end, int base) +grub_strtosl (const char *arg, char **end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); return grub_strtoul (arg, end, base); } +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +static inline grub_err_t +unescape (char *in, char *out, char *outmax, int *len) +{ + char *ptr, *dptr; + dptr = out; + for (ptr = in; *ptr && dptr < outmax; ) + if (*ptr == '%' && ptr[1] && ptr[2]) + { + *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2])); + ptr += 3; + dptr++; + } + else + { + *dptr = *ptr; + ptr++; + dptr++; + } + if (dptr == outmax) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Too many NVRAM variables for reserved variable space." + " Try increasing EfiEmu.pnvram.size."); + *len = dptr - out; + return 0; +} + /* Export stuff for efiemu */ static grub_err_t nvram_set (void * data __attribute__ ((unused))) { + const char *env; /* Take definitive pointers */ - grub_uint8_t *nvram_def = grub_efiemu_mm_obtain_request (nvram_handle); + char *nvram = grub_efiemu_mm_obtain_request (nvram_handle); grub_uint32_t *nvramsize_def = grub_efiemu_mm_obtain_request (nvramsize_handle); - grub_uint32_t *high_monotonic_count_def + grub_uint32_t *high_monotonic_count = grub_efiemu_mm_obtain_request (high_monotonic_count_handle); - grub_int16_t *timezone_def + grub_int16_t *timezone = grub_efiemu_mm_obtain_request (timezone_handle); - grub_uint8_t *daylight_def + grub_uint8_t *daylight = grub_efiemu_mm_obtain_request (daylight_handle); - grub_uint32_t *accuracy_def + grub_uint32_t *accuracy = grub_efiemu_mm_obtain_request (accuracy_handle); + char *nvramptr; + + auto int iterate_env (struct grub_env_var *var); + int iterate_env (struct grub_env_var *var) + { + char *guid, *attr, *name, *varname; + struct efi_variable *efivar; + int len = 0; + int i; + grub_uint64_t guidcomp; + + if (grub_memcmp (var->name, "EfiEmu.pnvram.", + sizeof ("EfiEmu.pnvram.") - 1) != 0) + return 0; + + guid = var->name + sizeof ("EfiEmu.pnvram.") - 1; + + attr = grub_strchr (guid, '.'); + if (!attr) + return 0; + attr++; + + name = grub_strchr (attr, '.'); + if (!name) + return 0; + name++; + + efivar = (struct efi_variable *) nvramptr; + if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Too many NVRAM variables for reserved variable space." + " Try increasing EfiEmu.pnvram.size."); + return 1; + } + + nvramptr += sizeof (struct efi_variable); + + efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + guidcomp = grub_strtoull (guid, 0, 16); + for (i = 0; i < 8; i++) + efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff; + + efivar->attributes = grub_strtoull (attr, 0, 16); + + varname = grub_malloc (grub_strlen (name) + 1); + if (! varname) + return 1; + + if (unescape (name, varname, varname + grub_strlen (name) + 1, &len)) + return 1; + + len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr, + (nvramsize - (nvramptr - nvram)) / 2, + (grub_uint8_t *) varname, len, NULL); + + if (len < 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Broken UTF-8 in variable name\n"); + return 1; + } + + nvramptr += 2 * len; + *((grub_uint16_t *) nvramptr) = 0; + nvramptr += 2; + efivar->namelen = 2 * len + 2; + + if (unescape (var->value, nvramptr, nvram + nvramsize, &len)) + { + efivar->namelen = 0; + return 1; + } + + nvramptr += len; + + efivar->size = len; + + return 0; + } /* Copy to definitive loaction */ grub_dprintf ("efiemu", "preparing pnvram\n"); - grub_memcpy (nvram_def, nvram, nvramsize); + + env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count"); + *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1; + env = grub_env_get ("EfiEmu.pnvram.timezone"); + *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE; + env = grub_env_get ("EfiEmu.pnvram.accuracy"); + *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000; + env = grub_env_get ("EfiEmu.pnvram.daylight"); + *daylight = env ? grub_strtoul (env, 0, 0) : 0; + + nvramptr = nvram; + grub_memset (nvram, 0, nvramsize); + grub_env_iterate (iterate_env); + if (grub_errno) + return grub_errno; *nvramsize_def = nvramsize; - *high_monotonic_count_def = high_monotonic_count; - *timezone_def = timezone; - *daylight_def = daylight; - *accuracy_def = accuracy; /* Register symbols */ grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0); @@ -113,197 +236,27 @@ nvram_unload (void * data __attribute__ ((unused))) grub_efiemu_mm_return_request (timezone_handle); grub_efiemu_mm_return_request (accuracy_handle); grub_efiemu_mm_return_request (daylight_handle); - - grub_free (nvram); - nvram = 0; } -/* Load the variables file It's in format - guid1:attr1:name1:data1; - guid2:attr2:name2:data2; - ... - Where all fields are in hex -*/ -static grub_err_t -read_pnvram (char *filename) -{ - char *buf, *ptr, *ptr2; - grub_file_t file; - grub_size_t size; - grub_uint8_t *nvramptr = nvram; - struct efi_variable *efivar; - grub_size_t guidlen, datalen; - unsigned i, j; - - file = grub_file_open (filename); - if (!file) - return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram"); - size = grub_file_size (file); - buf = grub_malloc (size + 1); - if (!buf) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read pnvram"); - if (grub_file_read (file, buf, size) != (grub_ssize_t) size) - return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram"); - buf[size] = 0; - grub_file_close (file); - - for (ptr = buf; *ptr; ) - { - if (grub_isspace (*ptr)) - { - ptr++; - continue; - } - - efivar = (struct efi_variable *) nvramptr; - if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "file is too large for reserved variable space"); - - nvramptr += sizeof (struct efi_variable); - - /* look ahow long guid field is*/ - guidlen = 0; - for (ptr2 = ptr; (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (!grub_isspace (*ptr2)) - guidlen++; - guidlen /= 2; - - /* Read guid */ - if (guidlen != sizeof (efivar->guid)) - { - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - for (i = 0; i < 2 * sizeof (efivar->guid); i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i%2 == 0) - ((grub_uint8_t *)&(efivar->guid))[i/2] = hex << 4; - else - ((grub_uint8_t *)&(efivar->guid))[i/2] |= hex; - ptr++; - } - - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != ':') - { - grub_dprintf ("efiemu", "Not colon\n"); - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - ptr++; - while (grub_isspace (*ptr)) - ptr++; - - /* Attributes can be just parsed by existing functions */ - efivar->attributes = grub_strtoul (ptr, &ptr, 16); - - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != ':') - { - grub_dprintf ("efiemu", "Not colon\n"); - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - ptr++; - while (grub_isspace (*ptr)) - ptr++; - - /* Read name and value */ - for (j = 0; j < 2; j++) - { - /* Look the length */ - datalen = 0; - for (ptr2 = ptr; *ptr2 && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (!grub_isspace (*ptr2)) - datalen++; - datalen /= 2; - - if (nvramptr - nvram + datalen > nvramsize) - { - grub_free (buf); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "file is too large for reserved " - " variable space"); - } - - for (i = 0; i < 2 * datalen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i%2 == 0) - nvramptr[i/2] = hex << 4; - else - nvramptr[i/2] |= hex; - ptr++; - } - nvramptr += datalen; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != (j ? ';' : ':')) - { - grub_free (buf); - grub_dprintf ("efiemu", j?"Not semicolon\n":"Not colon\n"); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - if (j) - efivar->size = datalen; - else - efivar->namelen = datalen; - - ptr++; - } - } - grub_free (buf); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_efiemu_make_nvram (void) +grub_err_t +grub_efiemu_pnvram (void) { + const char *size; grub_err_t err; - err = grub_efiemu_autocore (); - if (err) - { - grub_free (nvram); - return err; - } + nvramsize = 0; + + size = grub_env_get ("EfiEmu.pnvram.size"); + if (size) + nvramsize = grub_strtoul (size, 0, 0); + + if (!nvramsize) + nvramsize = 2048; err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0); if (err) - { - grub_free (nvram); - return err; - } + return err; + nvram_handle = grub_efiemu_request_memalign (1, nvramsize, GRUB_EFI_RUNTIME_SERVICES_DATA); @@ -323,78 +276,5 @@ grub_efiemu_make_nvram (void) = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t), GRUB_EFI_RUNTIME_SERVICES_DATA); - grub_efiemu_request_symbols (6); return GRUB_ERR_NONE; } - -grub_err_t -grub_efiemu_pnvram (void) -{ - if (nvram) - return GRUB_ERR_NONE; - - nvramsize = 2048; - high_monotonic_count = 1; - timezone = GRUB_EFI_UNSPECIFIED_TIMEZONE; - accuracy = 50000000; - daylight = 0; - - nvram = grub_zalloc (nvramsize); - if (!nvram) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate space for temporary pnvram storage"); - - return grub_efiemu_make_nvram (); -} - -static grub_err_t -grub_cmd_efiemu_pnvram (struct grub_extcmd *cmd, - int argc, char **args) -{ - struct grub_arg_list *state = cmd->state; - grub_err_t err; - - if (argc > 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one argument expected"); - - nvramsize = state[0].set ? grub_strtoul (state[0].arg, 0, 0) : 2048; - high_monotonic_count = state[1].set ? grub_strtoul (state[1].arg, 0, 0) : 1; - timezone = state[2].set ? grub_strtosl (state[2].arg, 0, 0) - : GRUB_EFI_UNSPECIFIED_TIMEZONE; - accuracy = state[3].set ? grub_strtoul (state[3].arg, 0, 0) : 50000000; - daylight = state[4].set ? grub_strtoul (state[4].arg, 0, 0) : 0; - - nvram = grub_zalloc (nvramsize); - if (!nvram) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate space for temporary pnvram storage"); - - if (argc == 1 && (err = read_pnvram (args[0]))) - { - grub_free (nvram); - return err; - } - return grub_efiemu_make_nvram (); -} - -static grub_extcmd_t cmd; - -void grub_efiemu_pnvram_cmd_register (void); -void grub_efiemu_pnvram_cmd_unregister (void); - -void -grub_efiemu_pnvram_cmd_register (void) -{ - cmd = grub_register_extcmd ("efiemu_pnvram", grub_cmd_efiemu_pnvram, - GRUB_COMMAND_FLAG_BOTH, - "efiemu_pnvram [FILENAME]", - "Initialise pseudo-NVRAM and load variables " - "from FILE", - options); -} - -void -grub_efiemu_pnvram_cmd_unregister (void) -{ - grub_unregister_extcmd (cmd); -} diff --git a/efiemu/prepare.c b/efiemu/prepare.c index 9e6d46fa1..620260049 100644 --- a/efiemu/prepare.c +++ b/efiemu/prepare.c @@ -36,7 +36,6 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, int cntconftables = 0; struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0; - struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; int i; int handle; grub_off_t off; @@ -54,6 +53,7 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, /* Switch from phase 1 (counting) to phase 2 (real job) */ grub_efiemu_alloc_syms (); grub_efiemu_mm_do_alloc (); + grub_efiemu_write_sym_markers (); grub_efiemu_system_table32 = 0; grub_efiemu_system_table64 = 0; @@ -81,16 +81,6 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, = (struct SUFFIX (grub_efi_system_table) *) ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - /* compute CRC32 of runtime_services */ - if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", - &handle, &off))) - return err; - runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) - ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - runtime_services->hdr.crc32 = 0; - runtime_services->hdr.crc32 = grub_getcrc32 - (0, runtime_services, runtime_services->hdr.header_size); - /* Put pointer to the list of configuration tables in system table */ grub_efiemu_write_value (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0, @@ -113,16 +103,51 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, conftables[i].vendor_table = PTR_TO_UINT64 (cur->data); } + err = SUFFIX (grub_efiemu_crc) (); + if (err) + { + grub_efiemu_unload (); + return err; + } + + grub_dprintf ("efiemu","system_table = %p, conftables = %p (%d entries)\n", + SUFFIX (grub_efiemu_system_table), conftables, cntconftables); + + return GRUB_ERR_NONE; +} + +grub_err_t +SUFFIX (grub_efiemu_crc) (void) +{ + grub_err_t err; + int handle; + grub_off_t off; + struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; + + /* compute CRC32 of runtime_services */ + err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", + &handle, &off); + if (err) + return err; + + runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) + ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); + runtime_services->hdr.crc32 = 0; + runtime_services->hdr.crc32 = grub_getcrc32 + (0, runtime_services, runtime_services->hdr.header_size); + + err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off); + if (err) + return err; + /* compute CRC32 of system table */ SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0; SUFFIX (grub_efiemu_system_table)->hdr.crc32 = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table), SUFFIX (grub_efiemu_system_table)->hdr.header_size); - grub_dprintf ("efiemu","system_table = %p, runtime_services = %p," - " conftables = %p (%d entries)\n", - SUFFIX (grub_efiemu_system_table), runtime_services, - conftables, cntconftables); + grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n", + SUFFIX (grub_efiemu_system_table), runtime_services); return GRUB_ERR_NONE; } diff --git a/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c index 085e75d0c..73893414a 100644 --- a/efiemu/runtime/efiemu.c +++ b/efiemu/runtime/efiemu.c @@ -111,9 +111,8 @@ static grub_uint8_t loge[1000] = "EFIEMULOG"; static int logn = 9; #define LOG(x) { if (logn<900) loge[logn++]=x; } -static int ptv_relocated = 0; - /* Interface with grub */ +extern grub_uint8_t efiemu_ptv_relocated; struct grub_efi_runtime_services efiemu_runtime_services; struct grub_efi_system_table efiemu_system_table; extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[]; @@ -343,9 +342,9 @@ grub_efi_status_t EFI_FUNC LOG ('e'); /* Ensure that we are called only once */ - if (ptv_relocated) + if (efiemu_ptv_relocated) return GRUB_EFI_UNSUPPORTED; - ptv_relocated = 1; + efiemu_ptv_relocated = 1; /* Correct addresses using information supplied by grub */ for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++) diff --git a/efiemu/symbols.c b/efiemu/symbols.c index ec508d975..5b9b2aec7 100644 --- a/efiemu/symbols.c +++ b/efiemu/symbols.c @@ -26,6 +26,7 @@ static int ptv_written = 0; static int ptv_alloc = 0; static int ptv_handle = 0; +static int relocated_handle = 0; static int ptv_requested = 0; static struct grub_efiemu_sym *efiemu_syms = 0; @@ -54,6 +55,8 @@ grub_efiemu_free_syms (void) ptv_requested = 0; grub_efiemu_mm_return_request (ptv_handle); ptv_handle = 0; + grub_efiemu_mm_return_request (relocated_handle); + relocated_handle = 0; } /* Announce that the module will need NUM allocators */ @@ -114,10 +117,26 @@ grub_efiemu_alloc_syms (void) ptv_handle = grub_efiemu_request_memalign (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel), GRUB_EFI_RUNTIME_SERVICES_DATA); + relocated_handle = grub_efiemu_request_memalign + (1, sizeof (grub_uint8_t), GRUB_EFI_RUNTIME_SERVICES_DATA); + + grub_efiemu_register_symbol ("efiemu_ptv_relocated", relocated_handle, 0); grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0); return grub_errno; } +grub_err_t +grub_efiemu_write_sym_markers (void) +{ + struct grub_efiemu_ptv_rel *ptv_rels + = grub_efiemu_mm_obtain_request (ptv_handle); + grub_uint8_t *relocated = grub_efiemu_mm_obtain_request (relocated_handle); + grub_memset (ptv_rels, 0, (ptv_requested + 1) + * sizeof (struct grub_efiemu_ptv_rel)); + *relocated = 0; + return GRUB_ERR_NONE; +} + /* Write value (pointer to memory PLUS_HANDLE) - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this @@ -186,3 +205,67 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, return GRUB_ERR_NONE; } + +grub_err_t +grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version + __attribute__ ((unused)), + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_uint8_t *ptv_relocated; + struct grub_efiemu_ptv_rel *cur_relloc; + struct grub_efiemu_ptv_rel *ptv_rels; + + ptv_relocated = grub_efiemu_mm_obtain_request (relocated_handle); + ptv_rels = grub_efiemu_mm_obtain_request (ptv_handle); + + /* Ensure that we are called only once */ + if (*ptv_relocated) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "EfiEmu is already relocated."); + *ptv_relocated = 1; + + /* Correct addresses using information supplied by grub */ + for (cur_relloc = ptv_rels; cur_relloc->size; cur_relloc++) + { + grub_int64_t corr = 0; + grub_efi_memory_descriptor_t *descptr; + + /* Compute correction */ + for (descptr = virtual_map; + (grub_size_t) ((grub_uint8_t *) descptr + - (grub_uint8_t *) virtual_map) < memory_map_size; + descptr = (grub_efi_memory_descriptor_t *) + ((grub_uint8_t *) descptr + descriptor_size)) + { + if (descptr->type == cur_relloc->plustype) + corr += descptr->virtual_start - descptr->physical_start; + if (descptr->type == cur_relloc->minustype) + corr -= descptr->virtual_start - descptr->physical_start; + } + + /* Apply correction */ + switch (cur_relloc->size) + { + case 8: + *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 4: + *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 2: + *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 1: + *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + } + } + + /* Recompute crc32 of system table and runtime services */ + + if (grub_efiemu_sizeof_uintn_t () == 4) + return grub_efiemu_crc32 (); + else + return grub_efiemu_crc64 (); +} diff --git a/fs/fat.c b/fs/fat.c index e7f01629e..ab84ee49a 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_FAT_DIR_ENTRY_SIZE 32 diff --git a/fs/hfs.c b/fs/hfs.c index 5062b5f71..493455054 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -1072,6 +1072,31 @@ grub_hfs_label (grub_device_t device, char **label) return grub_errno; } +static grub_err_t +grub_hfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_hfs_data *data; + + grub_dl_ref (my_mod); + + data = grub_hfs_mount (device->disk); + if (data && data->sblock.num_serial != 0) + { + *uuid = grub_malloc (16 + sizeof ('\0')); + grub_sprintf (*uuid, "%016llx", + (unsigned long long) + grub_be_to_cpu64 (data->sblock.num_serial)); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + static struct grub_fs grub_hfs_fs = @@ -1082,6 +1107,7 @@ static struct grub_fs grub_hfs_fs = .read = grub_hfs_read, .close = grub_hfs_close, .label = grub_hfs_label, + .uuid = grub_hfs_uuid, .next = 0 }; diff --git a/fs/hfsplus.c b/fs/hfsplus.c index b306e8d6a..71910330f 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -28,6 +28,7 @@ #include #include #include +#include #define GRUB_HFSPLUS_MAGIC 0x482B #define GRUB_HFSPLUSX_MAGIC 0x4858 diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 6c41d4298..4bab45d35 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -107,9 +107,11 @@ static struct grub_disk_dev grub_pxe_dev = }; static grub_err_t -grub_pxefs_dir (grub_device_t device UNUSED, const char *path UNUSED, +grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), + const char *path __attribute__ ((unused)), int (*hook) (const char *filename, - const struct grub_dirhook_info *info) UNUSED) + const struct grub_dirhook_info *info) + __attribute__ ((unused))) { return GRUB_ERR_NONE; } diff --git a/fs/iso9660.c b/fs/iso9660.c index 9b7ce765b..976222a45 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GRUB_ISO9660_FSTYPE_DIR 0040000 #define GRUB_ISO9660_FSTYPE_REG 0100000 diff --git a/fs/jfs.c b/fs/jfs.c index b73f9bdd4..589b6ae5a 100644 --- a/fs/jfs.c +++ b/fs/jfs.c @@ -24,6 +24,7 @@ #include #include #include +#include #define GRUB_JFS_MAX_SYMLNK_CNT 8 #define GRUB_JFS_FILETYPE_MASK 0170000 diff --git a/fs/ntfs.c b/fs/ntfs.c index 163f3e0a8..f3097d60b 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -63,7 +64,7 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno); static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, - grub_uint32_t ofs, grub_uint32_t len, + grub_disk_addr_t ofs, grub_size_t len, int cached, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t @@ -72,7 +73,7 @@ static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, unsigned length)); static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest, - grub_uint32_t ofs, grub_uint32_t len, + grub_disk_addr_t ofs, grub_size_t len, int cached, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t @@ -260,9 +261,9 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, } static char * -read_run_data (char *run, int nn, grub_uint32_t * val, int sig) +read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig) { - grub_uint32_t r, v; + grub_disk_addr_t r, v; r = 0; v = 1; @@ -284,7 +285,7 @@ grub_err_t grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx) { int c1, c2; - grub_uint32_t val; + grub_disk_addr_t val; char *run; run = ctx->cur_run; @@ -335,25 +336,25 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) struct grub_ntfs_rlst *ctx; ctx = (struct grub_ntfs_rlst *) node; - if ((grub_uint32_t) block >= ctx->next_vcn) + if (block >= ctx->next_vcn) { if (grub_ntfs_read_run_list (ctx)) return -1; return ctx->curr_lcn; } else - return (ctx->flags & RF_BLNK) ? 0 : ((grub_uint32_t) block - + return (ctx->flags & RF_BLNK) ? 0 : (block - ctx->curr_vcn + ctx->curr_lcn); } static grub_err_t -read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, - grub_uint32_t len, int cached, +read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + grub_disk_addr_t ofs, grub_size_t len, int cached, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length)) { - grub_uint32_t vcn; + grub_disk_addr_t vcn; struct grub_ntfs_rlst cc, *ctx; if (len == 0) @@ -388,7 +389,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, { if ((ofs & (~(COM_LEN - 1))) == at->save_pos) { - grub_uint32_t n; + grub_disk_addr_t n; n = COM_LEN - (ofs - at->save_pos); if (n > len) @@ -411,11 +412,11 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, at->save_pos = 1; } - vcn = ctx->target_vcn = (ofs / COM_LEN) * (COM_SEC / ctx->comp.spc); + vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc); ctx->target_vcn &= ~0xF; } else - vcn = ctx->target_vcn = (ofs >> BLK_SHR) / ctx->comp.spc; + vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0); ctx->next_vcn = u32at (pa, 0x10); ctx->curr_lcn = 0; @@ -427,11 +428,13 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, if (at->flags & AF_GPOS) { - grub_uint32_t st0, st1; + grub_disk_addr_t st0, st1; + grub_uint32_t m; + + grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m); st0 = - (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + - ((ofs >> BLK_SHR) % ctx->comp.spc); + (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m; st1 = st0 + 1; if (st1 == (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc) @@ -462,8 +465,8 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, } static grub_err_t -read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, - grub_uint32_t len, int cached, +read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + grub_size_t len, int cached, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length)) @@ -479,9 +482,9 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, if (at->flags & AF_ALST) { char *pa; - grub_uint32_t vcn; + grub_disk_addr_t vcn; - vcn = ofs / (at->mft->data->spc << BLK_SHR); + vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0); pa = at->attr_nxt + u16at (at->attr_nxt, 4); while (pa < at->attr_end) { @@ -508,7 +511,7 @@ static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) { if (read_attr - (&data->mmft.attr, buf, mftno * (data->mft_size << BLK_SHR), + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR), data->mft_size << BLK_SHR, 0, 0)) return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno); return fixup (data, buf, data->mft_size, "FILE"); @@ -640,7 +643,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, unsigned char *bitmap; struct grub_ntfs_attr attr, *at; char *cur_pos, *indx, *bmp; - int bitmap_len, ret = 0; + int ret = 0; + grub_size_t bitmap_len; struct grub_ntfs_file *mft; mft = (struct grub_ntfs_file *) dir; @@ -744,14 +748,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, if (bitmap) { - grub_uint32_t v, i; + grub_disk_addr_t v, i; indx = grub_malloc (mft->data->idx_size << BLK_SHR); if (indx == NULL) goto done; v = 1; - for (i = 0; i < (grub_uint32_t) bitmap_len * 8; i++) + for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++) { if (*bitmap & v) { diff --git a/fs/ntfscomp.c b/fs/ntfscomp.c index 20c79ac07..6bb33ffb1 100644 --- a/fs/ntfscomp.c +++ b/fs/ntfscomp.c @@ -209,7 +209,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) } } - nn = (16 - (ctx->target_vcn & 0xF)) / cpb; + nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb; if (nn > num) nn = num; num -= nn; diff --git a/gendistlist.sh b/gendistlist.sh old mode 100644 new mode 100755 index 36685a092..102c0c11c --- a/gendistlist.sh +++ b/gendistlist.sh @@ -19,6 +19,7 @@ EXTRA_DISTFILES="AUTHORS COPYING ChangeLog DISTLIST INSTALL NEWS README \ gendistlist.sh genfslist.sh genhandlerlist.sh geninit.sh \ geninitheader.sh genkernsyms.sh.in genmk.rb genmoddep.awk \ genmodsrc.sh genpartmaplist.sh genparttoollist.sh \ + genvideolist.sh \ gensymlist.sh.in install-sh mkinstalldirs stamp-h.in" DISTDIRS="boot bus commands conf disk docs efiemu font fs hello hook include io \ @@ -35,7 +36,7 @@ dir=`dirname $0` cd $dir for dir in $DISTDIRS; do - for d in `find $dir -type d -not -name .svn -not -name .bzr | sort`; do + for d in `find $dir -type d ! -name .svn ! -name .bzr | sort`; do find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \ -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \ -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \ diff --git a/genmk.rb b/genmk.rb index 50bf88fe1..b3dbe8678 100644 --- a/genmk.rb +++ b/genmk.rb @@ -193,6 +193,7 @@ endif partmap = 'partmap-' + obj.suffix('lst') handler = 'handler-' + obj.suffix('lst') parttool = 'parttool-' + obj.suffix('lst') + video = 'video-' + obj.suffix('lst') dep = deps[i] flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end @@ -203,7 +204,7 @@ endif -include #{dep} clean-module-#{extra_target}.#{@rule_count}: - rm -f #{command} #{fs} #{partmap} #{handler} #{parttool} + rm -f #{command} #{fs} #{partmap} #{handler} #{parttool} #{video} CLEAN_MODULE_TARGETS += clean-module-#{extra_target}.#{@rule_count} @@ -212,6 +213,7 @@ FSFILES += #{fs} PARTTOOLFILES += #{parttool} PARTMAPFILES += #{partmap} HANDLERFILES += #{handler} +VIDEOFILES += #{video} #{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh set -e; \ @@ -238,6 +240,11 @@ HANDLERFILES += #{handler} $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ | sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) +#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh + set -e; \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + | sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) + " end.join('') end @@ -357,6 +364,7 @@ class Script #{@name}: #{src} $(#{src}_DEPENDENCIES) config.status ./config.status --file=#{name}:#{src} + sed -i -e 's,@pkglib_DATA@,$(pkglib_DATA),g' $@ chmod +x $@ " diff --git a/genvideolist.sh b/genvideolist.sh new file mode 100644 index 000000000..b208fa25c --- /dev/null +++ b/genvideolist.sh @@ -0,0 +1,26 @@ +#! /bin/sh +# +# Copyright (C) 2005,2008,2009 Free Software Foundation, Inc. +# +# This script is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Read source code from stdin and detect partmap names. + +module=$1 + +# Ignore video.mod. +if test $module = video; then + exit +fi + +# For now, this emits only a module name, if the module registers a partition map. +if grep -v "^#" | grep '^ *grub_video_register' >/dev/null 2>&1; then + echo $module +fi diff --git a/gettext/gettext.c b/gettext/gettext.c index 856265e6f..fe14dab2e 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -17,6 +17,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include @@ -28,8 +29,8 @@ #include #include -/* - .mo file information from: +/* + .mo file information from: http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html . */ @@ -41,6 +42,16 @@ static int grub_gettext_max; static const char *(*grub_gettext_original) (const char *s); +struct grub_gettext_msg +{ + struct grub_gettext_msg *next; + const char *name; + + const char *translated; +}; + +struct grub_gettext_msg *grub_gettext_msg_list = NULL; + #define GETTEXT_MAGIC_NUMBER 0 #define GETTEXT_FILE_FORMAT 4 #define GETTEXT_NUMBER_OF_STRINGS 8 @@ -79,7 +90,7 @@ grub_gettext_getstring_from_offset (grub_uint32_t offset, translation[length] = '\0'; } -static char * +static const char * grub_gettext_gettranslation_from_position (int position) { int offsettranslation; @@ -130,9 +141,18 @@ static const char * grub_gettext_translate (const char *orig) { char *current_string; - char *ret; + const char *ret; int min, max, current; + int found = 0; + + struct grub_gettext_msg *cur; + + cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list), + orig); + + if (cur) + return cur->translated; if (fd_mo == 0) return orig; @@ -142,7 +162,7 @@ grub_gettext_translate (const char *orig) current = (max + min) / 2; - while (current != min && current != max) + while (current != min && current != max && found == 0) { current_string = grub_gettext_getstring_from_position (current); @@ -160,13 +180,31 @@ grub_gettext_translate (const char *orig) else if (grub_strcmp (current_string, orig) == 0) { grub_free (current_string); - return grub_gettext_gettranslation_from_position (current); + found = 1; } current = (max + min) / 2; } - ret = grub_malloc (grub_strlen (orig) + 1); - grub_strcpy (ret, orig); + ret = found ? grub_gettext_gettranslation_from_position (current) : orig; + + if (found) + { + cur = grub_zalloc (sizeof (*cur)); + + if (cur) + { + cur->name = grub_strdup (orig); + if (cur->name) + { + cur->translated = ret; + grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list), + GRUB_AS_LIST (cur)); + } + } + else + grub_errno = GRUB_ERR_NONE; + } + return ret; } @@ -222,7 +260,7 @@ grub_gettext_init_ext (const char *lang) locale_dir = grub_env_get ("locale_dir"); if (locale_dir == NULL) { - grub_printf ("locale_dir variable is not set up."); + grub_dprintf ("gettext", "locale_dir variable is not set up.\n"); return; } @@ -259,12 +297,29 @@ grub_gettext_init_ext (const char *lang) } } +static void +grub_gettext_delete_list () +{ + struct grub_gettext_msg *item; + + while ((item = + grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0) + { + char *original = (char *) ((struct grub_gettext_msg *) item)->name; + grub_free (original); + + // Don't delete the translated message because could be in use. + } +} + static char * grub_gettext_env_write_lang (struct grub_env_var *var __attribute__ ((unused)), const char *val) { grub_gettext_init_ext (val); + grub_gettext_delete_list (); + return grub_strdup (val); } @@ -307,5 +362,7 @@ GRUB_MOD_FINI (gettext) if (fd_mo != 0) grub_file_close (fd_mo); + grub_gettext_delete_list (); + grub_gettext = grub_gettext_original; } diff --git a/include/grub/auth.h b/include/grub/auth.h index da930eeda..823442941 100644 --- a/include/grub/auth.h +++ b/include/grub/auth.h @@ -19,10 +19,11 @@ #define GRUB_AUTH_HEADER 1 #include +#include /* Macros for indistinguishibility. */ #define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.") -#define GRUB_GET_PASSWORD(string, len) grub_cmdline_get ("Enter password: ", \ +#define GRUB_GET_PASSWORD(string, len) grub_cmdline_get (N_("Enter password:"), \ string, len, \ '*', 0, 0) diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h index b151cfc37..5ae4b3a21 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -26,8 +26,10 @@ # include # define grub_autoefi_get_memory_map grub_efi_get_memory_map # define grub_autoefi_finish_boot_services grub_efi_finish_boot_services +# define grub_autoefi_exit_boot_services grub_efi_exit_boot_services # define grub_autoefi_system_table grub_efi_system_table # define grub_autoefi_mmap_iterate grub_machine_mmap_iterate +# define grub_autoefi_set_virtual_address_map grub_efi_set_virtual_address_map static inline grub_err_t grub_autoefi_prepare (void) { return GRUB_ERR_NONE; @@ -53,9 +55,11 @@ static inline grub_err_t grub_autoefi_prepare (void) # include # define grub_autoefi_get_memory_map grub_efiemu_get_memory_map # define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services +# define grub_autoefi_exit_boot_services grub_efiemu_exit_boot_services # define grub_autoefi_system_table grub_efiemu_system_table # define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate # define grub_autoefi_prepare grub_efiemu_prepare +# define grub_autoefi_set_virtual_address_map grub_efiemu_set_virtual_address_map # define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE # define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED # define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI diff --git a/include/grub/charset.h b/include/grub/charset.h new file mode 100644 index 000000000..f85862f8b --- /dev/null +++ b/include/grub/charset.h @@ -0,0 +1,112 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CHARSET_HEADER +#define GRUB_CHARSET_HEADER 1 + +#include + +#define GRUB_UINT8_1_LEADINGBIT 0x80 +#define GRUB_UINT8_2_LEADINGBITS 0xc0 +#define GRUB_UINT8_3_LEADINGBITS 0xe0 +#define GRUB_UINT8_4_LEADINGBITS 0xf0 +#define GRUB_UINT8_5_LEADINGBITS 0xf8 +#define GRUB_UINT8_6_LEADINGBITS 0xfc +#define GRUB_UINT8_7_LEADINGBITS 0xfe + +#define GRUB_UINT8_1_TRAILINGBIT 0x01 +#define GRUB_UINT8_2_TRAILINGBITS 0x03 +#define GRUB_UINT8_3_TRAILINGBITS 0x07 +#define GRUB_UINT8_4_TRAILINGBITS 0x0f +#define GRUB_UINT8_5_TRAILINGBITS 0x1f +#define GRUB_UINT8_6_TRAILINGBITS 0x3f + +#define GRUB_UCS2_LIMIT 0x10000 +#define GRUB_UTF16_UPPER_SURROGATE(code) \ + (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff)) +#define GRUB_UTF16_LOWER_SURROGATE(code) \ + (0xDC00 + (((code) - GRUB_UCS2_LIMIT) & 0xfff)) + +grub_ssize_t +grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend); + +/* Convert UTF-16 to UTF-8. */ +static inline grub_uint8_t * +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, + grub_size_t size) +{ + grub_uint32_t code_high = 0; + + while (size--) + { + grub_uint32_t code = *src++; + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +#endif diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index e870eab41..32904150e 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -21,6 +21,7 @@ #define GRUB_EFI_API_HEADER 1 #include +#include /* For consistency and safety, we name the EFI-defined types differently. All names are transformed into lower case, _t appended, and diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 916f9d662..b12205ad3 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -54,9 +54,11 @@ char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); grub_efi_device_path_t * EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); -void EXPORT_FUNC (grub_reboot) (void); -void EXPORT_FUNC (grub_halt) (void); int EXPORT_FUNC (grub_efi_finish_boot_services) (void); +grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h index a55869dc7..a29221919 100644 --- a/include/grub/efi/graphics_output.h +++ b/include/grub/efi/graphics_output.h @@ -24,7 +24,7 @@ #define GRUB_EFI_GOP_GUID \ { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a }} -typedef enum +typedef enum { GRUB_EFI_GOT_RGBA8, GRUB_EFI_GOT_BGRA8, diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 20163dd61..3980d32cd 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -268,9 +268,19 @@ void grub_efiemu_free_syms (void); grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value, int plus_handle, int minus_handle, int ptv_needed, int size); +grub_err_t grub_efiemu_write_sym_markers (void); grub_err_t grub_efiemu_pnvram (void); grub_err_t grub_efiemu_prepare (void); char *grub_efiemu_get_default_core_name (void); void grub_efiemu_pnvram_cmd_unregister (void); grub_err_t grub_efiemu_autocore (void); +grub_err_t grub_efiemu_crc32 (void); +grub_err_t grub_efiemu_crc64 (void); +grub_err_t +grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version + __attribute__ ((unused)), + grub_efi_memory_descriptor_t *virtual_map); + #endif /* ! GRUB_EFI_EMU_HEADER */ diff --git a/include/grub/hfs.h b/include/grub/hfs.h index 08b947ccb..d93b9a2c9 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -48,7 +48,8 @@ struct grub_hfs_sblock /* A pascal style string that holds the volumename. */ grub_uint8_t volname[28]; - grub_uint8_t unused5[60]; + grub_uint8_t unused5[52]; + grub_uint64_t num_serial; grub_uint16_t embed_sig; struct grub_hfs_extent embed_extent; grub_uint8_t unused6[4]; diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h index 61e72a71b..f22c21190 100644 --- a/include/grub/i386/macho.h +++ b/include/grub/i386/macho.h @@ -1,3 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_MACHO_H +#define GRUB_CPU_MACHO_H 1 + +#include + #define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) #define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) @@ -9,3 +32,15 @@ struct grub_macho_thread32 grub_uint32_t entry_point; grub_uint8_t unknown2[20]; } __attribute__ ((packed)); + + +struct grub_macho_thread64 +{ + grub_uint32_t cmd; + grub_uint32_t cmdsize; + grub_uint8_t unknown1[0x88]; + grub_uint64_t entry_point; + grub_uint8_t unknown2[0x20]; +} __attribute__ ((packed)); + +#endif diff --git a/kern/i386/reboot.c b/include/grub/i386/memory.h similarity index 58% rename from kern/i386/reboot.c rename to include/grub/i386/memory.h index 6d562f827..466947cc6 100644 --- a/kern/i386/reboot.c +++ b/include/grub/i386/memory.h @@ -1,6 +1,7 @@ +/* memory.h - describe the memory map */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2002,2007,2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,17 +17,14 @@ * along with GRUB. If not, see . */ -#include -#include -#include -#include +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 -void -grub_reboot (void) -{ - /* Use the keyboard controller to reboot. That's what keyboards were - designed for, isn't it? */ - grub_outb (KEYBOARD_COMMAND_REBOOT, KEYBOARD_REG_STATUS); +/* The flag for protected mode. */ +#define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000040 +#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 +#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 +#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 - grub_printf ("GRUB doesn't know how to reboot this machine yet!\n"); -} +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index b8cab9d24..584955449 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -27,16 +27,9 @@ void grub_multiboot2_real_boot (grub_addr_t entry, struct multiboot_info *mbi) __attribute__ ((noreturn)); -extern grub_addr_t grub_multiboot_payload_orig; +extern grub_uint32_t grub_multiboot_payload_eip; +extern char *grub_multiboot_payload_orig; extern grub_addr_t grub_multiboot_payload_dest; extern grub_size_t grub_multiboot_payload_size; -extern grub_uint32_t grub_multiboot_payload_entry_offset; - -extern grub_uint8_t grub_multiboot_forward_relocator; -extern grub_uint8_t grub_multiboot_forward_relocator_end; -extern grub_uint8_t grub_multiboot_backward_relocator; -extern grub_uint8_t grub_multiboot_backward_relocator_end; - -#define RELOCATOR_SIZEOF(x) (&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator) #endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h index 0029959ae..2be80e773 100644 --- a/include/grub/i386/pc/init.h +++ b/include/grub/i386/pc/init.h @@ -39,13 +39,6 @@ grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry * /* Turn on/off Gate A20. */ void grub_gate_a20 (int on); -/* Reboot the machine. */ -void EXPORT_FUNC (grub_reboot) (void); - -/* Halt the system, using APM if possible. If NO_APM is true, don't - * use APM even if it is available. */ -void EXPORT_FUNC (grub_halt) (int no_apm); - void EXPORT_FUNC(grub_stop_floppy) (void); #endif /* ! GRUB_INIT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 4ce3a6283..e14cc3e96 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -27,6 +27,8 @@ #include #endif +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -62,9 +64,6 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 -/* The flag for protected mode. */ -#define GRUB_MEMORY_MACHINE_CR0_PE_ON 0x1 - /* The code segment of the protected mode. */ #define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 @@ -86,7 +85,7 @@ struct grub_machine_bios_data_area { grub_uint8_t unused1[0x17]; - grub_uint8_t keyboard_flag_lower; /* 0x17 */ + grub_uint8_t keyboard_flag_lower; /* 0x17 */ grub_uint8_t unused2[0xf0 - 0x18]; }; diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index 996f64245..5b5f5f0df 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -67,4 +67,20 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); } +static inline void * +grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), + grub_addr_t base, + grub_size_t size __attribute__ ((unused))) +{ + return (void *) base; +} + +static inline void +grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), + void *mem __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + + #endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/i386/reboot.h b/include/grub/i386/reboot.h deleted file mode 100644 index 5bcbb5d64..000000000 --- a/include/grub/i386/reboot.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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 . - */ - -extern void grub_reboot (void); diff --git a/include/grub/i386/halt.h b/include/grub/i386/relocator.h similarity index 51% rename from include/grub/i386/halt.h rename to include/grub/i386/relocator.h index 1c403a7d5..ef7fe23aa 100644 --- a/include/grub/i386/halt.h +++ b/include/grub/i386/relocator.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,4 +16,26 @@ * along with GRUB. If not, see . */ -extern void grub_halt (void); +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +#include +#include + +struct grub_relocator32_state +{ + grub_uint32_t esp; + grub_uint32_t eax; + grub_uint32_t ebx; + grub_uint32_t ecx; + grub_uint32_t edx; + grub_uint32_t eip; +}; + +void *grub_relocator32_alloc (grub_size_t size); +grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state); +void *grub_relocator32_realloc (void *relocator, grub_size_t size); +void grub_relocator32_free (void *relocator); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 68674e605..3be2c3bcc 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -20,6 +20,10 @@ #define GRUB_CPU_XNU_H 1 #include +#include +#include + +#define XNU_RELOCATOR(x) (grub_relocator32_ ## x) #define GRUB_XNU_PAGESIZE 4096 typedef grub_uint32_t grub_xnu_ptr_t; @@ -64,17 +68,54 @@ struct grub_xnu_boot_params /* Size of grub_efi_uintn_t in bits. */ grub_uint8_t efi_uintnbits; } __attribute__ ((packed)); -#define GRUB_XNU_BOOTARGS_VERMINOR 4 +#define GRUB_XNU_BOOTARGS_VERMINOR 5 #define GRUB_XNU_BOOTARGS_VERMAJOR 1 +struct grub_xnu_devprop_header +{ + grub_uint32_t length; + /* Always set to 1. Version? */ + grub_uint32_t alwaysone; + grub_uint32_t num_devices; +}; + +struct grub_xnu_devprop_device_header +{ + grub_uint32_t length; + grub_uint32_t num_values; +}; + +void grub_cpu_xnu_unload (void); + +struct grub_xnu_devprop_device_descriptor; + +struct grub_xnu_devprop_device_descriptor * +grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length); +grub_err_t +grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev); +grub_err_t +grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, + char *name); +grub_err_t +grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name, void *data, int datalen); +grub_err_t +grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint16_t *name, int namelen, + void *data, int datalen); +grub_err_t +grub_xnu_devprop_remove_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name); +void grub_cpu_xnu_init (void); +void grub_cpu_xnu_fini (void); + extern grub_uint32_t grub_xnu_entry_point; extern grub_uint32_t grub_xnu_stack; extern grub_uint32_t grub_xnu_arg1; extern char grub_xnu_cmdline[1024]; grub_err_t grub_xnu_boot (void); -grub_err_t grub_cpu_xnu_fill_devicetree (void); grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc); +grub_err_t +grub_cpu_xnu_fill_devicetree (void); extern grub_uint32_t grub_xnu_heap_will_be_at; -extern grub_uint8_t grub_xnu_launcher_start[]; -extern grub_uint8_t grub_xnu_launcher_end[]; #endif diff --git a/include/grub/macho.h b/include/grub/macho.h index 0604100e9..82145835f 100644 --- a/include/grub/macho.h +++ b/include/grub/macho.h @@ -102,6 +102,23 @@ struct grub_macho_segment32 grub_uint32_t flags; } __attribute__ ((packed)); +/* 64-bit segment command. */ +struct grub_macho_segment64 +{ +#define GRUB_MACHO_CMD_SEGMENT64 0x19 + grub_uint32_t cmd; + grub_uint32_t cmdsize; + grub_uint8_t segname[16]; + grub_uint64_t vmaddr; + grub_uint64_t vmsize; + grub_uint64_t fileoff; + grub_uint64_t filesize; + grub_macho_vmprot_t maxprot; + grub_macho_vmprot_t initprot; + grub_uint32_t nsects; + grub_uint32_t flags; +} __attribute__ ((packed)); + #define GRUB_MACHO_CMD_THREAD 5 #endif diff --git a/include/grub/machoload.h b/include/grub/machoload.h index a80bac68c..8410162fb 100644 --- a/include/grub/machoload.h +++ b/include/grub/machoload.h @@ -46,17 +46,28 @@ grub_macho_t grub_macho_file (grub_file_t); grub_err_t grub_macho_close (grub_macho_t); int grub_macho_contains_macho32 (grub_macho_t); -grub_err_t grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start, - grub_addr_t *segments_end, int flags); -grub_uint32_t grub_macho32_get_entry_point (grub_macho_t macho); +grub_err_t grub_macho_size32 (grub_macho_t macho, grub_uint32_t *segments_start, + grub_uint32_t *segments_end, int flags); +grub_uint32_t grub_macho_get_entry_point32 (grub_macho_t macho); + +int grub_macho_contains_macho64 (grub_macho_t); +grub_err_t grub_macho_size64 (grub_macho_t macho, grub_uint64_t *segments_start, + grub_uint64_t *segments_end, int flags); +grub_uint64_t grub_macho_get_entry_point64 (grub_macho_t macho); /* Ignore BSS segments when loading. */ #define GRUB_MACHO_NOBSS 0x1 -grub_err_t grub_macho32_load (grub_macho_t macho, char *offset, int flags); +grub_err_t grub_macho_load32 (grub_macho_t macho, char *offset, int flags); +grub_err_t grub_macho_load64 (grub_macho_t macho, char *offset, int flags); /* Like filesize and file_read but take only 32-bit part for current architecture. */ -grub_size_t grub_macho32_filesize (grub_macho_t macho); -grub_err_t grub_macho32_readfile (grub_macho_t macho, void *dest); +grub_size_t grub_macho_filesize32 (grub_macho_t macho); +grub_err_t grub_macho_readfile32 (grub_macho_t macho, void *dest); +grub_size_t grub_macho_filesize64 (grub_macho_t macho); +grub_err_t grub_macho_readfile64 (grub_macho_t macho, void *dest); + +void grub_macho_parse32 (grub_macho_t macho); +void grub_macho_parse64 (grub_macho_t macho); #endif /* ! GRUB_MACHOLOAD_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h index 3fd4f7dd5..786ea5c4f 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -220,6 +220,9 @@ char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n); void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int EXPORT_FUNC(grub_puts) (const char *s); +int EXPORT_FUNC(grub_puts_) (const char *s); void EXPORT_FUNC(grub_real_dprintf) (const char *file, const int line, const char *condition, @@ -229,9 +232,6 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ (( int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); -grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest, - grub_uint16_t *src, - grub_size_t size); grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, grub_size_t destsize, const grub_uint8_t *src, @@ -271,4 +271,15 @@ grub_div_roundup (unsigned int x, unsigned int y) return (x + y - 1) / y; } +/* Reboot the machine. */ +void EXPORT_FUNC (grub_reboot) (void); + +#ifdef GRUB_MACHINE_PCBIOS +/* Halt the system, using APM if possible. If NO_APM is true, don't + * use APM even if it is available. */ +void EXPORT_FUNC (grub_halt) (int no_apm); +#else +void EXPORT_FUNC (grub_halt) (void); +#endif + #endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/normal.h b/include/grub/normal.h index feebc85b1..e55553de5 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -30,6 +30,9 @@ /* The maximum size of a command-line. */ #define GRUB_MAX_CMDLINE 1600 +/* The standard left and right margin for some messages. */ +#define STANDARD_MARGIN 6 + /* The type of a completion item. */ enum grub_completion_type { @@ -73,6 +76,14 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); /* Defined in `menu_text.c'. */ void grub_wait_after_message (void); +int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, + grub_uint32_t **last_position); +void grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position); +grub_ssize_t grub_getstringwidth (grub_uint32_t * str, + const grub_uint32_t * last_position); +void grub_print_message_indented (const char *msg, int margin_left, + int margin_right); /* Defined in `handler.c'. */ void read_handler_list (void); diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index 6482e964b..6f9d4ad6e 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -73,6 +73,7 @@ #define MAX_IDX (16384 >> BLK_SHR) #define COM_LEN 4096 +#define COM_LOG_LEN 12 #define COM_SEC (COM_LEN >> BLK_SHR) #define AF_ALST 1 @@ -164,7 +165,7 @@ struct grub_ntfs_comp struct grub_ntfs_rlst { int flags; - grub_uint32_t target_vcn, curr_vcn, next_vcn, curr_lcn; + grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn; char *cur_run; struct grub_ntfs_attr *attr; struct grub_ntfs_comp comp; diff --git a/include/grub/pci.h b/include/grub/pci.h index 7c8b50528..2bea05410 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,15 +36,44 @@ #define GRUB_PCI_ADDR_IO_MASK ~0x03 typedef grub_uint32_t grub_pci_id_t; -typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t) - (int bus, int device, int func, grub_pci_id_t pciid); -typedef grub_uint32_t grub_pci_address_t; -grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device, - int function, int reg); +#ifdef GRUB_UTIL +#include +#else +typedef grub_uint32_t grub_pci_address_t; +struct grub_pci_device +{ + int bus; + int device; + int function; +}; +typedef struct grub_pci_device grub_pci_device_t; +static inline int +grub_pci_get_bus (grub_pci_device_t dev) +{ + return dev.bus; +} + +static inline int +grub_pci_get_device (grub_pci_device_t dev) +{ + return dev.device; +} + +static inline int +grub_pci_get_function (grub_pci_device_t dev) +{ + return dev.function; +} +#include +#endif + +typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t) + (grub_pci_device_t dev, grub_pci_id_t pciid); + +grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, + int reg); void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); -#include - #endif /* GRUB_PCI_H */ diff --git a/include/grub/pciutils.h b/include/grub/pciutils.h new file mode 100644 index 000000000..36d47e5c8 --- /dev/null +++ b/include/grub/pciutils.h @@ -0,0 +1,103 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PCIUTILS_H +#define GRUB_PCIUTILS_H 1 + +#include + +typedef struct pci_device *grub_pci_device_t; + +static inline int +grub_pci_get_bus (grub_pci_device_t dev) +{ + return dev->bus; +} + +static inline int +grub_pci_get_device (grub_pci_device_t dev) +{ + return dev->dev; +} + +static inline int +grub_pci_get_function (grub_pci_device_t dev) +{ + return dev->func; +} + +struct grub_pci_address +{ + grub_pci_device_t dev; + int pos; +}; + +typedef struct grub_pci_address grub_pci_address_t; + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + grub_uint32_t ret; + pci_device_cfg_read_u32 (addr.dev, &ret, addr.pos); + return ret; +} + +static inline grub_uint16_t +grub_pci_read_word (grub_pci_address_t addr) +{ + grub_uint16_t ret; + pci_device_cfg_read_u16 (addr.dev, &ret, addr.pos); + return ret; +} + +static inline grub_uint8_t +grub_pci_read_byte (grub_pci_address_t addr) +{ + grub_uint8_t ret; + pci_device_cfg_read_u8 (addr.dev, &ret, addr.pos); + return ret; +} + +static inline void +grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) +{ + pci_device_cfg_write_u32 (addr.dev, data, addr.pos); +} + +static inline void +grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) +{ + pci_device_cfg_write_u16 (addr.dev, data, addr.pos); +} + +static inline void +grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) +{ + pci_device_cfg_write_u8 (addr.dev, data, addr.pos); +} + +void * +grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base, + grub_size_t size); + +void +grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem, + grub_size_t size); + + +#endif /* GRUB_PCIUTILS_H */ diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index 917e1548f..a76c2a4df 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -23,9 +23,6 @@ #ifndef ASM_FILE -void EXPORT_FUNC (grub_reboot) (void); -void EXPORT_FUNC (grub_halt) (void); - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 03a631492..e63e1f616 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -54,9 +54,6 @@ extern grub_int32_t grub_total_module_size; configuration file are located. */ extern char grub_prefix[]; -void EXPORT_FUNC (grub_reboot) (void); -void EXPORT_FUNC (grub_halt) (void); - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/types.h b/include/grub/types.h index 8e2ad15ef..5f6b7ec62 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -22,8 +22,6 @@ #include #include -#define UNUSED __attribute__ ((unused)) - #ifdef GRUB_UTIL # define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P # define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG diff --git a/include/grub/usb.h b/include/grub/usb.h index 8dd3b6e2e..dc90e7879 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -64,9 +64,6 @@ grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint); grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, int configuration); -grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, - int langid, char **string); - void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb); void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb); diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index d0184d416..09108547c 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -57,12 +58,20 @@ void grub_util_write_image (const char *img, size_t size, FILE *out); void grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out); +#ifndef HAVE_VASPRINTF + +int vasprintf (char **buf, const char *fmt, va_list ap); + +#endif + #ifndef HAVE_ASPRINTF int asprintf (char **buf, const char *fmt, ...); #endif +char *xasprintf (const char *fmt, ...); + #ifdef __MINGW32__ #define fseeko fseeko64 diff --git a/include/grub/x86_64/relocator.h b/include/grub/x86_64/relocator.h new file mode 100644 index 000000000..247e7a18b --- /dev/null +++ b/include/grub/x86_64/relocator.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/xnu.h b/include/grub/xnu.h index b058bd1b9..6089aad34 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -76,6 +76,8 @@ struct grub_xnu_extheader grub_uint32_t infoplistsize; grub_uint32_t binaryaddr; grub_uint32_t binarysize; + grub_uint32_t nameaddr; + grub_uint32_t namesize; } __attribute__ ((packed)); struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent, @@ -92,6 +94,7 @@ struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key void grub_xnu_lock (void); void grub_xnu_unlock (void); grub_err_t grub_xnu_resume (char *imagename); +grub_err_t grub_xnu_boot_resume (void); struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name); grub_err_t grub_xnu_align_heap (int align); @@ -100,11 +103,13 @@ grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, int maxrecursion); void *grub_xnu_heap_malloc (int size); +grub_err_t grub_xnu_fill_devicetree (void); extern grub_uint32_t grub_xnu_heap_real_start; extern grub_size_t grub_xnu_heap_size; -extern char *grub_xnu_heap_start; +extern void *grub_xnu_heap_start; extern struct grub_video_bitmap *grub_xnu_bitmap; typedef enum {GRUB_XNU_BITMAP_CENTER, GRUB_XNU_BITMAP_STRETCH} grub_xnu_bitmap_mode_t; extern grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode; +extern int grub_xnu_is_64bit; #endif diff --git a/kern/device.c b/kern/device.c index 83ae3dcc8..9f219949b 100644 --- a/kern/device.c +++ b/kern/device.c @@ -109,6 +109,8 @@ grub_device_iterate (int (*hook) (const char *name)) (void) grub_partition_iterate (dev->disk, iterate_partition); grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + p = ents; while (p != NULL) { diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 8e09a90c0..501ab4578 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -188,6 +189,25 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key) return status == GRUB_EFI_SUCCESS; } +grub_err_t +grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_efi_runtime_services_t *r; + grub_efi_status_t status; + + r = grub_efi_system_table->runtime_services; + status = efi_call_4 (r->set_virtual_address_map, memory_map_size, + descriptor_size, descriptor_version, virtual_map); + + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); +} + grub_uint32_t grub_get_rtc (void) { diff --git a/kern/elf.c b/kern/elf.c index f14161060..951049e73 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -181,7 +181,9 @@ grub_elf32_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf32_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) @@ -360,7 +362,9 @@ grub_elf64_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf64_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) diff --git a/kern/env.c b/kern/env.c index 750902af8..969227dec 100644 --- a/kern/env.c +++ b/kern/env.c @@ -101,6 +101,7 @@ grub_env_context_open (int export) grub_env_context_close (); return grub_errno; } + grub_env_export (var->name); grub_register_variable_hook (var->name, var->read_hook, var->write_hook); } } @@ -170,8 +171,16 @@ grub_env_export (const char *name) struct grub_env_var *var; var = grub_env_find (name); - if (var) - var->type = GRUB_ENV_VAR_GLOBAL; + if (! var) + { + grub_err_t err; + + err = grub_env_set (name, ""); + if (err) + return err; + var = grub_env_find (name); + } + var->type = GRUB_ENV_VAR_GLOBAL; return GRUB_ERR_NONE; } diff --git a/kern/i386/halt.c b/kern/i386/halt.c index 2f0043539..10805e42b 100644 --- a/kern/i386/halt.c +++ b/kern/i386/halt.c @@ -17,7 +17,6 @@ */ #include -#include #include #include diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index da3624c89..4de14a3d1 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -146,6 +146,9 @@ multiboot_entry: /* obtain the boot device */ movl 12(%ebx), %edx + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp + movl %ebp, %esp + /* relocate the code */ movl $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx addl EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx @@ -484,21 +487,6 @@ FUNCTION(grub_exit) jmp cold_reboot .code32 -/* - * grub_reboot() - * - * Reboot the system. At the moment, rely on BIOS. - */ -FUNCTION(grub_reboot) - call prot_to_real - .code16 -cold_reboot: - /* cold boot */ - movw $0x0472, %di - movw %ax, (%di) - ljmp $0xFFFF, $0x0000 - .code32 - /* * grub_halt(int no_apm) * diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S index 0be5ae84f..7484650b2 100644 --- a/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -81,7 +81,7 @@ codestart: movl $END_SYMBOL, %ecx subl %edi, %ecx #endif - + /* clean out */ xorl %eax, %eax cld @@ -95,3 +95,5 @@ codestart: /* This should never happen. */ jmp EXT_C(grub_stop) + +#include "../realmode.S" diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S index 11f4d5347..a74eb1217 100644 --- a/kern/i386/realmode.S +++ b/kern/i386/realmode.S @@ -127,7 +127,7 @@ real_to_prot: /* turn on protected mode */ movl %cr0, %eax - orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + orl $GRUB_MEMORY_CPU_CR0_PE_ON, %eax movl %eax, %cr0 /* jump to relocation, flush prefetch queue, and reload %cs */ @@ -196,7 +196,7 @@ tmpcseg: /* clear the PE bit of CR0 */ movl %cr0, %eax - andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax + andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax movl %eax, %cr0 /* flush prefetch queue, reload %cs */ @@ -215,10 +215,27 @@ realcseg: movw %ax, %gs movw %ax, %ss +#ifdef GRUB_MACHINE_PCBIOS /* restore interrupts */ sti +#endif /* return on new stack! */ DATA32 ret .code32 + +/* + * grub_reboot() + * + * Reboot the system. At the moment, rely on BIOS. + */ +FUNCTION(grub_reboot) + call prot_to_real + .code16 +cold_reboot: + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 + .code32 diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 20ef730e0..9a2b0c9aa 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -1,7 +1,7 @@ /* openfw.c -- Open firmware support functions. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -399,11 +399,14 @@ grub_ieee1275_encode_devname (const char *path) return encoding; } +/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ +#ifndef __i386__ void grub_reboot (void) { grub_ieee1275_interpret ("reset-all", 0); } +#endif void grub_halt (void) diff --git a/kern/misc.c b/kern/misc.c index 06b068e69..7a62386d1 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -126,6 +126,38 @@ grub_printf (const char *fmt, ...) return ret; } +int +grub_printf_ (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_vprintf (_(fmt), ap); + va_end (ap); + + return ret; +} + +int +grub_puts (const char *s) +{ + while (*s) + { + grub_putchar (*s); + s++; + } + grub_putchar ('\n'); + + return 1; /* Cannot fail. */ +} + +int +grub_puts_ (const char *s) +{ + return grub_puts (_(s)); +} + #if defined (APPLE_CC) && ! defined (GRUB_UTIL) int grub_err_printf (const char *fmt, ...) @@ -843,68 +875,6 @@ grub_sprintf (char *str, const char *fmt, ...) return ret; } -/* Convert UTF-16 to UTF-8. */ -grub_uint8_t * -grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, - grub_size_t size) -{ - grub_uint32_t code_high = 0; - - while (size--) - { - grub_uint32_t code = *src++; - - if (code_high) - { - if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Surrogate pair. */ - code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; - - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - else - { - /* Error... */ - *dest++ = '?'; - } - - code_high = 0; - } - else - { - if (code <= 0x007F) - *dest++ = code; - else if (code <= 0x07FF) - { - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - } - else if (code >= 0xD800 && code <= 0xDBFF) - { - code_high = code; - continue; - } - else if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Error... */ - *dest++ = '?'; - } - else - { - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - } - } - - return dest; -} - /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string. Return the number of characters converted. DEST must be able to hold diff --git a/kern/parser.c b/kern/parser.c index db59af056..006d67da7 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -142,7 +142,7 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, *(bp++) = *val; } - *argc = 1; + *argc = 0; do { if (! *rd) @@ -188,12 +188,16 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, state = newstate; } } while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); - *(bp++) = '\0'; /* A special case for when the last character was part of a variable. */ add_var (GRUB_PARSER_STATE_TEXT); + if (bp != buffer && *(bp - 1)) + { + *(bp++) = '\0'; + (*argc)++; + } /* Reserve memory for the return values. */ args = grub_malloc (bp - buffer); @@ -219,8 +223,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, bp++; } - (*argc)--; - return 0; } diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c index 1e0841e49..d3725e739 100644 --- a/kern/rescue_parser.c +++ b/kern/rescue_parser.c @@ -35,9 +35,12 @@ grub_rescue_parse_line (char *line, grub_reader_getline_t getline) if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) return grub_errno; + if (n == 0) + return GRUB_ERR_NONE; + /* In case of an assignment set the environment accordingly instead of calling a function. */ - if (n == 0 && grub_strchr (line, '=')) + if (n == 1 && grub_strchr (line, '=')) { char *val = grub_strchr (args[0], '='); val[0] = 0; @@ -56,7 +59,7 @@ grub_rescue_parse_line (char *line, grub_reader_getline_t getline) cmd = grub_command_find (name); if (cmd) { - (cmd->func) (cmd, n, &args[1]); + (cmd->func) (cmd, n - 1, &args[1]); } else { diff --git a/lib/arg.c b/lib/arg.c index ed37986b6..6da9bb5dd 100644 --- a/lib/arg.c +++ b/lib/arg.c @@ -30,9 +30,9 @@ static const struct grub_arg_option help_options[] = { {"help", SHORT_ARG_HELP, 0, - "display this help and exit", 0, ARG_TYPE_NONE}, + "Display this help and exit.", 0, ARG_TYPE_NONE}, {"usage", SHORT_ARG_USAGE, 0, - "display the usage of this command and exit", 0, ARG_TYPE_NONE}, + "Display the usage of this command and exit.", 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -355,7 +355,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, { char *tail; - grub_strtoul (option, &tail, 0); + grub_strtoull (option, &tail, 0); if (tail == 0 || tail == option || *tail != '\0' || grub_errno) { grub_error (GRUB_ERR_BAD_ARGUMENT, diff --git a/lib/charset.c b/lib/charset.c new file mode 100644 index 000000000..8bc5b9149 --- /dev/null +++ b/lib/charset.c @@ -0,0 +1,116 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE + bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string. + Return the number of characters converted. DEST must be able to hold + at least DESTSIZE characters. If an invalid sequence is found, return -1. + If SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ + +#include + +grub_ssize_t +grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend) +{ + grub_uint16_t *p = dest; + int count = 0; + grub_uint32_t code = 0; + + if (srcend) + *srcend = src; + + while (srcsize && destsize) + { + grub_uint32_t c = *src++; + if (srcsize != (grub_size_t)-1) + srcsize--; + if (count) + { + if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) + { + /* invalid */ + return -1; + } + else + { + code <<= 6; + code |= (c & GRUB_UINT8_6_TRAILINGBITS); + count--; + } + } + else + { + if (c == 0) + break; + + if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) + code = c; + else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) + { + count = 1; + code = c & GRUB_UINT8_5_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) + { + count = 2; + code = c & GRUB_UINT8_4_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) + { + count = 3; + code = c & GRUB_UINT8_3_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS) + { + count = 4; + code = c & GRUB_UINT8_2_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS) + { + count = 5; + code = c & GRUB_UINT8_1_TRAILINGBIT; + } + else + return -1; + } + + if (count == 0) + { + if (destsize < 2 && code >= GRUB_UCS2_LIMIT) + break; + if (code >= GRUB_UCS2_LIMIT) + { + *p++ = GRUB_UTF16_UPPER_SURROGATE (code); + *p++ = GRUB_UTF16_LOWER_SURROGATE (code); + destsize -= 2; + } + else + { + *p++ = code; + destsize--; + } + } + } + + if (srcend) + *srcend = src; + return p - dest; +} diff --git a/lib/i386/pc/biosnum.c b/lib/i386/pc/biosnum.c index 1f9b5f3fc..058c9d331 100644 --- a/lib/i386/pc/biosnum.c +++ b/lib/i386/pc/biosnum.c @@ -33,7 +33,7 @@ grub_get_root_biosnumber_default (void) return grub_strtoul (biosnum, 0, 0); dev = grub_device_open (0); - if (dev && dev->disk && dev->disk->dev + if (dev && dev->disk && dev->disk->dev && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) ret = (int) dev->disk->id; diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c new file mode 100644 index 000000000..453f73fdd --- /dev/null +++ b/lib/i386/relocator.c @@ -0,0 +1,102 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +extern grub_uint32_t grub_relocator32_backward_dest; +extern grub_uint32_t grub_relocator32_backward_size; +extern grub_addr_t grub_relocator32_backward_src; + +extern grub_uint32_t grub_relocator32_forward_dest; +extern grub_uint32_t grub_relocator32_forward_size; +extern grub_addr_t grub_relocator32_forward_src; + +extern grub_uint32_t grub_relocator32_forward_eax; +extern grub_uint32_t grub_relocator32_forward_ebx; +extern grub_uint32_t grub_relocator32_forward_ecx; +extern grub_uint32_t grub_relocator32_forward_edx; +extern grub_uint32_t grub_relocator32_forward_eip; +extern grub_uint32_t grub_relocator32_forward_esp; + +extern grub_uint32_t grub_relocator32_backward_eax; +extern grub_uint32_t grub_relocator32_backward_ebx; +extern grub_uint32_t grub_relocator32_backward_ecx; +extern grub_uint32_t grub_relocator32_backward_edx; +extern grub_uint32_t grub_relocator32_backward_eip; +extern grub_uint32_t grub_relocator32_backward_esp; + +#define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start) +#define RELOCATOR_ALIGN 16 +#define PREFIX(x) grub_relocator32_ ## x + +static void +write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + grub_relocator32_backward_dest = dest; + grub_relocator32_backward_src = PTR_TO_UINT64 (src); + grub_relocator32_backward_size = size; + + grub_relocator32_backward_eax = state.eax; + grub_relocator32_backward_ebx = state.ebx; + grub_relocator32_backward_ecx = state.ecx; + grub_relocator32_backward_edx = state.edx; + grub_relocator32_backward_eip = state.eip; + grub_relocator32_backward_esp = state.esp; + + grub_memmove (ptr, + &grub_relocator32_backward_start, + RELOCATOR_SIZEOF (backward)); + ((void (*) (void)) ptr) (); +} + +static void +write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + + grub_relocator32_forward_dest = dest; + grub_relocator32_forward_src = PTR_TO_UINT64 (src); + grub_relocator32_forward_size = size; + + grub_relocator32_forward_eax = state.eax; + grub_relocator32_forward_ebx = state.ebx; + grub_relocator32_forward_ecx = state.ecx; + grub_relocator32_forward_edx = state.edx; + grub_relocator32_forward_eip = state.eip; + grub_relocator32_forward_esp = state.esp; + + grub_memmove (ptr, + &grub_relocator32_forward_start, + RELOCATOR_SIZEOF (forward)); + ((void (*) (void)) ptr) (); +} + +#include "../relocator.c" diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S new file mode 100644 index 000000000..6b803db13 --- /dev/null +++ b/lib/i386/relocator_asm.S @@ -0,0 +1,248 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#ifdef BACKWARD +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) +#else +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) +#endif +#ifdef __x86_64__ +#define RAX %rax +#define RCX %rcx +#define RDI %rdi +#define RSI %rdi +#else +#define RAX %eax +#define RCX %ecx +#define RDI %edi +#define RSI %esi +#endif + +/* The code segment of the protected mode. */ +#define CODE_SEGMENT 0x10 + +/* The data segment of the protected mode. */ +#define DATA_SEGMENT 0x18 + + .p2align 4 /* force 16-byte alignment */ + +RELOCATOR_VARIABLE(start) +#ifdef BACKWARD +LOCAL(base): +#endif + cli + +#ifndef __x86_64__ + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + movl %eax, %edi + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0 + movl %eax, %esi + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 +#else + xorq %rax, %rax + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + movq %rax, %rdi + + /* mov imm64, %rax */ + .byte 0x48 + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0, 0 + movq %rax, %rsi + + xorq %rcx, %rcx + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 + +#endif + + mov RDI, RAX + +#ifdef BACKWARD + add RCX, RSI + add RCX, RDI +#endif + +#ifndef BACKWARD + add RCX, RAX +#endif + add $0x3, RCX + shr $2, RCX + + +#ifdef BACKWARD + /* Backward movsl is implicitly off-by-four. compensate that. */ + sub $4, RSI + sub $4, RDI + + /* Backward copy. */ + std + + rep + movsl + +#else + /* Forward copy. */ + cld + rep + movsl +#endif + + /* %rax contains now our new 'base'. */ + mov RAX, RSI + add $(LOCAL(cont0) - LOCAL(base)), RAX + jmp *RAX +LOCAL(cont0): + lea (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX + movl %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) + + lea (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX + mov RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1) + + /* Switch to compatibility mode. */ + + lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1) + + /* Update %cs. */ + ljmp *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) + +LOCAL(cont1): + .code32 + + /* Update other registers. */ + movl $DATA_SEGMENT, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + movl %eax, %ss + + /* Disable paging. */ + movl %cr0, %eax + andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax + movl %eax, %cr0 + + /* Disable amd64. */ + movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx + rdmsr + andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax + wrmsr + + /* Turn off PAE. */ + movl %cr4, %eax + andl $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax + movl %eax, %cr4 + + jmp LOCAL(cont2) +LOCAL(cont2): + .code32 + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (esp) + .long 0 + + movl %eax, %esp + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (eax) + .long 0 + + /* mov imm32, %ebx */ + .byte 0xbb +RELOCATOR_VARIABLE (ebx) + .long 0 + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE (ecx) + .long 0 + + /* mov imm32, %edx */ + .byte 0xba +RELOCATOR_VARIABLE (edx) + .long 0 + + /* Cleared direction flag is of no problem with any current + payload and makes this implementation easier. */ + cld + + .byte 0xea +RELOCATOR_VARIABLE (eip) + .long 0 + .word CODE_SEGMENT + + /* GDT. Copied from loader/i386/linux.c. */ + .p2align 4 +LOCAL(gdt): + /* NULL. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Reserved. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Code segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 + + /* Data segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + + .p2align 4 +LOCAL(gdtdesc): + .word 0x27 +LOCAL(gdt_addr): +#ifdef __x86_64__ + /* Filled by the code. */ + .quad 0 +#else + /* Filled by the code. */ + .long 0 +#endif + + .p2align 4 +LOCAL(jump_vector): + /* Jump location. Is filled by the code */ + .long 0 + .long CODE_SEGMENT + +#ifndef BACKWARD +LOCAL(base): +#endif + +RELOCATOR_VARIABLE(end) diff --git a/lib/i386/relocator_backward.S b/lib/i386/relocator_backward.S new file mode 100644 index 000000000..06913470e --- /dev/null +++ b/lib/i386/relocator_backward.S @@ -0,0 +1,2 @@ +#define BACKWARD +#include "relocator_asm.S" diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c new file mode 100644 index 000000000..796473bf7 --- /dev/null +++ b/lib/mips/relocator.c @@ -0,0 +1,109 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include +#include + +#include + +/* Remark: doesn't work with source outside of 4G. + Use relocator64 in this case. + */ + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (sizeof (grub_uint32_t)) + +#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \ + - &grub_relocator32_##x##_start) +#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ + + REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF) +#define RELOCATOR_ALIGN 16 + +#define PREFIX(x) grub_relocator32_ ## x + +static void +write_reg (int regn, grub_uint32_t val, void **target) +{ + /* lui $r, (val+0x8000). */ + *(grub_uint32_t *) *target = ((0x3c00 | regn) << 16) | ((val + 0x8000) >> 16); + *target = ((grub_uint32_t *) *target) + 1; + /* addiu $r, $r, val. */ + *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16) + | (val & 0xffff)); + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_jump (int regn, void **target) +{ + /* j $r. */ + *(grub_uint32_t *) *target = (regn<<21) | 0x8; + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_backward_start, + RELOCATOR_SRC_SIZEOF (backward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); + grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0); + ((void (*) (void)) ptr0) (); +} + +static void +write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_forward_start, + RELOCATOR_SRC_SIZEOF (forward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); + grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0); + ((void (*) (void)) ptr0) (); +} + +#include "../relocator.c" diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S new file mode 100644 index 000000000..9daf0d32f --- /dev/null +++ b/lib/mips/relocator_asm.S @@ -0,0 +1,93 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .p2align 4 /* force 16-byte alignment */ + +VARIABLE (grub_relocator32_forward_start) + move $12, $9 + move $13, $10 + +copycont1: + lb $11,0($8) + sb $11,0($9) + addiu $8, $8, 0x1 + addiu $9, $9, 0x1 + addiu $10, $10, 0xffff + bne $10, $0, copycont1 + + move $9, $12 + move $10, $13 +cachecont1a: + cache 1,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont1a + + sync + + move $12, $9 + move $13, $10 +cachecont1b: + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont1b + + sync + +VARIABLE (grub_relocator32_forward_end) + +VARIABLE (grub_relocator32_backward_start) + move $12, $9 + move $13, $10 + + addu $9, $9, $10 + addu $8, $8, $10 + /* Backward movsl is implicitly off-by-one. compensate that. */ + addiu $9, $9, 0xffff + addiu $8, $8, 0xffff +copycont2: + lb $11,0($8) + sb $11,0($9) + addiu $8, $8, 0xffff + addiu $9, $9, 0xffff + addiu $10, 0xffff + bne $10, $0, copycont2 + + move $9, $12 + move $10, $13 +cachecont2a: + cache 1,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont2a + + sync + + move $12, $9 + move $13, $10 +cachecont2b: + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont2b + + sync +VARIABLE (grub_relocator32_backward_end) diff --git a/lib/relocator.c b/lib/relocator.c new file mode 100644 index 000000000..6a5acc548 --- /dev/null +++ b/lib/relocator.c @@ -0,0 +1,137 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define MAX_OVERHEAD ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)) +#define PRE_REGION_SIZE (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) + +void * +PREFIX (alloc) (grub_size_t size) +{ + char *playground; + + playground = grub_malloc (size + MAX_OVERHEAD); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + PRE_REGION_SIZE; +} + +void * +PREFIX (realloc) (void *relocator, grub_size_t size) +{ + char *playground; + + if (!relocator) + return PREFIX (alloc) (size); + + playground = (char *) relocator - PRE_REGION_SIZE; + + playground = grub_realloc (playground, size + MAX_OVERHEAD); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + PRE_REGION_SIZE; +} + +void +PREFIX(free) (void *relocator) +{ + if (relocator) + grub_free ((char *) relocator - PRE_REGION_SIZE); +} + +grub_err_t +PREFIX (boot) (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state) +{ + grub_size_t size; + char *playground; + + playground = (char *) relocator - PRE_REGION_SIZE; + size = *(grub_size_t *) playground; + + grub_dprintf ("relocator", + "Relocator: source: %p, destination: 0x%x, size: 0x%lx\n", + relocator, (unsigned) dest, (unsigned long) size); + + /* Very unlikely condition: Relocator may risk overwrite itself. + Just move it a bit up. */ + if ((grub_addr_t) dest < (grub_addr_t) relocator + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) + && (grub_addr_t) dest + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + > (grub_addr_t) relocator) + { + void *relocator_new = ((grub_uint8_t *) relocator) + + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN); + grub_dprintf ("relocator", "Overwrite condition detected moving " + "relocator from %p to %p\n", relocator, relocator_new); + grub_memmove (relocator_new, relocator, + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + relocator = relocator_new; + } + + if ((grub_addr_t) dest >= (grub_addr_t) relocator) + { + int overhead; + overhead = dest - + ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, + RELOCATOR_ALIGN); + grub_dprintf ("relocator", + "Backward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%lx\n", + (char *) relocator - overhead, + (char *) relocator - overhead, + (unsigned) dest - overhead, + (unsigned long) size + overhead); + + write_call_relocator_bw ((char *) relocator - overhead, + (char *) relocator - overhead, + dest - overhead, size + overhead, state); + } + else + { + int overhead; + + overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + + RELOCATOR_SIZEOF (forward) - (dest + size); + grub_dprintf ("relocator", + "Forward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%lx\n", + (char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, (unsigned) dest, + (unsigned long) size + overhead); + + write_call_relocator_fw ((char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead, state); + } + + /* Not reached. */ + return GRUB_ERR_NONE; +} diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c index 01acc4135..9c833e9b9 100644 --- a/loader/efi/chainloader.c +++ b/loader/efi/chainloader.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 6f2202a67..84eb13d74 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -140,7 +140,7 @@ grub_bsd_get_device (grub_uint32_t * biosdev, grub_uint32_t * slice, grub_uint32_t * part) { char *p; - grub_device_t dev; + grub_device_t dev; #ifdef GRUB_MACHINE_PCBIOS *biosdev = grub_get_root_biosnumber () & 0xff; diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index f96c60e11..8cd4d23f2 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -469,21 +469,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 5085cdbea..236732804 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -71,21 +71,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index d1ea307d2..be824e2f4 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -48,18 +48,36 @@ #include #include #endif +#include extern grub_dl_t my_mod; static struct multiboot_info *mbi, *mbi_dest; -static grub_addr_t entry; -static char *playground = 0; static grub_size_t code_size; +char *grub_multiboot_payload_orig; +grub_addr_t grub_multiboot_payload_dest; +grub_size_t grub_multiboot_payload_size; +grub_uint32_t grub_multiboot_payload_eip; + static grub_err_t grub_multiboot_boot (void) { - grub_multiboot_real_boot (entry, mbi_dest); + struct grub_relocator32_state state = + { + .eax = MULTIBOOT_MAGIC2, + .ebx = PTR_TO_UINT32 (mbi_dest), + .ecx = 0, + .edx = 0, + .eip = grub_multiboot_payload_eip, + /* Set esp to some random location in low memory to avoid breaking + non-compliant kernels. */ + .esp = 0x7ff00 + }; + + grub_relocator32_boot (grub_multiboot_payload_orig, + grub_multiboot_payload_dest, + state); /* Not reached. */ return GRUB_ERR_NONE; @@ -68,7 +86,7 @@ grub_multiboot_boot (void) static grub_err_t grub_multiboot_unload (void) { - if (playground) + if (mbi) { unsigned int i; for (i = 0; i < mbi->mods_count; i++) @@ -79,11 +97,11 @@ grub_multiboot_unload (void) ((struct multiboot_mod_list *) mbi->mods_addr)[i].cmdline); } grub_free ((void *) mbi->mods_addr); - grub_free (playground); } + grub_relocator32_free (grub_multiboot_payload_orig); mbi = NULL; - playground = NULL; + grub_multiboot_payload_orig = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; @@ -183,7 +201,7 @@ grub_multiboot_get_bootdev (grub_uint32_t *bootdev) if (dev) grub_device_close (dev); - *bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) + *bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) | ((part & 0xff) << 8) | 0xff; return (biosdev != ~0UL); #else @@ -250,11 +268,8 @@ grub_multiboot (int argc, char *argv[]) goto fail; } - if (playground) - { - grub_free (playground); - playground = NULL; - } + grub_relocator32_free (grub_multiboot_payload_orig); + grub_multiboot_payload_orig = NULL; mmap_length = grub_get_multiboot_mmap_len (); @@ -296,13 +311,14 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_dest = header->load_addr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) + + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (! grub_multiboot_payload_orig) goto fail; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); - - if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) + if ((grub_file_seek (file, offset)) == (grub_off_t) -1) goto fail; grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); @@ -313,7 +329,7 @@ grub_multiboot (int argc, char *argv[]) grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, header->bss_end_addr - header->load_addr - load_size); - grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr; + grub_multiboot_payload_eip = header->entry_addr; } else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) @@ -334,23 +350,6 @@ grub_multiboot (int argc, char *argv[]) mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest); mbi->flags |= MULTIBOOT_INFO_MEM_MAP; - if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) - { - grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward)); - entry = (grub_addr_t) playground; - } - else - { - grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size), - &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward)); - entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size; - } - - grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n", - (void *) grub_multiboot_payload_dest, - grub_multiboot_payload_size, - grub_multiboot_payload_entry_offset); - /* Convert from bytes to kilobytes. */ mbi->mem_lower = grub_mmap_get_lower () / 1024; mbi->mem_upper = grub_mmap_get_upper () / 1024; diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 77c47118c..80db25144 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -32,6 +32,8 @@ #error "I'm confused" #endif +#include + #define CONCAT(a,b) CONCAT_(a, b) #define CONCAT_(a,b) a ## b @@ -99,11 +101,12 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) - return grub_errno; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (!grub_multiboot_payload_orig) + return grub_errno; /* Load every loadable segment in memory. */ for (i = 0; i < ehdr->e_phnum; i++) @@ -135,8 +138,8 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) { - grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr) - + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr); + grub_multiboot_payload_eip = grub_multiboot_payload_dest + + (ehdr->e_entry - phdr(i)->p_vaddr) + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr); break; } diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S index d1094588b..2f9af778b 100644 --- a/loader/i386/multiboot_helper.S +++ b/loader/i386/multiboot_helper.S @@ -22,81 +22,6 @@ .p2align 2 /* force 4-byte alignment */ -/* - * This starts the multiboot kernel. - */ - -VARIABLE(grub_multiboot_payload_size) - .long 0 -VARIABLE(grub_multiboot_payload_orig) - .long 0 -VARIABLE(grub_multiboot_payload_dest) - .long 0 -VARIABLE(grub_multiboot_payload_entry_offset) - .long 0 - -/* - * The relocators below understand the following parameters: - * ecx: Size of the block to be copied. - * esi: Where to copy from (always lowest address, even if we're relocating - * backwards). - * edi: Where to copy to (likewise). - * edx: Offset of the entry point (relative to the beginning of the block). - */ - -VARIABLE(grub_multiboot_forward_relocator) - /* Add entry offset. */ - addl %edi, %edx - - /* Forward copy. */ - cld - rep - movsb - - jmp *%edx -VARIABLE(grub_multiboot_forward_relocator_end) - -VARIABLE(grub_multiboot_backward_relocator) - /* Add entry offset (before %edi is mangled). */ - addl %edi, %edx - - /* Backward movsb is implicitly off-by-one. compensate that. */ - decl %esi - decl %edi - - /* Backward copy. */ - std - addl %ecx, %esi - addl %ecx, %edi - rep - movsb - - cld - jmp *%edx -VARIABLE(grub_multiboot_backward_relocator_end) - -FUNCTION(grub_multiboot_real_boot) - /* Push the entry address on the stack. */ - pushl %eax - /* Move the address of the multiboot information structure to ebx. */ - movl %edx,%ebx - - /* Interrupts should be disabled. */ - cli - - /* Where do we copy what from. */ - movl EXT_C(grub_multiboot_payload_size), %ecx - movl EXT_C(grub_multiboot_payload_orig), %esi - movl EXT_C(grub_multiboot_payload_dest), %edi - movl EXT_C(grub_multiboot_payload_entry_offset), %edx - - /* Move the magic value into eax. */ - movl $MULTIBOOT_MAGIC2, %eax - - /* Jump to the relocator. */ - popl %ebp - jmp *%ebp - /* * This starts the multiboot 2 kernel. */ diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c index caf1450e4..2e3b24fee 100644 --- a/loader/i386/pc/chainloader.c +++ b/loader/i386/pc/chainloader.c @@ -102,7 +102,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (dev) grub_device_close (dev); - + /* Ignore errors. Perhaps it's not fatal. */ grub_errno = GRUB_ERR_NONE; diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c index e2d649613..6ef8c70ca 100644 --- a/loader/i386/pc/multiboot2.c +++ b/loader/i386/pc/multiboot2.c @@ -27,7 +27,8 @@ #include grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf32_Addr paddr = phdr->p_paddr; @@ -48,7 +49,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, } grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf64_Addr paddr = phdr->p_paddr; @@ -82,7 +84,8 @@ grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) } grub_err_t -grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size) +grub_mb2_arch_module_free (grub_addr_t addr, + grub_size_t size __attribute__ ((unused))) { grub_free((void *) addr); return GRUB_ERR_NONE; diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 275b50dbc..4786bfd39 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -25,11 +25,17 @@ #include #include #include +#include #include #include +#include #include +#include +#include char grub_xnu_cmdline[1024]; +grub_uint32_t grub_xnu_heap_will_be_at; +grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack; /* Aliases set for some tables. */ struct tbl_alias @@ -44,20 +50,13 @@ struct tbl_alias table_aliases[] = {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, }; -/* The following function is used to be able to debug xnu loader - with grub-emu. */ -#ifdef GRUB_UTIL -static grub_err_t -grub_xnu_launch (void) +struct grub_xnu_devprop_device_descriptor { - grub_printf ("Fake launch %x:%p:%p", grub_xnu_entry_point, grub_xnu_arg1, - grub_xnu_stack); - grub_getkey (); - return 0; -} -#else -static void (*grub_xnu_launch) (void) = 0; -#endif + struct grub_xnu_devprop_device_descriptor *next; + struct property_descriptor *properties; + struct grub_efi_device_path *path; + int pathlen; +}; static int utf16_strlen (grub_uint16_t *in) @@ -205,6 +204,417 @@ guessfsb (void) ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0); } +struct property_descriptor +{ + struct property_descriptor *next; + grub_uint8_t *name; + grub_uint16_t *name16; + int name16len; + int length; + void *data; +}; + +struct grub_xnu_devprop_device_descriptor *devices = 0; + +grub_err_t +grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, + char *name) +{ + struct property_descriptor *prop; + prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name); + if (!prop) + return GRUB_ERR_NONE; + + grub_free (prop->name); + grub_free (prop->name16); + grub_free (prop->data); + + grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop)); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev) +{ + void *t; + struct property_descriptor *prop; + + grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev)); + + for (prop = dev->properties; prop; ) + { + grub_free (prop->name); + grub_free (prop->name16); + grub_free (prop->data); + t = prop; + prop = prop->next; + grub_free (t); + } + + grub_free (dev->path); + grub_free (dev); + + return GRUB_ERR_NONE; +} + +struct grub_xnu_devprop_device_descriptor * +grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length) +{ + struct grub_xnu_devprop_device_descriptor *ret; + + ret = grub_zalloc (sizeof (*ret)); + if (!ret) + return 0; + + ret->path = grub_malloc (length); + if (!ret->path) + { + grub_free (ret); + return 0; + } + ret->pathlen = length; + grub_memcpy (ret->path, path, length); + + grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret)); + + return ret; +} + +static grub_err_t +grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint8_t *utf8, grub_uint16_t *utf16, + int utf16len, void *data, int datalen) +{ + struct property_descriptor *prop; + + prop = grub_malloc (sizeof (*prop)); + if (!prop) + return grub_errno; + + prop->name = utf8; + prop->name16 = utf16; + prop->name16len = utf16len; + + prop->length = datalen; + prop->data = grub_malloc (prop->length); + if (!prop->data) + { + grub_free (prop); + grub_free (prop->name); + grub_free (prop->name16); + return grub_errno; + } + grub_memcpy (prop->data, data, prop->length); + grub_list_push (GRUB_AS_LIST_P (&dev->properties), + GRUB_AS_LIST (prop)); + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name, void *data, int datalen) +{ + grub_uint8_t *utf8; + grub_uint16_t *utf16; + int len, utf16len; + grub_err_t err; + + utf8 = (grub_uint8_t *) grub_strdup (name); + if (!utf8) + return grub_errno; + + len = grub_strlen (name); + utf16 = grub_malloc (sizeof (grub_uint16_t) * len); + if (!utf16) + { + grub_free (utf8); + return grub_errno; + } + + utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL); + if (utf16len < 0) + { + grub_free (utf8); + grub_free (utf16); + return grub_errno; + } + + err = grub_xnu_devprop_add_property (dev, utf8, utf16, + utf16len, data, datalen); + if (err) + { + grub_free (utf8); + grub_free (utf16); + return err; + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint16_t *name, int namelen, + void *data, int datalen) +{ + grub_uint8_t *utf8; + grub_uint16_t *utf16; + grub_err_t err; + + utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); + if (!utf16) + return grub_errno; + grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); + + utf8 = grub_malloc (namelen * 4 + 1); + if (!utf8) + { + grub_free (utf8); + return grub_errno; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0'; + + err = grub_xnu_devprop_add_property (dev, utf8, utf16, + namelen, data, datalen); + if (err) + { + grub_free (utf8); + grub_free (utf16); + return err; + } + + return GRUB_ERR_NONE; +} + +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +void +grub_cpu_xnu_unload (void) +{ + struct grub_xnu_devprop_device_descriptor *dev1, *dev2; + + for (dev1 = devices; dev1; ) + { + dev2 = dev1->next; + grub_xnu_devprop_remove_device (dev1); + dev1 = dev2; + } +} + +static grub_err_t +grub_cpu_xnu_fill_devprop (void) +{ + struct grub_xnu_devtree_key *efikey; + int total_length = sizeof (struct grub_xnu_devprop_header); + struct grub_xnu_devtree_key *devprop; + struct grub_xnu_devprop_device_descriptor *device; + void *ptr; + struct grub_xnu_devprop_header *head; + void *t; + int numdevs = 0; + + /* The key "efi". */ + efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi"); + if (! efikey) + return grub_errno; + + for (device = devices; device; device = device->next) + { + struct property_descriptor *propdesc; + total_length += sizeof (struct grub_xnu_devprop_device_header); + total_length += device->pathlen; + + for (propdesc = device->properties; propdesc; propdesc = propdesc->next) + { + total_length += sizeof (grub_uint32_t); + total_length += sizeof (grub_uint16_t) + * (propdesc->name16len + 1); + total_length += sizeof (grub_uint32_t); + total_length += propdesc->length; + } + numdevs++; + } + + devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties"); + if (devprop) + { + devprop->data = grub_malloc (total_length); + devprop->datasize = total_length; + } + + ptr = devprop->data; + head = ptr; + ptr = head + 1; + head->length = total_length; + head->alwaysone = 1; + head->num_devices = numdevs; + for (device = devices; device; ) + { + struct grub_xnu_devprop_device_header *devhead; + struct property_descriptor *propdesc; + devhead = ptr; + devhead->num_values = 0; + ptr = devhead + 1; + + grub_memcpy (ptr, device->path, device->pathlen); + ptr = (char *) ptr + device->pathlen; + + for (propdesc = device->properties; propdesc; ) + { + grub_uint32_t *len; + grub_uint16_t *name; + void *data; + + len = ptr; + *len = 2 * propdesc->name16len + sizeof (grub_uint16_t) + + sizeof (grub_uint32_t); + ptr = len + 1; + + name = ptr; + grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len); + name += propdesc->name16len; + + /* NUL terminator. */ + *name = 0; + ptr = name + 1; + + len = ptr; + *len = propdesc->length + sizeof (grub_uint32_t); + data = len + 1; + ptr = data; + grub_memcpy (ptr, propdesc->data, propdesc->length); + ptr = (char *) ptr + propdesc->length; + + grub_free (propdesc->name); + grub_free (propdesc->name16); + grub_free (propdesc->data); + t = propdesc; + propdesc = propdesc->next; + grub_free (t); + devhead->num_values++; + } + + devhead->length = (char *) ptr - (char *) devhead; + t = device; + device = device->next; + grub_free (t); + } + + devices = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), + int argc, char *args[]) +{ + grub_file_t file; + void *buf, *bufstart, *bufend; + struct grub_xnu_devprop_header *head; + grub_size_t size; + unsigned i, j; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "File name required. "); + + file = grub_gzfile_open (args[0], 1); + if (! file) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load device-propertie dump. "); + size = grub_file_size (file); + buf = grub_malloc (size); + if (!buf) + { + grub_file_close (file); + return grub_errno; + } + if (grub_file_read (file, buf, size) != (grub_ssize_t) size) + { + grub_file_close (file); + return grub_errno; + } + grub_file_close (file); + + bufstart = buf; + bufend = (char *) buf + size; + head = buf; + buf = head + 1; + for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++) + { + struct grub_efi_device_path *dp, *dpstart; + struct grub_xnu_devprop_device_descriptor *dev; + struct grub_xnu_devprop_device_header *devhead; + + devhead = buf; + buf = devhead + 1; + dpstart = buf; + + do + { + dp = buf; + buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp); + } + while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend); + + dev = grub_xnu_devprop_add_device (dpstart, (char *) buf + - (char *) dpstart); + + for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend; + j++) + { + grub_uint32_t *namelen; + grub_uint32_t *datalen; + grub_uint16_t *utf16; + void *data; + grub_err_t err; + + namelen = buf; + buf = namelen + 1; + if (buf >= bufend) + break; + + utf16 = buf; + buf = (char *) buf + *namelen - sizeof (grub_uint32_t); + if (buf >= bufend) + break; + + datalen = buf; + buf = datalen + 1; + if (buf >= bufend) + break; + + data = buf; + buf = (char *) buf + *datalen - sizeof (grub_uint32_t); + if (buf >= bufend) + break; + err = grub_xnu_devprop_add_property_utf16 + (dev, utf16, (*namelen - sizeof (grub_uint32_t) + - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t), + data, *datalen - sizeof (grub_uint32_t)); + if (err) + { + grub_free (bufstart); + return err; + } + } + } + + grub_free (bufstart); + return GRUB_ERR_NONE; +} + /* Fill device tree. */ /* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */ grub_err_t @@ -216,11 +626,6 @@ grub_cpu_xnu_fill_devicetree (void) struct grub_xnu_devtree_key *runtimesrvkey; struct grub_xnu_devtree_key *platformkey; unsigned i, j; - grub_err_t err; - - err = grub_autoefi_prepare (); - if (err) - return err; /* The value "model". */ /* FIXME: may this value be sometimes different? */ @@ -417,6 +822,19 @@ grub_cpu_xnu_fill_devicetree (void) return GRUB_ERR_NONE; } +grub_err_t +grub_xnu_boot_resume (void) +{ + struct grub_relocator32_state state; + + state.esp = grub_xnu_stack; + state.eip = grub_xnu_entry_point; + state.eax = grub_xnu_arg1; + + return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, + state); +} + /* Boot xnu. */ grub_err_t grub_xnu_boot (void) @@ -430,10 +848,28 @@ grub_xnu_boot (void) grub_efi_uintn_t map_key = 0; grub_efi_uintn_t descriptor_size = 0; grub_efi_uint32_t descriptor_version = 0; - grub_uint64_t firstruntimeaddr, lastruntimeaddr; + grub_uint64_t firstruntimepage, lastruntimepage; + grub_uint64_t curruntimepage; void *devtree; grub_size_t devtreelen; int i; + struct grub_relocator32_state state; + + err = grub_autoefi_prepare (); + if (err) + return err; + + err = grub_cpu_xnu_fill_devprop (); + if (err) + return err; + + err = grub_cpu_xnu_fill_devicetree (); + if (err) + return err; + + err = grub_xnu_fill_devicetree (); + if (err) + return err; /* Page-align to avoid following parts to be inadvertently freed. */ err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); @@ -447,94 +883,7 @@ grub_xnu_boot (void) descriptor_size = 0; descriptor_version = 0; - if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, - &map_key, &descriptor_size, - &descriptor_version) < 0) - return grub_errno; - - memory_map = grub_xnu_heap_malloc (memory_map_size); - if (! memory_map) - return grub_errno; - - if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, - &map_key, &descriptor_size, - &descriptor_version) <= 0) - return grub_errno; - mmap_relloc_off = (grub_uint8_t *) memory_map - - (grub_uint8_t *) grub_xnu_heap_start; - - firstruntimeaddr = (grub_uint64_t) (-1); - lastruntimeaddr = 0; - for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) - { - grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) - ((char *) memory_map + descriptor_size * i); - - /* Some EFI implementations set physical_start to 0 which - causes XNU crash. */ - curdesc->virtual_start = curdesc->physical_start; - - if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA - || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) - { - if (firstruntimeaddr > curdesc->physical_start) - firstruntimeaddr = curdesc->physical_start; - if (lastruntimeaddr < curdesc->physical_start - + curdesc->num_pages * 4096) - lastruntimeaddr = curdesc->physical_start - + curdesc->num_pages * 4096; - } - } - - /* Relocate the boot parameters to heap. */ - bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc)); - if (! bootparams_relloc) - return grub_errno; - bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc - - (grub_uint8_t *) grub_xnu_heap_start; - err = grub_xnu_writetree_toheap (&devtree, &devtreelen); - if (err) - return err; - bootparams_relloc = (struct grub_xnu_boot_params *) - (bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start); - - grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline, - sizeof (bootparams_relloc->cmdline)); - - bootparams_relloc->devtree = ((char *) devtree - grub_xnu_heap_start) - + grub_xnu_heap_will_be_at; - bootparams_relloc->devtreelen = devtreelen; - - bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; - bootparams_relloc->heap_size = grub_xnu_heap_size; - - bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; - bootparams_relloc->efi_mmap_size = memory_map_size; - bootparams_relloc->efi_mem_desc_size = descriptor_size; - bootparams_relloc->efi_mem_desc_version = descriptor_version; - - bootparams_relloc->efi_runtime_first_page = firstruntimeaddr - / GRUB_XNU_PAGESIZE; - bootparams_relloc->efi_runtime_npages - = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE) - - (firstruntimeaddr / GRUB_XNU_PAGESIZE); - bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8; - bootparams_relloc->efi_system_table - = PTR_TO_UINT32 (grub_autoefi_system_table); - - bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR; - bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR; - - /* Parameters for asm helper. */ - grub_xnu_stack = bootparams_relloc->heap_start - + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE; - grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at; -#ifndef GRUB_UTIL - grub_xnu_launch = (void (*) (void)) - (grub_xnu_heap_start + grub_xnu_heap_size); -#endif grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point); - grub_dprintf ("xnu", "launch=%p\n", grub_xnu_launch); const char *debug = grub_env_get ("debug"); @@ -544,6 +893,13 @@ grub_xnu_boot (void) grub_getkey (); } + /* Relocate the boot parameters to heap. */ + bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc)); + if (! bootparams_relloc) + return grub_errno; + bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc + - (grub_uint8_t *) grub_xnu_heap_start; + /* Set video. */ err = grub_xnu_set_video (bootparams_relloc); if (err != GRUB_ERR_NONE) @@ -560,16 +916,121 @@ grub_xnu_boot (void) bootparams_relloc->lfb_base = 0; } - grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size, - grub_xnu_launcher_start, - grub_xnu_launcher_end - grub_xnu_launcher_start); + if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, + &map_key, &descriptor_size, + &descriptor_version) < 0) + return grub_errno; + /* We will do few allocations later. Reserve some space for possible + memory map growth. */ + memory_map_size += 20 * descriptor_size; + memory_map = grub_xnu_heap_malloc (memory_map_size); + if (! memory_map) + return grub_errno; + mmap_relloc_off = (grub_uint8_t *) memory_map + - (grub_uint8_t *) grub_xnu_heap_start; - if (! grub_autoefi_finish_boot_services ()) + err = grub_xnu_writetree_toheap (&devtree, &devtreelen); + if (err) + return err; + bootparams_relloc = (struct grub_xnu_boot_params *) + (bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start); + + grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline, + sizeof (bootparams_relloc->cmdline)); + + bootparams_relloc->devtree + = ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start) + + grub_xnu_heap_will_be_at; + bootparams_relloc->devtreelen = devtreelen; + + memory_map = (grub_efi_memory_descriptor_t *) + ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off); + + if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, + &map_key, &descriptor_size, + &descriptor_version) <= 0) + return grub_errno; + + bootparams_relloc->efi_system_table + = PTR_TO_UINT32 (grub_autoefi_system_table); + + firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at + + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1) + / GRUB_XNU_PAGESIZE) + 20; + curruntimepage = firstruntimepage; + + for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) + { + grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) + ((char *) memory_map + descriptor_size * i); + + curdesc->virtual_start = curdesc->physical_start; + + if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA + || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) + { + curdesc->virtual_start = curruntimepage << 12; + curruntimepage += curdesc->num_pages; + if (curdesc->physical_start + <= PTR_TO_UINT64 (grub_autoefi_system_table) + && curdesc->physical_start + (curdesc->num_pages << 12) + > PTR_TO_UINT64 (grub_autoefi_system_table)) + bootparams_relloc->efi_system_table + = PTR_TO_UINT64 (grub_autoefi_system_table) + - curdesc->physical_start + curdesc->virtual_start; + if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit) + curdesc->virtual_start |= 0xffffff8000000000ULL; + } + } + + lastruntimepage = curruntimepage; + + bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; + bootparams_relloc->efi_mmap_size = memory_map_size; + bootparams_relloc->efi_mem_desc_size = descriptor_size; + bootparams_relloc->efi_mem_desc_version = descriptor_version; + + bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; + bootparams_relloc->heap_size = grub_xnu_heap_size; + bootparams_relloc->efi_runtime_first_page = firstruntimepage; + + bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage; + bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8; + + bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR; + bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR; + + /* Parameters for asm helper. */ + grub_xnu_stack = bootparams_relloc->heap_start + + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE; + grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at; + + if (! grub_autoefi_exit_boot_services (map_key)) return grub_error (GRUB_ERR_IO, "can't exit boot services"); - grub_xnu_launch (); + grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, + descriptor_version,memory_map); - /* Never reaches here. */ - return 0; + state.eip = grub_xnu_entry_point; + state.eax = grub_xnu_arg1; + state.esp = grub_xnu_stack; + return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, + state); +} + +static grub_command_t cmd_devprop_load; + +void +grub_cpu_xnu_init (void) +{ + cmd_devprop_load = grub_register_command ("xnu_devprop_load", + grub_cmd_devprop_load, + 0, "Load device-properties dump."); +} + +void +grub_cpu_xnu_fini (void) +{ + grub_unregister_command (cmd_devprop_load); } diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S deleted file mode 100644 index 4250c58ad..000000000 --- a/loader/i386/xnu_helper.S +++ /dev/null @@ -1,211 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_xnu_launcher_start) -base: - cli - -#ifndef __x86_64__ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_will_be_at) - .long 0 - mov %eax, %edi - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_start) - .long 0 - mov %eax, %esi - - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE(grub_xnu_heap_size) - .long 0 - mov %edi, %eax - add %ecx, %eax - /* %rax now contains our starting position after relocation. */ - /* One more page to copy: ourselves. */ - add $0x403, %ecx - shr $2, %ecx - - /* Forward copy. */ - cld - rep - movsl - - mov %eax, %esi - add $(cont0-base), %eax - jmp *%eax -cont0: -#else - xorq %rax, %rax - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_will_be_at) - .long 0 - mov %rax, %rdi - - /* mov imm32, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_xnu_heap_start) - .long 0 - .long 0 - mov %rax, %rsi - - /* mov imm32, %rcx */ - .byte 0x48 - .byte 0xb9 -VARIABLE(grub_xnu_heap_size) - .long 0 - .long 0 - mov %rdi, %rax - add %rcx, %rax - /* %rax now contains our starting position after relocation. */ - /* One more page to copy: ourselves. */ - add $0x403, %rcx - shr $2, %rcx - - /* Forward copy. */ - cld - rep - movsl - - mov %rax, %rsi -#ifdef APPLE_CC - add $(cont0-base), %eax -#else - add $(cont0-base), %rax -#endif - jmp *%rax - -cont0: -#ifdef APPLE_CC - lea (cont1 - base) (%esi, 1), %eax - mov %eax, (jump_vector - base) (%esi, 1) - - lea (gdt - base) (%esi, 1), %eax - mov %eax, (gdt_addr - base) (%esi, 1) - - /* Switch to compatibility mode. */ - - lgdt (gdtdesc - base) (%esi, 1) - - /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%esi,1) -#else - lea (cont1 - base) (%rsi, 1), %rax - mov %eax, (jump_vector - base) (%rsi, 1) - - lea (gdt - base) (%rsi, 1), %rax - mov %rax, (gdt_addr - base) (%rsi, 1) - - /* Switch to compatibility mode. */ - - lgdt (gdtdesc - base) (%rsi, 1) - - /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%rsi, 1) -#endif - -cont1: - .code32 - - /* Update other registers. */ - mov $0x18, %eax - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - mov %eax, %ss - - /* Disable paging. */ - mov %cr0, %eax - and $0x7fffffff, %eax - mov %eax, %cr0 - - /* Disable amd64. */ - mov $0xc0000080, %ecx - rdmsr - and $0xfffffeff, %eax - wrmsr - - /* Turn off PAE. */ - movl %cr4, %eax - and $0xffffffcf, %eax - mov %eax, %cr4 - - jmp cont2 -cont2: -#endif - .code32 - - /* Registers on XNU boot: eip, esp and eax. */ - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE (grub_xnu_entry_point) - .long 0 - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE (grub_xnu_arg1) - .long 0 - /* mov imm32, %ebx */ - .byte 0xbb -VARIABLE (grub_xnu_stack) - .long 0 - - movl %ebx, %esp - - jmp *%ecx - -#ifdef __x86_64__ - /* GDT. Copied from loader/i386/linux.c. */ - .p2align 4 -gdt: - /* NULL. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - /* Reserved. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - /* Code segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 - - /* Data segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 - -gdtdesc: - .word 31 -gdt_addr: - /* Filled by the code. */ - .quad 0 - - .p2align 4 -jump_vector: - /* Jump location. Is filled by the code */ - .long 0 - .long 0x10 -#endif -VARIABLE(grub_xnu_launcher_end) diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c index 3646e8091..3b0ab758e 100644 --- a/loader/ieee1275/multiboot2.c +++ b/loader/ieee1275/multiboot2.c @@ -36,7 +36,8 @@ typedef void (*kernel_entry_t) (unsigned long, void *, int (void *), /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; @@ -61,7 +62,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; diff --git a/loader/macho.c b/loader/macho.c index bd460b810..a23f5b206 100644 --- a/loader/macho.c +++ b/loader/macho.c @@ -30,239 +30,6 @@ #include #include -#define min(a,b) (((a) < (b)) ? (a) : (b)) - -/* 32-bit. */ - -int -grub_macho_contains_macho32 (grub_macho_t macho) -{ - return macho->offset32 != -1; -} - -static void -grub_macho_parse32 (grub_macho_t macho) -{ - struct grub_macho_header32 head; - - /* Is there any candidate at all? */ - if (macho->offset32 == -1) - return; - - /* Read header and check magic*/ - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1 - || grub_file_read (macho->file, &head, sizeof (head)) - != sizeof(head)) - { - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); - macho->offset32 = -1; - return; - } - if (head.magic != GRUB_MACHO_MAGIC32) - { - grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); - macho->offset32 = -1; - return; - } - - /* Read commands. */ - macho->ncmds32 = head.ncmds; - macho->cmdsize32 = head.sizeofcmds; - macho->cmds32 = grub_malloc(macho->cmdsize32); - if (! macho->cmds32) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands"); - return; - } - if (grub_file_read (macho->file, macho->cmds32, - (grub_size_t) macho->cmdsize32) - != (grub_ssize_t) macho->cmdsize32) - { - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); - macho->offset32 = -1; - } -} - -typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t) -(grub_macho_t , struct grub_macho_cmd *, - void *); - -static grub_err_t -grub_macho32_cmds_iterate (grub_macho_t macho, - grub_macho_iter_hook_t hook, - void *hook_arg) -{ - grub_uint8_t *hdrs = macho->cmds32; - int i; - if (! macho->cmds32) - return grub_error (GRUB_ERR_BAD_OS, "Couldn't find 32-bit Mach-O"); - for (i = 0; i < macho->ncmds32; i++) - { - struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs; - if (hook (macho, hdr, hook_arg)) - break; - hdrs += hdr->cmdsize; - } - - return grub_errno; -} - -grub_size_t -grub_macho32_filesize (grub_macho_t macho) -{ - if (grub_macho_contains_macho32 (macho)) - return macho->end32 - macho->offset32; - return 0; -} - -grub_err_t -grub_macho32_readfile (grub_macho_t macho, void *dest) -{ - grub_ssize_t read; - if (! grub_macho_contains_macho32 (macho)) - return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read architecture-specific part"); - - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) - { - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); - } - - read = grub_file_read (macho->file, dest, - macho->end32 - macho->offset32); - if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) - { - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read architecture-specific part"); - } - return GRUB_ERR_NONE; -} - -/* Calculate the amount of memory spanned by the segments. */ -grub_err_t -grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start, - grub_addr_t *segments_end, int flags) -{ - int nr_phdrs = 0; - - /* Run through the program headers to calculate the total memory size we - should claim. */ - auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, - struct grub_macho_cmd *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr0, void UNUSED *_arg) - { - struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0; - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32) - return 0; - if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) - return 0; - - nr_phdrs++; - if (hdr->vmaddr < *segments_start) - *segments_start = hdr->vmaddr; - if (hdr->vmaddr + hdr->vmsize > *segments_end) - *segments_end = hdr->vmaddr + hdr->vmsize; - return 0; - } - - *segments_start = (grub_uint32_t) -1; - *segments_end = 0; - - grub_macho32_cmds_iterate (macho, calcsize, 0); - - if (nr_phdrs == 0) - return grub_error (GRUB_ERR_BAD_OS, "No program headers present"); - - if (*segments_end < *segments_start) - /* Very bad addresses. */ - return grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); - - return GRUB_ERR_NONE; -} - -/* Load every loadable segment into memory specified by `_load_hook'. */ -grub_err_t -grub_macho32_load (grub_macho_t macho, char *offset, int flags) -{ - grub_err_t err = 0; - auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, - struct grub_macho_cmd *hdr0, - void UNUSED *_arg); - int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, - struct grub_macho_cmd *hdr0, - void UNUSED *_arg) - { - struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0; - - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32) - return 0; - - if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) - return 0; - if (! hdr->vmsize) - return 0; - - if (grub_file_seek (_macho->file, hdr->fileoff - + _macho->offset32) == (grub_off_t) -1) - { - grub_error_push (); - grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); - return 1; - } - - if (hdr->filesize) - { - grub_ssize_t read; - read = grub_file_read (_macho->file, offset + hdr->vmaddr, - min (hdr->filesize, hdr->vmsize)); - if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize)) - { - /* XXX How can we free memory from `load_hook'? */ - grub_error_push (); - err=grub_error (GRUB_ERR_BAD_OS, - "Couldn't read segment from file: " - "wanted 0x%lx bytes; read 0x%lx bytes.", - hdr->filesize, read); - return 1; - } - } - - if (hdr->filesize < hdr->vmsize) - grub_memset (offset + hdr->vmaddr + hdr->filesize, - 0, hdr->vmsize - hdr->filesize); - return 0; - } - - grub_macho32_cmds_iterate (macho, do_load, 0); - - return err; -} - -grub_uint32_t -grub_macho32_get_entry_point (grub_macho_t macho) -{ - grub_uint32_t entry_point = 0; - auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg); - int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg) - { - if (hdr->cmd == GRUB_MACHO_CMD_THREAD) - entry_point = ((struct grub_macho_thread32 *) hdr)->entry_point; - return 0; - } - grub_macho32_cmds_iterate (macho, hook, 0); - return entry_point; -} - - grub_err_t grub_macho_close (grub_macho_t macho) { @@ -367,8 +134,7 @@ grub_macho_file (grub_file_t file) } grub_macho_parse32 (macho); - /* FIXME: implement 64-bit.*/ - /* grub_macho_parse64 (macho); */ + grub_macho_parse64 (macho); return macho; diff --git a/loader/macho32.c b/loader/macho32.c new file mode 100644 index 000000000..0d740eda7 --- /dev/null +++ b/loader/macho32.c @@ -0,0 +1,18 @@ +#include +#include + +#define SUFFIX(x) x ## 32 +typedef struct grub_macho_header32 grub_macho_header_t; +typedef struct grub_macho_segment32 grub_macho_segment_t; +typedef grub_uint32_t grub_macho_addr_t; +typedef struct grub_macho_thread32 grub_macho_thread_t; +#define offsetXX offset32 +#define ncmdsXX ncmds32 +#define cmdsizeXX cmdsize32 +#define cmdsXX cmds32 +#define endXX end32 +#define XX "32" +#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC32 +#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT32 +#include "machoXX.c" + diff --git a/loader/macho64.c b/loader/macho64.c new file mode 100644 index 000000000..17a8021e0 --- /dev/null +++ b/loader/macho64.c @@ -0,0 +1,18 @@ +#include +#include + +#define SUFFIX(x) x ## 64 +typedef struct grub_macho_header64 grub_macho_header_t; +typedef struct grub_macho_segment64 grub_macho_segment_t; +typedef grub_uint64_t grub_macho_addr_t; +typedef struct grub_macho_thread64 grub_macho_thread_t; +#define offsetXX offset64 +#define ncmdsXX ncmds64 +#define cmdsizeXX cmdsize64 +#define cmdsXX cmds64 +#define endXX end64 +#define XX "64" +#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC64 +#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT64 +#include "machoXX.c" + diff --git a/loader/machoXX.c b/loader/machoXX.c new file mode 100644 index 000000000..8441e0128 --- /dev/null +++ b/loader/machoXX.c @@ -0,0 +1,239 @@ + +#include +#include +#include + +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +int +SUFFIX (grub_macho_contains_macho) (grub_macho_t macho) +{ + return macho->offsetXX != -1; +} + +void +SUFFIX (grub_macho_parse) (grub_macho_t macho) +{ + grub_macho_header_t head; + + /* Is there any candidate at all? */ + if (macho->offsetXX == -1) + return; + + /* Read header and check magic*/ + if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1 + || grub_file_read (macho->file, &head, sizeof (head)) + != sizeof(head)) + { + grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + macho->offsetXX = -1; + return; + } + if (head.magic != GRUB_MACHO_MAGIC) + { + grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O " XX "-bit header."); + macho->offsetXX = -1; + return; + } + + /* Read commands. */ + macho->ncmdsXX = head.ncmds; + macho->cmdsizeXX = head.sizeofcmds; + macho->cmdsXX = grub_malloc(macho->cmdsizeXX); + if (! macho->cmdsXX) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands"); + return; + } + if (grub_file_read (macho->file, macho->cmdsXX, + (grub_size_t) macho->cmdsizeXX) + != (grub_ssize_t) macho->cmdsizeXX) + { + grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + macho->offsetXX = -1; + } +} + +typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t) +(grub_macho_t , struct grub_macho_cmd *, + void *); + +static grub_err_t +grub_macho_cmds_iterate (grub_macho_t macho, + grub_macho_iter_hook_t hook, + void *hook_arg) +{ + grub_uint8_t *hdrs = macho->cmdsXX; + int i; + if (! macho->cmdsXX) + return grub_error (GRUB_ERR_BAD_OS, "Couldn't find " XX "-bit Mach-O"); + for (i = 0; i < macho->ncmdsXX; i++) + { + struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs; + if (hook (macho, hdr, hook_arg)) + break; + hdrs += hdr->cmdsize; + } + + return grub_errno; +} + +grub_size_t +SUFFIX (grub_macho_filesize) (grub_macho_t macho) +{ + if (SUFFIX (grub_macho_contains_macho) (macho)) + return macho->endXX - macho->offsetXX; + return 0; +} + +grub_err_t +SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) +{ + grub_ssize_t read; + if (! SUFFIX (grub_macho_contains_macho) (macho)) + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read architecture-specific part"); + + if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + } + + read = grub_file_read (macho->file, dest, + macho->endXX - macho->offsetXX); + if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read architecture-specific part"); + } + return GRUB_ERR_NONE; +} + +/* Calculate the amount of memory spanned by the segments. */ +grub_err_t +SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, + grub_macho_addr_t *segments_end, int flags) +{ + int nr_phdrs = 0; + + /* Run through the program headers to calculate the total memory size we + should claim. */ + auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, + struct grub_macho_cmd *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr0, + void *_arg __attribute__ ((unused))) + { + grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; + if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) + return 0; + + if (! hdr->vmsize) + return 0; + + if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) + return 0; + + nr_phdrs++; + if (hdr->vmaddr < *segments_start) + *segments_start = hdr->vmaddr; + if (hdr->vmaddr + hdr->vmsize > *segments_end) + *segments_end = hdr->vmaddr + hdr->vmsize; + return 0; + } + + *segments_start = (grub_macho_addr_t) -1; + *segments_end = 0; + + grub_macho_cmds_iterate (macho, calcsize, 0); + + if (nr_phdrs == 0) + return grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + + if (*segments_end < *segments_start) + /* Very bad addresses. */ + return grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + + return GRUB_ERR_NONE; +} + +/* Load every loadable segment into memory specified by `_load_hook'. */ +grub_err_t +SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags) +{ + grub_err_t err = 0; + auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, + struct grub_macho_cmd *hdr0, + void *_arg __attribute__ ((unused))); + int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, + struct grub_macho_cmd *hdr0, + void *_arg __attribute__ ((unused))) + { + grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; + + if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) + return 0; + + if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) + return 0; + if (! hdr->vmsize) + return 0; + + if (grub_file_seek (_macho->file, hdr->fileoff + + _macho->offsetXX) == (grub_off_t) -1) + { + grub_error_push (); + grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + return 1; + } + + if (hdr->filesize) + { + grub_ssize_t read; + read = grub_file_read (_macho->file, offset + hdr->vmaddr, + min (hdr->filesize, hdr->vmsize)); + if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize)) + { + /* XXX How can we free memory from `load_hook'? */ + grub_error_push (); + err=grub_error (GRUB_ERR_BAD_OS, + "Couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes.", + hdr->filesize, read); + return 1; + } + } + + if (hdr->filesize < hdr->vmsize) + grub_memset (offset + hdr->vmaddr + hdr->filesize, + 0, hdr->vmsize - hdr->filesize); + return 0; + } + + grub_macho_cmds_iterate (macho, do_load, 0); + + return err; +} + +grub_macho_addr_t +SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho) +{ + grub_macho_addr_t entry_point = 0; + auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))); + int NESTED_FUNC_ATTR hook(grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))) + { + if (hdr->cmd == GRUB_MACHO_CMD_THREAD) + entry_point = ((grub_macho_thread_t *) hdr)->entry_point; + return 0; + } + grub_macho_cmds_iterate (macho, hook, 0); + return entry_point; +} diff --git a/loader/multiboot2.c b/loader/multiboot2.c index 976285b85..4c73a2f17 100644 --- a/loader/multiboot2.c +++ b/loader/multiboot2.c @@ -222,7 +222,8 @@ grub_mb2_unload (void) } static grub_err_t -grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer) +grub_mb2_load_other (grub_file_t file __attribute__ ((unused)), + void *buffer __attribute__ ((unused))) { /* XXX Create module tag here. */ return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported"); diff --git a/loader/xnu.c b/loader/xnu.c index ab88317d2..85a19033f 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -32,10 +32,15 @@ #include #include #include +#include struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; static int driversnum = 0; +int grub_xnu_is_64bit = 0; + +void *grub_xnu_heap_start = 0; +grub_size_t grub_xnu_heap_size = 0; /* Allocate heap by 32MB-blocks. */ #define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000 @@ -47,12 +52,6 @@ void * grub_xnu_heap_malloc (int size) { void *val; - -#if 0 - /* This way booting is faster but less reliable. - Once we have advanced mm second way will be as fast as this one. */ - val = grub_xnu_heap_start = (char *) 0x100000; -#else int oldblknum, newblknum; /* The page after the heap is used for stack. Ensure it's usable. */ @@ -64,25 +63,21 @@ grub_xnu_heap_malloc (int size) newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK; if (oldblknum != newblknum) - /* FIXME: instruct realloc to allocate at 1MB if possible once - advanced mm is ready. */ - val = grub_realloc (grub_xnu_heap_start, - newblknum * GRUB_XNU_HEAP_ALLOC_BLOCK); - else - val = grub_xnu_heap_start; - if (! val) { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "not enough space on xnu memory heap"); - return 0; + /* FIXME: instruct realloc to allocate at 1MB if possible once + advanced mm is ready. */ + grub_xnu_heap_start + = XNU_RELOCATOR (realloc) (grub_xnu_heap_start, + newblknum + * GRUB_XNU_HEAP_ALLOC_BLOCK); + if (!grub_xnu_heap_start) + return NULL; } - grub_xnu_heap_start = val; -#endif - val = (char *) grub_xnu_heap_start + grub_xnu_heap_size; + val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size; grub_xnu_heap_size += size; grub_dprintf ("xnu", "val=%p\n", val); - return (char *) val; + return val; } /* Make sure next block of the heap will be aligned. @@ -252,7 +247,7 @@ grub_xnu_writetree_toheap (void **start, grub_size_t *size) - *size % GRUB_XNU_PAGESIZE); /* Put real data in the dummy. */ - extdesc->addr = (char *) *start - grub_xnu_heap_start + extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_will_be_at; extdesc->size = (grub_uint32_t) *size; @@ -334,6 +329,8 @@ grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name) static grub_err_t grub_xnu_unload (void) { + grub_cpu_xnu_unload (); + grub_xnu_free_devtree (grub_xnu_devtree_root); grub_xnu_devtree_root = 0; @@ -353,7 +350,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), { grub_err_t err; grub_macho_t macho; - grub_addr_t startcode, endcode; + grub_uint32_t startcode, endcode; int i; char *ptr, *loadaddr; @@ -369,10 +366,10 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), { grub_macho_close (macho); return grub_error (GRUB_ERR_BAD_OS, - "Kernel doesn't contain suitable architecture"); + "Kernel doesn't contain suitable 32-bit architecture"); } - err = grub_macho32_size (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); + err = grub_macho_size32 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -395,7 +392,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), } /* Load kernel. */ - err = grub_macho32_load (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -403,7 +400,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), return err; } - grub_xnu_entry_point = grub_macho32_get_entry_point (macho); + grub_xnu_entry_point = grub_macho_get_entry_point32 (macho); if (! grub_xnu_entry_point) { grub_macho_close (macho); @@ -437,13 +434,112 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; - err = grub_cpu_xnu_fill_devicetree (); + grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); + + grub_xnu_lock (); + grub_xnu_is_64bit = 0; + + return 0; +} + +static grub_err_t +grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), + int argc, char *args[]) +{ + grub_err_t err; + grub_macho_t macho; + grub_uint64_t startcode, endcode; + int i; + char *ptr, *loadaddr; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_xnu_unload (); + + macho = grub_macho_open (args[0]); + if (! macho) + return grub_errno; + if (! grub_macho_contains_macho64 (macho)) + { + grub_macho_close (macho); + return grub_error (GRUB_ERR_BAD_OS, + "Kernel doesn't contain suitable 64-bit architecture"); + } + + err = grub_macho_size64 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); if (err) - return err; + { + grub_macho_close (macho); + grub_xnu_unload (); + return err; + } + + startcode &= 0x0fffffff; + endcode &= 0x0fffffff; + + grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n", + (unsigned long) endcode, (unsigned long) startcode); + + loadaddr = grub_xnu_heap_malloc (endcode - startcode); + grub_xnu_heap_will_be_at = startcode; + + if (! loadaddr) + { + grub_macho_close (macho); + grub_xnu_unload (); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "not enough memory to load kernel"); + } + + /* Load kernel. */ + err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + if (err) + { + grub_macho_close (macho); + grub_xnu_unload (); + return err; + } + + grub_xnu_entry_point = grub_macho_get_entry_point64 (macho) & 0x0fffffff; + if (! grub_xnu_entry_point) + { + grub_macho_close (macho); + grub_xnu_unload (); + return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point"); + } + + grub_macho_close (macho); + + err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); + if (err) + { + grub_xnu_unload (); + return err; + } + + /* Copy parameters to kernel command line. */ + ptr = grub_xnu_cmdline; + for (i = 1; i < argc; i++) + { + if (ptr + grub_strlen (args[i]) + 1 + >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline)) + break; + grub_memcpy (ptr, args[i], grub_strlen (args[i])); + ptr += grub_strlen (args[i]); + *ptr = ' '; + ptr++; + } + + /* Replace last space by '\0'. */ + if (ptr != grub_xnu_cmdline) + *(ptr - 1) = 0; grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); + grub_xnu_is_64bit = 1; + return 0; } @@ -495,6 +591,34 @@ grub_xnu_register_memory (char *prefix, int *suffix, return GRUB_ERR_NONE; } +static inline char * +get_name_ptr (char *name) +{ + char *p = name, *p2; + /* Skip Info.plist. */ + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + if (p2 == name) + return name + 1; + p = p2 - 1; + + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + if (p2 == name) + return name + 1; + if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0) + return p2 + 1; + + p = p2 - 1; + + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + return p2 + 1; +} + /* Load .kext. */ static grub_err_t grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) @@ -504,8 +628,20 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) grub_file_t infoplist; struct grub_xnu_extheader *exthead; int neededspace = sizeof (*exthead); - char *buf; + grub_uint8_t *buf; grub_size_t infoplistsize = 0, machosize = 0; + char *name, *nameend; + int namelen; + + name = get_name_ptr (infoplistname); + nameend = grub_strchr (name, '/'); + + if (nameend) + namelen = nameend - name; + else + namelen = grub_strlen (name); + + neededspace += namelen + 1; if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); @@ -521,7 +657,10 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) return grub_error (GRUB_ERR_BAD_OS, "Extension doesn't contain suitable architecture"); } - machosize = grub_macho32_filesize (macho); + if (grub_xnu_is_64bit) + machosize = grub_macho_filesize64 (macho); + else + machosize = grub_macho_filesize32 (macho); neededspace += machosize; } else @@ -553,10 +692,14 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the binary. */ if (macho) { - exthead->binaryaddr = (buf - grub_xnu_heap_start) + exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->binarysize = machosize; - if ((err = grub_macho32_readfile (macho, buf))) + if (grub_xnu_is_64bit) + err = grub_macho_readfile64 (macho, buf); + else + err = grub_macho_readfile32 (macho, buf); + if (err) { grub_macho_close (macho); return err; @@ -569,7 +712,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the plist. */ if (infoplist) { - exthead->infoplistaddr = (buf - grub_xnu_heap_start) + exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->infoplistsize = infoplistsize + 1; if (grub_file_read (infoplist, buf, infoplistsize) @@ -582,9 +725,17 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) } grub_file_close (infoplist); buf[infoplistsize] = 0; + buf += infoplistsize + 1; } grub_errno = GRUB_ERR_NONE; + exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start) + + grub_xnu_heap_will_be_at; + exthead->namesize = namelen + 1; + grub_memcpy (buf, name, namelen); + buf[namelen] = 0; + buf += namelen + 1; + /* Announce to kernel */ return grub_xnu_register_memory ("Driver-", &driversnum, exthead, neededspace); @@ -649,7 +800,13 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), } for (i = 0; i < narchs; i++) { - if (GRUB_MACHO_CPUTYPE_IS_HOST32 + if (!grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32 + (grub_be_to_cpu32 (archs[i].cputype))) + { + readoff = grub_be_to_cpu32 (archs[i].offset); + readlen = grub_be_to_cpu32 (archs[i].size); + } + if (grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64 (grub_be_to_cpu32 (archs[i].cputype))) { readoff = grub_be_to_cpu32 (archs[i].offset); @@ -740,135 +897,6 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), return grub_xnu_register_memory ("RAMDisk", 0, loadto, size); } -/* Parse a devtree file. It uses the following format: - valuename:valuedata; - keyname{ - contents - } - keyname, valuename and valuedata are in hex. - */ -static char * -grub_xnu_parse_devtree (struct grub_xnu_devtree_key **parent, - char *start, char *end) -{ - char *ptr, *ptr2; - char *name, *data; - int namelen, datalen, i; - for (ptr = start; ptr && ptr < end; ) - { - if (grub_isspace (*ptr)) - { - ptr++; - continue; - } - if (*ptr == '}') - return ptr + 1; - namelen = 0; - - /* Parse the name. */ - for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (! grub_isspace (*ptr2)) - namelen++; - if (ptr2 == end) - return 0; - namelen /= 2; - name = grub_malloc (namelen + 1); - if (!name) - return 0; - for (i = 0; i < 2 * namelen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i % 2 == 0) - name[i / 2] = hex << 4; - else - name[i / 2] |= hex; - ptr++; - } - name [namelen] = 0; - while (grub_isspace (*ptr)) - ptr++; - - /* If it describes a key recursively invoke the function. */ - if (*ptr == '{') - { - struct grub_xnu_devtree_key *newkey - = grub_xnu_create_key (parent, name); - grub_free (name); - if (! newkey) - return 0; - ptr = grub_xnu_parse_devtree (&(newkey->first_child), ptr + 1, end); - continue; - } - - /* Parse the data. */ - if (*ptr != ':') - return 0; - ptr++; - datalen = 0; - for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (! grub_isspace (*ptr2)) - datalen++; - if (ptr2 == end) - return 0; - datalen /= 2; - data = grub_malloc (datalen); - if (! data) - return 0; - for (i = 0; i < 2 * datalen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i % 2 == 0) - data[i / 2] = hex << 4; - else - data[i / 2] |= hex; - ptr++; - } - while (ptr < end && grub_isspace (*ptr)) - ptr++; - { - struct grub_xnu_devtree_key *newkey - = grub_xnu_create_value (parent, name); - grub_free (name); - if (! newkey) - return 0; - newkey->datasize = datalen; - newkey->data = data; - } - if (*ptr != ';') - return 0; - ptr++; - } - if (ptr >= end && *parent != grub_xnu_devtree_root) - return 0; - return ptr; -} - /* Returns true if the kext should be loaded according to plist and osbundlereq. Also fill BINNAME. */ static int @@ -1165,53 +1193,6 @@ grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, return GRUB_ERR_NONE; } -/* Load devtree file. */ -static grub_err_t -grub_cmd_xnu_devtree (grub_command_t cmd __attribute__ ((unused)), - int argc, char *args[]) -{ - grub_file_t file; - char *data, *endret; - grub_size_t datalen; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Filename required"); - - if (! grub_xnu_heap_size) - return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); - - /* Load the file. */ - file = grub_gzfile_open (args[0], 1); - if (! file) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load device tree"); - datalen = grub_file_size (file); - data = grub_malloc (datalen + 1); - if (! data) - { - grub_file_close (file); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could load device tree into memory"); - } - if (grub_file_read (file, data, datalen) != (grub_ssize_t) datalen) - { - grub_file_close (file); - grub_free (data); - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]); - } - grub_file_close (file); - data[datalen] = 0; - - /* Parse the file. */ - endret = grub_xnu_parse_devtree (&grub_xnu_devtree_root, - data, data + datalen); - grub_free (data); - - if (! endret) - return grub_error (GRUB_ERR_BAD_OS, "Couldn't parse devtree"); - - return GRUB_ERR_NONE; -} static int locked=0; static grub_dl_t my_mod; @@ -1272,6 +1253,107 @@ grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)), } } +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +static inline void +unescape (char *name, char *curdot, char *nextdot, int *len) +{ + char *ptr, *dptr; + dptr = name; + for (ptr = curdot; ptr < nextdot;) + if (ptr + 2 < nextdot && *ptr == '%') + { + *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2])); + ptr += 3; + dptr++; + } + else + { + *dptr = *ptr; + ptr++; + dptr++; + } + *len = dptr - name; +} + +grub_err_t +grub_xnu_fill_devicetree (void) +{ + auto int iterate_env (struct grub_env_var *var); + int iterate_env (struct grub_env_var *var) + { + char *nextdot = 0, *curdot; + struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root; + struct grub_xnu_devtree_key *curvalue; + char *name = 0, *data; + int len; + + if (grub_memcmp (var->name, "XNU.DeviceTree.", + sizeof ("XNU.DeviceTree.") - 1) != 0) + return 0; + + curdot = var->name + sizeof ("XNU.DeviceTree.") - 1; + nextdot = grub_strchr (curdot, '.'); + if (nextdot) + nextdot++; + while (nextdot) + { + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) + return 1; + + unescape (name, curdot, nextdot, &len); + name[len - 1] = 0; + + curkey = &(grub_xnu_create_key (curkey, name)->first_child); + + curdot = nextdot; + nextdot = grub_strchr (nextdot, '.'); + if (nextdot) + nextdot++; + } + + nextdot = curdot + grub_strlen (curdot) + 1; + + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) + return 1; + + unescape (name, curdot, nextdot, &len); + name[len] = 0; + + curvalue = grub_xnu_create_value (curkey, name); + grub_free (name); + + data = grub_malloc (grub_strlen (var->value) + 1); + if (!data) + return 1; + + unescape (data, var->value, var->value + grub_strlen (var->value), + &len); + curvalue->datasize = len; + curvalue->data = data; + + return 0; + } + + grub_env_iterate (iterate_env); + + return grub_errno; +} + struct grub_video_bitmap *grub_xnu_bitmap = 0; grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode; @@ -1336,8 +1418,7 @@ grub_xnu_unlock () locked = 0; } -static grub_command_t cmd_kernel, cmd_mkext, cmd_kext; -static grub_command_t cmd_devtree; +static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext; static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume; static grub_extcmd_t cmd_splash; @@ -1345,6 +1426,8 @@ GRUB_MOD_INIT(xnu) { cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, "load a xnu kernel"); + cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, + 0, "load a 64-bit xnu kernel"); cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0, "Load XNU extension package."); cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0, @@ -1355,8 +1438,6 @@ GRUB_MOD_INIT(xnu) cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, "Load XNU ramdisk. " "It will be seen as md0"); - cmd_devtree = grub_register_command ("xnu_devtree", grub_cmd_xnu_devtree, 0, - "Load XNU devtree"); cmd_splash = grub_register_extcmd ("xnu_splash", grub_cmd_xnu_splash, GRUB_COMMAND_FLAG_BOTH, 0, @@ -1367,7 +1448,10 @@ GRUB_MOD_INIT(xnu) cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume, 0, "Load XNU hibernate image."); #endif - my_mod=mod; + + grub_cpu_xnu_init (); + + my_mod = mod; } GRUB_MOD_FINI(xnu) @@ -1378,8 +1462,10 @@ GRUB_MOD_FINI(xnu) grub_unregister_command (cmd_mkext); grub_unregister_command (cmd_kext); grub_unregister_command (cmd_kextdir); - grub_unregister_command (cmd_devtree); grub_unregister_command (cmd_ramdisk); grub_unregister_command (cmd_kernel); grub_unregister_extcmd (cmd_splash); + grub_unregister_command (cmd_kernel64); + + grub_cpu_xnu_fini (); } diff --git a/loader/xnu_resume.c b/loader/xnu_resume.c index 77f688726..83c2c3cd1 100644 --- a/loader/xnu_resume.c +++ b/loader/xnu_resume.c @@ -45,7 +45,7 @@ grub_xnu_resume (char *imagename) grub_file_t file; grub_size_t total_header_size; struct grub_xnu_hibernate_header hibhead; - char *buf, *codetmp; + grub_uint8_t *buf; grub_uint32_t codedest; grub_uint32_t codesize; @@ -94,17 +94,28 @@ grub_xnu_resume (char *imagename) /* Try to allocate necessary space. FIXME: mm isn't good enough yet to handle huge allocations. */ - grub_xnu_hibernate_image = buf = grub_malloc (hibhead.image_size); + grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size + + codesize + + GRUB_XNU_PAGESIZE); if (! buf) { grub_file_close (file); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "not enough memory to load image"); + return grub_errno; + } + + /* Read code part. */ + if (grub_file_seek (file, total_header_size) == (grub_off_t) -1 + || grub_file_read (file, buf, codesize) + != (grub_ssize_t) codesize) + { + grub_file_close (file); + return grub_error (GRUB_ERR_READ_ERROR, "Cannot read resume image."); } /* Read image. */ - if (grub_file_seek (file, 0) == (grub_off_t)-1 - || grub_file_read (file, buf, hibhead.image_size) + if (grub_file_seek (file, 0) == (grub_off_t) -1 + || grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE, + hibhead.image_size) != (grub_ssize_t) hibhead.image_size) { grub_file_close (file); @@ -112,22 +123,20 @@ grub_xnu_resume (char *imagename) } grub_file_close (file); - codetmp = grub_memalign (GRUB_XNU_PAGESIZE, codesize + GRUB_XNU_PAGESIZE); /* Setup variables needed by asm helper. */ grub_xnu_heap_will_be_at = codedest; - grub_xnu_heap_start = codetmp; - grub_xnu_heap_size = codesize; + grub_xnu_heap_start = buf; + grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size; grub_xnu_stack = (codedest + hibhead.stack); grub_xnu_entry_point = (codedest + hibhead.entry_point); - grub_xnu_arg1 = (long) buf; + grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE; - /* Prepare asm helper. */ - grub_memcpy (codetmp, ((grub_uint8_t *) buf) + total_header_size, codesize); - grub_memcpy (codetmp + codesize, grub_xnu_launcher_start, - grub_xnu_launcher_end - grub_xnu_launcher_start); + grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point); + grub_dprintf ("xnu", "image at 0x%x\n", + codedest + codesize + GRUB_XNU_PAGESIZE); /* We're ready now. */ - grub_loader_set ((grub_err_t (*) (void)) (codetmp + codesize), + grub_loader_set (grub_xnu_boot_resume, grub_xnu_resume_unload, 0); /* Prevent module from unloading. */ diff --git a/normal/auth.c b/normal/auth.c index c71262584..54107fe01 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_auth_user { @@ -237,7 +238,7 @@ grub_auth_check_authentication (const char *userlist) return GRUB_ERR_NONE; } - if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1, + if (!grub_cmdline_get (N_("Enter username:"), login, sizeof (login) - 1, 0, 0, 0)) goto access_denied; diff --git a/normal/cmdline.c b/normal/cmdline.c index 3816ce9d6..a4cb6681f 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,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 @@ -26,6 +26,7 @@ #include #include #include +#include static char *kill_buf; @@ -193,6 +194,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, auto void cl_delete (unsigned len); auto void cl_print (int pos, int c); auto void cl_set_pos (void); + const char *prompt_translated = _(prompt); void cl_set_pos (void) { @@ -260,14 +262,14 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, } } - plen = grub_strlen (prompt); + plen = grub_strlen (prompt_translated); lpos = llen = 0; buf[0] = '\0'; if ((grub_getxy () >> 8) != 0) grub_putchar ('\n'); - grub_printf ("%s", prompt); + grub_printf ("%s", prompt_translated); xpos = plen; ystart = ypos = (grub_getxy () & 0xFF); @@ -330,7 +332,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, if (restore) { /* Restore the prompt. */ - grub_printf ("\n%s%s", prompt, buf); + grub_printf ("\n%s %s", prompt_translated, buf); xpos = plen; ystart = ypos = (grub_getxy () & 0xFF); } diff --git a/normal/color.c b/normal/color.c index 340e43a02..0b9868d3b 100644 --- a/normal/color.c +++ b/normal/color.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Borrowed from GRUB Legacy */ static char *color_list[16] = @@ -76,7 +77,7 @@ grub_parse_color_name_pair (grub_uint8_t *ret, const char *name) bg_name = grub_strchr (fg_name, '/'); if (bg_name == NULL) { - grub_printf ("Warning: syntax error (missing slash) in `%s'\n", fg_name); + grub_printf_ (N_("Warning: syntax error (missing slash) in `%s'\n"), fg_name); grub_wait_after_message (); goto free_and_return; } @@ -85,13 +86,13 @@ grub_parse_color_name_pair (grub_uint8_t *ret, const char *name) if (parse_color_name (&fg, fg_name) == -1) { - grub_printf ("Warning: invalid foreground color `%s'\n", fg_name); + grub_printf_ (N_("Warning: invalid foreground color `%s'\n"), fg_name); grub_wait_after_message (); goto free_and_return; } if (parse_color_name (&bg, bg_name) == -1) { - grub_printf ("Warning: invalid background color `%s'\n", bg_name); + grub_printf_ (N_("Warning: invalid background color `%s'\n"), bg_name); grub_wait_after_message (); goto free_and_return; } diff --git a/normal/completion.c b/normal/completion.c index 4b38e334d..d264028cc 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -409,13 +409,16 @@ grub_normal_do_completion (char *buf, int *restore, if (grub_parser_split_cmdline (buf, 0, &argc, &argv)) return 0; - current_word = argv[argc]; + if (argc == 0) + current_word = ""; + else + current_word = argv[argc - 1]; /* Determine the state the command line is in, depending on the state, it can be determined how to complete. */ cmdline_state = get_state (buf); - if (argc == 0) + if (argc == 1 || argc == 0) { /* Complete a command. */ if (grub_command_iterate (iterate_command)) @@ -485,13 +488,15 @@ grub_normal_do_completion (char *buf, int *restore, goto fail; } - grub_free (argv[0]); + if (argc != 0) + grub_free (argv[0]); grub_free (match); return ret; } fail: - grub_free (argv[0]); + if (argc != 0) + grub_free (argv[0]); grub_free (match); grub_errno = GRUB_ERR_NONE; diff --git a/normal/main.c b/normal/main.c index 96955f009..245f20f30 100644 --- a/normal/main.c +++ b/normal/main.c @@ -385,22 +385,35 @@ read_config_file (const char *config) void grub_normal_init_page (void) { - grub_uint8_t width, margin; - -#define TITLE ("GNU GRUB version " PACKAGE_VERSION) - - width = grub_getwh () >> 8; - margin = (width - (sizeof(TITLE) + 7)) / 2; + int msg_len; + int posx; + const char *msg = _("GNU GRUB version %s"); + char *msg_formatted = grub_malloc (grub_strlen(msg) + + grub_strlen(PACKAGE_VERSION)); + grub_cls (); - grub_putchar ('\n'); - while (margin--) - grub_putchar (' '); + grub_sprintf (msg_formatted, msg, PACKAGE_VERSION); - grub_printf ("%s\n\n", TITLE); + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + + msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, + &unicode_msg, &last_position); + + if (msg_len < 0) + { + return; + } -#undef TITLE + posx = grub_getstringwidth (unicode_msg, last_position); + posx = (GRUB_TERM_WIDTH - posx) / 2; + grub_gotoxy (posx, 1); + + grub_print_ucs4 (unicode_msg, last_position); + grub_printf("\n\n"); + grub_free (unicode_msg); } static int reader_nested; @@ -509,12 +522,21 @@ grub_normal_reader_init (void) grub_normal_init_page (); grub_setcursor (1); - grub_printf (_("\ - [ Minimal BASH-like line editing is supported. For the first word, TAB\n\ - lists possible command completions. Anywhere else TAB lists possible\n\ - device/file completions.%s ]\n\n"), - reader_nested ? " ESC at any time exits." : ""); + const char *msg = _("Minimal BASH-like line editing is supported. For " + "the first word, TAB lists possible command completions. Anywhere " + "else TAB lists possible device or file completions. %s"); + const char *msg_esc = _("ESC at any time exits."); + + char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) + + grub_strlen(msg_esc) + 1)); + + grub_sprintf (msg_formatted, msg, reader_nested ? msg_esc : ""); + grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN); + grub_puts ("\n"); + + grub_free (msg_formatted); + return 0; } diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 7478c33ae..7a31c27af 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -836,7 +836,9 @@ store_completion (const char *item, grub_completion_type_t type, int count) } grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - grub_printf (" Possible %s are:\n ", what); + grub_printf (" "); + grub_printf_ (N_("Possible %s are:"), what); + grub_printf ("\n "); } /* Make sure that the completion buffer has enough room. */ @@ -997,7 +999,9 @@ run (struct screen *screen) } grub_cls (); - grub_printf (_(" Booting a command list\n\n")); + grub_printf (" "); + grub_printf_ (N_("Booting a command list")); + grub_printf ("\n\n"); /* Execute the script, line for line. */ @@ -1177,6 +1181,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) grub_cls (); grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_printf (_("\nPress any key to continue...")); + grub_putchar ('\n'); + grub_printf_ (N_("Press any key to continue...")); (void) grub_getkey (); } diff --git a/normal/menu_text.c b/normal/menu_text.c index 25eff4c44..81bcad0f7 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -39,11 +39,127 @@ static grub_uint8_t grub_color_menu_highlight; void grub_wait_after_message (void) { - grub_printf ("\nPress any key to continue..."); + grub_putchar ('\n'); + grub_printf_ (N_("Press any key to continue...")); (void) grub_getkey (); grub_putchar ('\n'); } +static void +print_spaces (int number_spaces) +{ + int i; + for (i = 0; i < number_spaces; i++) + grub_putchar (' '); +} + +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position) +{ + while (str < last_position) + { + grub_putcode (*str); + str++; + } +} + +int +grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, + grub_uint32_t **last_position) +{ + grub_ssize_t msg_len = grub_strlen (msg); + + *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t)); + + if (!*unicode_msg) + { + grub_printf ("utf8_to_ucs4 ERROR1: %s", msg); + return -1; + } + + msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len, + (grub_uint8_t *) msg, -1, 0); + + *last_position = *unicode_msg + msg_len; + + if (msg_len < 0) + { + grub_printf ("utf8_to_ucs4 ERROR2: %s", msg); + grub_free (*unicode_msg); + } + return msg_len; +} + +grub_ssize_t +grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position) +{ + grub_ssize_t width = 0; + + while (str < last_position) + { + width += grub_getcharwidth (*str); + str++; + } + return width; +} + +void +grub_print_message_indented (const char *msg, int margin_left, int margin_right) +{ + int line_len; + line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') * + (margin_left + margin_right); + + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + + int msg_len; + + msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position); + + if (msg_len < 0) + { + return; + } + + grub_uint32_t *current_position = unicode_msg; + + grub_uint32_t *next_new_line = unicode_msg; + + int first_loop = 1; + + while (current_position < last_position) + { + if (! first_loop) + grub_putchar ('\n'); + + next_new_line = (grub_uint32_t *) last_position; + + while (grub_getstringwidth (current_position, next_new_line) > line_len + || (*next_new_line != ' ' && next_new_line > current_position && + next_new_line != last_position)) + { + next_new_line--; + } + + if (next_new_line == current_position) + { + next_new_line = (next_new_line + line_len > last_position) ? + (grub_uint32_t *) last_position : next_new_line + line_len; + } + + print_spaces (margin_left); + grub_print_ucs4 (current_position, next_new_line); + + next_new_line++; + current_position = next_new_line; + first_loop = 0; + } + grub_free (unicode_msg); +} + + static void draw_border (void) { @@ -87,22 +203,33 @@ print_message (int nested, int edit) if (edit) { - grub_printf ("\n\ - Minimum Emacs-like screen editing is supported. TAB lists\n\ - completions. Press Ctrl-x to boot, Ctrl-c for a command-line\n\ - or ESC to return menu."); + grub_putchar ('\n'); + grub_print_message_indented (_("Minimum Emacs-like screen editing is \ +supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \ +command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN); } else { - grub_printf (_("\n\ - Use the %C and %C keys to select which entry is highlighted.\n"), - (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN); - grub_printf ("\ - Press enter to boot the selected OS, \'e\' to edit the\n\ - commands before booting or \'c\' for a command-line."); + const char *msg = _("Use the %C and %C keys to select which \ +entry is highlighted.\n"); + char *msg_translated = + grub_malloc (sizeof (char) * grub_strlen (msg) + 1); + + grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP, + (grub_uint32_t) GRUB_TERM_DISP_DOWN); + grub_putchar ('\n'); + grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN); + + grub_free (msg_translated); + + grub_print_message_indented (_("Press enter to boot the selected OS, \ +\'e\' to edit the commands before booting or \'c\' for a command-line.\n"), STANDARD_MARGIN, STANDARD_MARGIN); + if (nested) - grub_printf ("\n\ - ESC to return previous menu."); + { + grub_printf ("\n "); + grub_printf_ (N_("ESC to return previous menu.")); + } } } @@ -237,18 +364,26 @@ grub_menu_init_page (int nested, int edit) } static void -print_timeout (int timeout, int offset, int second_stage) +print_timeout (int timeout, int offset) { - /* NOTE: Do not remove the trailing space characters. - They are required to clear the line. */ - char *msg = " The highlighted entry will be booted automatically in %ds. "; - char *msg_end = grub_strchr (msg, '%'); + const char *msg = + _("The highlighted entry will be booted automatically in %ds."); + + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); + + char *msg_translated = + grub_malloc (sizeof (char) * grub_strlen (msg) + 5); + + grub_sprintf (msg_translated, msg, timeout); + grub_print_message_indented (msg_translated, 3, 0); + + int posx; + posx = grub_getxy() >> 8; + print_spaces (GRUB_TERM_WIDTH - posx - 1); - grub_gotoxy (second_stage ? (msg_end - msg) : 0, GRUB_TERM_HEIGHT - 3); - grub_printf (second_stage ? msg_end : msg, timeout); grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); grub_refresh (); -}; +} /* Show the menu and handle menu entry selection. Returns the menu entry index that should be executed or -1 if no entry should be executed (e.g., @@ -299,7 +434,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) timeout = grub_menu_get_timeout (); if (timeout > 0) - print_timeout (timeout, offset, 0); + print_timeout (timeout, offset); while (! grub_menu_viewer_should_return ()) { @@ -316,7 +451,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) timeout--; grub_menu_set_timeout (timeout); saved_time = current_time; - print_timeout (timeout, offset, 1); + print_timeout (timeout, offset); } } @@ -334,8 +469,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (timeout >= 0) { grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - grub_printf ("\ - "); + print_spaces (GRUB_TERM_WIDTH - 1); + grub_env_unset ("timeout"); grub_env_unset ("fallback"); grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); @@ -496,7 +631,9 @@ static void notify_booting (grub_menu_entry_t entry, void *userdata __attribute__((unused))) { - grub_printf (" Booting \'%s\'\n\n", entry->title); + grub_printf (" "); + grub_printf_ (N_("Booting \'%s\'"), entry->title); + grub_printf ("\n\n"); } /* Callback invoked when a default menu entry executed because of a timeout @@ -506,7 +643,9 @@ static void notify_fallback (grub_menu_entry_t entry, void *userdata __attribute__((unused))) { - grub_printf ("\n Falling back to \'%s\'\n\n", entry->title); + grub_printf ("\n "); + grub_printf_ (N_("Falling back to \'%s\'"), entry->title); + grub_printf ("\n\n"); grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS); } @@ -520,7 +659,8 @@ notify_execution_failure (void *userdata __attribute__((unused))) grub_print_error (); grub_errno = GRUB_ERR_NONE; } - grub_printf ("\n Failed to boot default entries.\n"); + grub_printf ("\n "); + grub_printf_ (N_("Failed to boot default entries.\n")); grub_wait_after_message (); } diff --git a/normal/misc.c b/normal/misc.c index 0a1a2f052..18e20d2fc 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -1,7 +1,7 @@ /* misc.c - miscellaneous functions */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ #include #include #include +#include +#include /* Print the information on the device NAME. */ grub_err_t @@ -34,13 +36,20 @@ grub_normal_print_device_info (const char *name) p = grub_strchr (name, ','); if (p) - grub_printf ("\tPartition %s: ", name); + { + grub_putchar ('\t'); + grub_printf_ (N_("Partition %s:"), name); + grub_putchar (' '); + } else - grub_printf ("Device %s: ", name); + { + grub_printf_ (N_("Device %s:"), name); + grub_putchar (' '); + } dev = grub_device_open (name); if (! dev) - grub_printf ("Filesystem cannot be accessed"); + grub_printf ("%s", _("Filesystem cannot be accessed")); else if (dev->disk) { grub_fs_t fs; @@ -51,7 +60,7 @@ grub_normal_print_device_info (const char *name) if (fs) { - grub_printf ("Filesystem type %s", fs->name); + grub_printf_ (N_("Filesystem type %s"), fs->name); if (fs->label) { char *label; @@ -59,7 +68,7 @@ grub_normal_print_device_info (const char *name) if (grub_errno == GRUB_ERR_NONE) { if (label && grub_strlen (label)) - grub_printf (", Label %s", label); + grub_printf_ (N_("- Label %s"), label); grub_free (label); } grub_errno = GRUB_ERR_NONE; @@ -72,8 +81,8 @@ grub_normal_print_device_info (const char *name) if (grub_errno == GRUB_ERR_NONE) { grub_unixtime2datetime (tm, &datetime); - grub_printf (", Last modification time %d-%02d-%02d " - "%02d:%02d:%02d %s", + grub_printf_ (N_("- Last modification time %d-%02d-%02d " + "%02d:%02d:%02d %s"), datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second, grub_get_weekday_name (&datetime)); @@ -95,13 +104,13 @@ grub_normal_print_device_info (const char *name) } } else if (! dev->disk->has_partitions || dev->disk->partition) - grub_printf ("Unknown filesystem"); + grub_printf ("%s", _("Unknown filesystem")); else - grub_printf ("Partition table"); + grub_printf ("%s", _("Partition table")); grub_device_close (dev); } - grub_printf ("\n"); + grub_putchar ('\n'); return grub_errno; } diff --git a/po/POTFILES b/po/POTFILES index c0fc40c30..c214eb968 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,4 +1,6 @@ # List of files which contain translatable strings. +commands/loadenv.c + util/i386/pc/grub-mkimage.c util/i386/pc/grub-setup.c @@ -11,4 +13,9 @@ util/mkisofs/rock.c util/mkisofs/tree.c util/mkisofs/write.c +normal/auth.c +normal/color.c +normal/main.c +normal/menu_entry.c normal/menu_text.c +normal/misc.c diff --git a/script/execute.c b/script/execute.c index e9064ad2f..08224fc7d 100644 --- a/script/execute.c +++ b/script/execute.c @@ -113,13 +113,13 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) if (eq) { + /* This was set because the command was not found. */ + grub_errno = GRUB_ERR_NONE; + /* Create two strings and set the variable. */ *eq = '\0'; eq++; grub_env_set (assign, eq); - - /* This was set because the command was not found. */ - grub_errno = GRUB_ERR_NONE; } grub_free (assign); diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index c61e16eb7..ab11e9fb2 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -1,7 +1,7 @@ /* ofconsole.c -- Open Firmware console for GRUB. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,17 +43,17 @@ struct color int blue; }; -#define MAX 0xff -static struct color colors[8] = +static struct color colors[] = { - { 0, 0, 0}, - { MAX, 0, 0}, - { 0, MAX, 0}, - { MAX, MAX, 0}, - { 0, 0, MAX}, - { MAX, 0, MAX}, - { 0, MAX, MAX}, - { MAX, MAX, MAX} + // {R, G, B} + {0x00, 0x00, 0x00}, + {0x00, 0x00, 0xA8}, // 1 = blue + {0x00, 0xA8, 0x00}, // 2 = green + {0x00, 0xA8, 0xA8}, // 3 = cyan + {0xA8, 0x00, 0x00}, // 4 = red + {0xA8, 0x00, 0xA8}, // 5 = magenta + {0xFE, 0xFE, 0x54}, // 6 = yellow + {0xFE, 0xFE, 0xFE} // 7 = white }; static grub_uint8_t grub_ofconsole_normal_color = 0x7; @@ -131,8 +131,9 @@ static void grub_ofconsole_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) { - grub_ofconsole_normal_color = normal_color; - grub_ofconsole_highlight_color = highlight_color; + /* Discard bright bit. */ + grub_ofconsole_normal_color = normal_color & 0x77; + grub_ofconsole_highlight_color = highlight_color & 0x77; } static void @@ -354,7 +355,6 @@ static grub_err_t grub_ofconsole_init_output (void) { grub_ssize_t actual; - int col; /* The latest PowerMacs don't actually initialize the screen for us, so we * use this trick to re-open the output device (but we avoid doing this on @@ -370,7 +370,8 @@ grub_ofconsole_init_output (void) /* Initialize colors. */ if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)) { - for (col = 0; col < 7; col++) + unsigned col; + for (col = 0; col < ARRAY_SIZE (colors); col++) grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red, colors[col].green, colors[col].blue); diff --git a/util/getroot.c b/util/getroot.c index a3c03d0b0..22ad7e967 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -483,12 +483,12 @@ grub_util_is_dmraid (const char *os_dev) return 1; else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) return 1; - + return 0; } int -grub_util_get_dev_abstraction (const char *os_dev UNUSED) +grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { #ifdef __linux__ /* Check for LVM. */ @@ -546,7 +546,7 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "md%s", p); + grub_dev = xasprintf ("md%s", p); free (p); } else if (os_dev[7] == '/' && os_dev[8] == 'd') @@ -561,7 +561,7 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "md%s", p); + grub_dev = xasprintf ("md%s", p); free (p); } else if (os_dev[7] >= '0' && os_dev[7] <= '9') @@ -574,7 +574,7 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "md%s", p); + grub_dev = xasprintf ("md%s", p); free (p); } else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9') @@ -587,7 +587,7 @@ grub_util_get_grub_dev (const char *os_dev) if (q) *q = ','; - asprintf (&grub_dev, "md%s", p); + grub_dev = xasprintf ("md%s", p); free (p); } else diff --git a/util/grub-editenv.c b/util/grub-editenv.c index 842c5a103..68fb23b15 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -107,7 +107,7 @@ create_envblk_file (const char *name) if (! buf) grub_util_error ("out of memory"); - asprintf (&namenew, "%s.new", name); + namenew = xasprintf ("%s.new", name); fp = fopen (namenew, "wb"); if (! fp) grub_util_error ("cannot open the file %s", namenew); diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 03184b632..fa54fe414 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -85,7 +85,7 @@ execute_command (char *name, int n, char **args) #define BUF_SIZE 32256 -static grub_off_t skip, leng; +static grub_disk_addr_t skip, leng; static void read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) @@ -140,7 +140,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) if (skip > file->size) { - grub_util_error ("invalid skip value %d."); + grub_util_error ("invalid skip value %lld.", (unsigned long long) skip); return; } diff --git a/util/grub-install.in b/util/grub-install.in index 1cf7135fd..d11432de4 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -248,6 +248,14 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then done fi +# Copy gettext files +mkdir -p ${grubdir}/locale/ +for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do + if test -f "$file"; then + cp -f "$file" ${grubdir}/locale/ + fi +done + # Write device to a variable so we don't have to traverse /dev every time. grub_device=`$grub_probe --target=device ${grubdir}` diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index a8c267518..49e52b313 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -144,13 +144,9 @@ case x${GRUB_TERMINAL_OUTPUT} in x | xgfxterm) # If this platform supports gfxterm, try to use it. if test -e ${grub_prefix}/gfxterm.mod ; then - GRUB_VIDEO_BACKEND= - for i in vbe ; do - if test -e ${grub_prefix}/$i.mod ; then - GRUB_VIDEO_BACKEND=$i - break - fi - done + # FIXME: this should do something smarter than just loading first + # video backend. + GRUB_VIDEO_BACKEND=$(head -n 1 ${grub_prefix}/video.lst || true) if [ -n "${GRUB_VIDEO_BACKEND}" ] ; then GRUB_TERMINAL_OUTPUT=gfxterm elif [ "${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index d18002ce4..1f71d9641 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -24,8 +24,12 @@ bindir=@bindir@ sbindir=@sbindir@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` -grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` -grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` +if test "x$grub_probe" = x; then + grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +fi +if test "x$grub_mkrelpath" = x; then + grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` +fi grub_warn () { @@ -104,7 +108,7 @@ prepare_grub_to_access_device () # Abstraction modules aren't auto-loaded. abstraction="`${grub_probe} --device ${device} --target=abstraction`" - for module in ${abstraction} ; do + for module in ${abstraction} ; do echo "insmod ${module}" done diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 40d145fd3..9775e0803 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -366,8 +366,8 @@ write_font (struct grub_font_info *font_info, char *output_file) if (! style_name[0]) strcpy (style_name, " Regular"); - asprintf (&font_name, "%s %s %d", font_info->name, &style_name[1], - font_info->size); + font_name = xasprintf ("%s %s %d", font_info->name, &style_name[1], + font_info->size); write_string_section ("NAME", font_name, &offset, file); write_string_section ("FAMI", font_info->name, &offset, file); diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index a20109628..956e52ed7 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -27,6 +27,7 @@ static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, + {0, 0, 0, 0}, }; static void diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 51639ccb1..6b3c9ecb8 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -28,6 +28,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ native_platform=@platform@ +pkglib_DATA="@pkglib_DATA@" coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc @@ -93,13 +94,23 @@ process_input_dir () input_dir="$1" platform="$2" mkdir -p ${iso9660_dir}/boot/grub/${target_cpu}-${platform} - for file in ${input_dir}/*.mod ${input_dir}/efiemu??.o \ - ${input_dir}/command.lst ${input_dir}/moddep.lst ${input_dir}/fs.lst \ - ${input_dir}/handler.lst ${input_dir}/parttool.lst; do + for file in ${input_dir}/*.mod; do if test -f "$file"; then cp -f "$file" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ fi done + for file in ${pkglib_DATA}; do + if test -f "${input_dir}/${file}"; then + cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + fi + done + + mkdir -p ${iso9660_dir}/boot/grub/locale + for file in ${input_dir}/po/*.mo; do + if test -f "$file"; then + cp -f "$file" ${iso9660_dir}/boot/grub/locale/ + fi + done } if [ "${override_dir}" = "" ] ; then @@ -121,7 +132,7 @@ fi # build coreboot core.img if test -e "${coreboot_dir}" ; then - echo "Generates coreboot" + echo "Enabling coreboot support ..." memdisk_img=`mktemp` memdisk_dir=`mktemp -d` mkdir -p ${memdisk_dir}/boot/grub @@ -148,14 +159,17 @@ EOF grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" fi -# build eltorito core.img +# build BIOS core.img if test -e "${pc_dir}" ; then - echo "Generates eltorito" + echo "Enabling BIOS support ..." core_img=`mktemp` grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ - memdisk tar search iso9660 configfile sh \ - biosdisk + iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img + + embed_img=`mktemp` + cat ${pc_dir}/boot.img ${core_img} > ${embed_img} + rm -f ${core_img} modules="$(cat ${pc_dir}/partmap.lst) ${modules}" @@ -165,11 +179,14 @@ if test -e "${pc_dir}" ; then echo "source /boot/grub/grub.cfg") \ > ${iso9660_dir}/boot/grub/i386-pc/grub.cfg - grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -boot-info-table" + grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -boot-info-table \ + --embedded-boot ${embed_img}" fi # build iso image -grub-mkisofs ${grub_mkisofs_arguments} -o ${output_image} -r ${iso9660_dir} ${source} +grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} +rm -f ${embed_img} + exit 0 diff --git a/util/grub-probe.c b/util/grub-probe.c index 2b9784123..1958308c3 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -123,7 +123,7 @@ probe (const char *path, char *device_name) device_name = grub_guess_root_device (path); if (! device_name) - grub_util_error ("cannot find a device for %s.\n", path); + grub_util_error ("cannot find a device for %s (is /dev mounted?).\n", path); if (print == PRINT_DEVICE) { @@ -254,7 +254,7 @@ probe (const char *path, char *device_name) filebuf_via_sys = grub_util_read_image (path); rel_path = make_system_path_relative_to_its_root (path); - asprintf (&grub_path, "(%s)%s", drive_name, rel_path); + grub_path = xasprintf ("(%s)%s", drive_name, rel_path); free (rel_path); grub_util_info ("reading %s via GRUB facilities", grub_path); file = grub_file_open (grub_path); diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 577a12722..0adfe6b76 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -115,12 +115,12 @@ if [ "x${LANG}" != "xC" ] ; then cat << EOF set locale_dir=${locale_dir} set lang=${grub_lang} -insmod gettext +insmod gettext EOF fi if [ "x${GRUB_HIDDEN_TIMEOUT}" != "x" ] ; then - if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then + if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then verbose= else verbose=" --verbose" diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 0e71096d1..aaca597be 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -37,6 +37,56 @@ if [ -z "${OSPROBED}" ] ; then exit 0 fi +osx_entry() { + cat << EOF +menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" { +EOF + prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" + cat << EOF + insmod ${GRUB_VIDEO_BACKEND} + do_resume=0 + if [ /var/vm/sleepimage -nt10 / ]; then + if xnu_resume /var/vm/sleepimage; then + do_resume=1 + fi + fi + if [ \$do_resume == 0 ]; then + xnu_uuid ${OSXUUID} uuid + if [ -f /Extra/DSDT.aml ]; then + acpi -e /Extra/DSDT.aml + fi + $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid + if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then + xnu_mkext /System/Library/Extensions.mkext + else + xnu_kextdir /System/Library/Extensions + fi + if [ -f /Extra/Extensions.mkext ]; then + xnu_mkext /Extra/Extensions.mkext + fi + if [ -d /Extra/Extensions ]; then + xnu_kextdir /Extra/Extensions + fi + if [ -f /Extra/devprop.bin ]; then + xnu_devprop_load /Extra/devprop.bin + fi + if [ -f /Extra/splash.jpg ]; then + insmod jpeg + xnu_splash /Extra/splash.jpg + fi + if [ -f /Extra/splash.png ]; then + insmod png + xnu_splash /Extra/splash.png + fi + if [ -f /Extra/splash.tga ]; then + insmod tga + xnu_splash /Extra/splash.tga + fi + fi +} +EOF +} + for OS in ${OSPROBED} ; do DEVICE="`echo ${OS} | cut -d ':' -f 1`" LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" @@ -116,55 +166,8 @@ EOF ;; macosx) OSXUUID="`grub-probe --target=fs_uuid --device ${DEVICE} 2> /dev/null`" - cat << EOF -menuentry "${LONGNAME} (on ${DEVICE})" { -EOF - save_default_entry | sed -e "s/^/\t/" - save_default_entry | sed -e "s/^/\t/" - prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" - cat << EOF - insmod vbe - do_resume=0 - if [ /var/vm/sleepimage -nt10 / ]; then - if xnu_resume /var/vm/sleepimage; then - do_resume=1 - fi - fi - if [ \$do_resume == 0 ]; then - xnu_uuid ${OSXUUID} uuid - if [ -f /Extra/DSDT.aml ]; then - acpi -e /Extra/DSDT.aml - fi - xnu_kernel /mach_kernel boot-uuid=\${uuid} rd=*uuid - if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then - xnu_mkext /System/Library/Extensions.mkext - else - xnu_kextdir /System/Library/Extensions - fi - if [ -f /Extra/Extensions.mkext ]; then - xnu_mkext /Extra/Extensions.mkext - fi - if [ -d /Extra/Extensions ]; then - xnu_kextdir /Extra/Extensions - fi - if [ -f /Extra/devtree.txt ]; then - xnu_devtree /Extra/devtree.txt - fi - if [ -f /Extra/splash.jpg ]; then - insmod jpeg - xnu_splash /Extra/splash.jpg - fi - if [ -f /Extra/splash.png ]; then - insmod png - xnu_splash /Extra/splash.png - fi - if [ -f /Extra/splash.tga ]; then - insmod tga - xnu_splash /Extra/splash.tga - fi - fi -} -EOF + osx_entry xnu_kernel 32 + osx_entry xnu_kernel64 64 ;; hurd) cat << EOF diff --git a/util/hostdisk.c b/util/hostdisk.c index 04c412300..11caaf407 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -679,14 +679,14 @@ make_device_name (int drive, int dos_part, int bsd_part) char *bsd_part_str = NULL; if (dos_part >= 0) - asprintf (&dos_part_str, ",%d", dos_part + 1); + dos_part_str = xasprintf (",%d", dos_part + 1); if (bsd_part >= 0) - asprintf (&bsd_part_str, ",%c", dos_part + 'a'); + bsd_part_str = xasprintf (",%c", dos_part + 'a'); - asprintf (&ret, "%s%s%s", map[drive].drive, - dos_part_str ? : "", - bsd_part_str ? : ""); + ret = xasprintf ("%s%s%s", map[drive].drive, + dos_part_str ? : "", + bsd_part_str ? : ""); if (dos_part_str) free (dos_part_str); diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree index bc13e3c35..25aa35e23 100644 --- a/util/i386/efi/grub-dumpdevtree +++ b/util/i386/efi/grub-dumpdevtree @@ -15,11 +15,8 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . -hexify() -{ - echo -n "$@" | od -A n -t x1 - | sed -e 's/ //g' | tr '\n' '\0' -} +if [ x$1 == x ]; then + echo "Filename required". +fi -echo "`hexify efi`{ `hexify device-properties`:" -ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' -echo ";}" +ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' | xxd -r -p > $1 diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c index 401c5006c..7f5141531 100644 --- a/util/i386/efi/grub-mkimage.c +++ b/util/i386/efi/grub-mkimage.c @@ -55,12 +55,12 @@ align_pe32_section (Elf_Addr addr) /* Read the whole kernel image. Return the pointer to a read image, and store the size in bytes in *SIZE. */ static char * -read_kernel_module (const char *dir, size_t *size) +read_kernel_image (const char *dir, size_t *size) { char *kernel_image; char *kernel_path; - kernel_path = grub_util_get_path (dir, "kernel.mod"); + kernel_path = grub_util_get_path (dir, "kernel.img"); *size = grub_util_get_image_size (kernel_path); kernel_image = grub_util_read_image (kernel_path); free (kernel_path); @@ -945,7 +945,7 @@ convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) int i; /* Get the kernel image and check the format. */ - kernel_image = read_kernel_module (dir, &kernel_size); + kernel_image = read_kernel_image (dir, &kernel_size); e = (Elf_Ehdr *) kernel_image; if (! check_elf_header (e, kernel_size)) grub_util_error ("invalid ELF header"); diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c index 785ea8c71..3c2cb7549 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/i386/pc/grub-mkimage.c @@ -204,19 +204,19 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); if (num > 0xffff) grub_util_error (_("the core image is too big")); - + boot_path = grub_util_get_path (dir, "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); if (boot_size != GRUB_DISK_SECTOR_SIZE) grub_util_error (_("diskboot.img size must be %u bytes"), GRUB_DISK_SECTOR_SIZE); - + boot_img = grub_util_read_image (boot_path); - + /* i386 is a little endian architecture. */ *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) = grub_cpu_to_le16 (num); - + grub_util_write_image (boot_img, boot_size, out); free (boot_img); free (boot_path); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 1c7e8452f..c2b9b9268 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -356,8 +356,12 @@ setup (const char *dir, goto unable_to_embed; } - grub_partition_iterate (dest_dev->disk, (strcmp (dest_partmap, "part_msdos") ? - find_usable_region_gpt : find_usable_region_msdos)); + if (strcmp (dest_partmap, "part_msdos") == 0) + grub_partition_iterate (dest_dev->disk, find_usable_region_msdos); + else if (strcmp (dest_partmap, "part_gpt") == 0) + grub_partition_iterate (dest_dev->disk, find_usable_region_gpt); + else + grub_util_error (_("No DOS-style partitions found")); if (embed_region.end == embed_region.start) { diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c index bddfc17e7..19ab746ef 100644 --- a/util/ieee1275/devicemap.c +++ b/util/ieee1275/devicemap.c @@ -35,8 +35,10 @@ escape_of_path (const char *orig_path) } void -grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED, - int *num_fd UNUSED, int *num_hd UNUSED) +grub_util_emit_devicemap_entry (FILE *fp, char *name, + int is_floppy __attribute__((unused)), + int *num_fd __attribute__((unused)), + int *num_hd __attribute__((unused))) { const char *orig_path = grub_util_devname_to_ofpath (name); char *ofpath = escape_of_path (orig_path); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 7b464bf09..e90488fc3 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -39,7 +39,6 @@ #include #ifdef OFPATH_STANDALONE -#define UNUSED __attribute__((unused)) #define xmalloc malloc void grub_util_error (const char *fmt, ...) @@ -199,8 +198,10 @@ get_basename(char *p) static void of_path_of_vdisk(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), + const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int devno, junk; @@ -217,8 +218,9 @@ of_path_of_vdisk(char *of_path, static void of_path_of_ide(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int chan, devno; @@ -299,8 +301,9 @@ check_sas (char *sysfs_path, int *tgt) static void of_path_of_scsi(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { const char *p, *digit_string, *disk_name; int host, bus, tgt, lun; diff --git a/util/misc.c b/util/misc.c index 626851306..5896da0c8 100644 --- a/util/misc.c +++ b/util/misc.c @@ -370,6 +370,19 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), { } +#ifndef HAVE_VASPRINTF + +int +vasprintf (char **buf, const char *fmt, va_list ap) +{ + /* Should be large enough. */ + *buf = xmalloc (512); + + return vsprintf (*buf, fmt, ap); +} + +#endif + #ifndef HAVE_ASPRINTF int @@ -378,11 +391,8 @@ asprintf (char **buf, const char *fmt, ...) int status; va_list ap; - /* Should be large enough. */ - *buf = xmalloc (512); - va_start (ap, fmt); - status = vsprintf (*buf, fmt, ap); + status = vasprintf (*buf, fmt, ap); va_end (ap); return status; @@ -390,6 +400,23 @@ asprintf (char **buf, const char *fmt, ...) #endif +char * +xasprintf (const char *fmt, ...) +{ + va_list ap; + char *result; + + va_start (ap, fmt); + if (vasprintf (&result, fmt, ap) < 0) + { + if (errno == ENOMEM) + grub_util_error ("out of memory"); + return NULL; + } + + return result; +} + #ifdef __MINGW32__ void sync (void) @@ -500,7 +527,17 @@ make_system_path_relative_to_its_root (const char *path) /* buf is another filesystem; we found it. */ if (st.st_dev != num) - break; + { + /* offset == 0 means path given is the mount point. */ + if (offset == 0) + { + free (buf); + free (buf2); + return strdup ("/"); + } + else + break; + } offset = p - buf; /* offset == 1 means root directory. */ diff --git a/util/mkisofs/eltorito.c b/util/mkisofs/eltorito.c index 05a9040d6..a134dfc48 100644 --- a/util/mkisofs/eltorito.c +++ b/util/mkisofs/eltorito.c @@ -1,6 +1,6 @@ /* * Program eltorito.c - Handle El Torito specific extensions to iso9660. - * + * Written by Michael Fulbright (1996). @@ -53,7 +53,7 @@ static struct eltorito_boot_descriptor gboot_desc; static int tvd_write __PR((FILE * outfile)); /* - * Check for presence of boot catalog. If it does not exist then make it + * Check for presence of boot catalog. If it does not exist then make it */ void FDECL1(init_boot_catalog, const char *, path) { @@ -61,37 +61,37 @@ void FDECL1(init_boot_catalog, const char *, path) char * bootpath; /* filename of boot catalog */ char * buf; struct stat statbuf; - + bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2); strcpy(bootpath, path); - if (bootpath[strlen(bootpath)-1] != '/') + if (bootpath[strlen(bootpath)-1] != '/') { strcat(bootpath,"/"); } - + strcat(bootpath, boot_catalog); - + /* - * check for the file existing + * check for the file existing */ #ifdef DEBUG_TORITO fprintf(stderr,"Looking for boot catalog file %s\n",bootpath); #endif - - if (!stat_filter(bootpath, &statbuf)) + + if (!stat_filter(bootpath, &statbuf)) { /* - * make sure its big enough to hold what we want + * make sure its big enough to hold what we want */ - if (statbuf.st_size == 2048) + if (statbuf.st_size == 2048) { /* - * printf("Boot catalog exists, so we do nothing\n"); + * printf("Boot catalog exists, so we do nothing\n"); */ free(bootpath); return; } - else + else { fprintf (stderr, _("A boot catalog exists and appears corrupted.\n")); fprintf (stderr, _("Please check the following file: %s.\n"), bootpath); @@ -100,15 +100,15 @@ void FDECL1(init_boot_catalog, const char *, path) exit (1); } } - + /* - * file does not exist, so we create it + * file does not exist, so we create it * make it one CD sector long */ bcat = fopen (bootpath, "wb"); if (bcat == NULL) error (1, errno, _("Error creating boot catalog (%s)"), bootpath); - + buf = (char *) e_malloc( 2048 ); if (fwrite (buf, 1, 2048, bcat) != 2048) error (1, errno, _("Error writing to boot catalog (%s)"), bootpath); @@ -127,65 +127,65 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) struct directory_entry * de2; unsigned int i; int nsectors; - + memset(boot_desc, 0, sizeof(*boot_desc)); boot_desc->id[0] = 0; memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); boot_desc->version[0] = 1; - + memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID)); - + /* - * search from root of iso fs to find boot catalog + * search from root of iso fs to find boot catalog */ de2 = search_tree_file(root, boot_catalog); - if (!de2) + if (!de2) { fprintf (stderr, _("Boot catalog cannot be found!\n")); exit (1); } - + set_731(boot_desc->bootcat_ptr, (unsigned int) get_733(de2->isorec.extent)); - - /* + + /* * now adjust boot catalog - * lets find boot image first + * lets find boot image first */ de=search_tree_file(root, boot_image); - if (!de) + if (!de) { fprintf (stderr, _("Boot image cannot be found!\n")); exit (1); - } - - /* + } + + /* * we have the boot image, so write boot catalog information - * Next we write out the primary descriptor for the disc + * Next we write out the primary descriptor for the disc */ memset(&valid_desc, 0, sizeof(valid_desc)); valid_desc.headerid[0] = 1; valid_desc.arch[0] = EL_TORITO_ARCH_x86; - + /* * we'll shove start of publisher id into id field, may get truncated * but who really reads this stuff! */ if (publisher) memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher))); - + valid_desc.key1[0] = 0x55; valid_desc.key2[0] = 0xAA; - + /* - * compute the checksum + * compute the checksum */ checksum=0; checksum_ptr = (unsigned char *) &valid_desc; - for (i=0; isize + 511) & ~(511))/512; - fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors); - fprintf (stderr, " -> "); + fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors); + fprintf (stderr, " -> "); if (! use_eltorito_emul_floppy) { default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL; fprintf (stderr, _("No emulation\n")); } - else if (nsectors == 2880 ) + else if (nsectors == 2880 ) /* - * choose size of emulated floppy based on boot image size + * choose size of emulated floppy based on boot image size */ { default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP; fprintf (stderr, _("Emulating a 1.44 meg floppy\n")); } - else if (nsectors == 5760 ) + else if (nsectors == 5760 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP; fprintf (stderr, _("Emulating a 2.88 meg floppy\n")); } - else if (nsectors == 2400 ) + else if (nsectors == 2400 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP; fprintf (stderr, _("Emulating a 1.2 meg floppy\n")); } - else + else { fprintf (stderr, _("\nError - boot image is not the an allowable size.\n")); exit (1); } - - /* - * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! + + /* + * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! */ nsectors = 1; set_721(default_desc.nsect, (unsigned int) nsectors ); #ifdef DEBUG_TORITO fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent)); #endif - set_731(default_desc.bootoff, + set_731(default_desc.bootoff, (unsigned int) get_733(de->isorec.extent)); - + /* - * now write it to disk + * now write it to disk */ bootcat = fopen (de2->whole_name, "r+b"); - if (bootcat == NULL) + if (bootcat == NULL) error (1, errno, _("Error opening boot catalog for update")); - /* - * write out + /* + * write out */ if (fwrite (&valid_desc, 1, 32, bootcat) != 32) error (1, errno, _("Error writing to boot catalog")); @@ -332,7 +332,7 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) static int FDECL1(tvd_write, FILE *, outfile) { /* - * Next we write out the boot volume descriptor for the disc + * Next we write out the boot volume descriptor for the disc */ get_torito_desc(&gboot_desc); xfwrite(&gboot_desc, 1, 2048, outfile); diff --git a/util/mkisofs/exclude.h b/util/mkisofs/exclude.h index 87cd6948a..ac1a561ad 100644 --- a/util/mkisofs/exclude.h +++ b/util/mkisofs/exclude.h @@ -1,6 +1,6 @@ /* * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: - * added 'exclude' option (-x) to specify pathnames NOT to be included in + * added 'exclude' option (-x) to specify pathnames NOT to be included in * CD image. * * $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $ diff --git a/util/mkisofs/hash.c b/util/mkisofs/hash.c index 4d26e4dba..41e76b342 100644 --- a/util/mkisofs/hash.c +++ b/util/mkisofs/hash.c @@ -33,7 +33,7 @@ void FDECL1(add_hash, struct directory_entry *, spnt){ struct file_hash * s_hash; unsigned int hash_number; - if(spnt->size == 0 || spnt->starting_block == 0) + if(spnt->size == 0 || spnt->starting_block == 0) if(spnt->size != 0 || spnt->starting_block != 0) { fprintf(stderr,"Non zero-length file assigned zero extent.\n"); exit(1); @@ -116,10 +116,10 @@ static unsigned int FDECL1(name_hash, const char *, name) { unsigned int hash = 0; const char * p; - + p = name; - - while (*p) + + while (*p) { /* * Don't hash the iso9660 version number. This way @@ -155,7 +155,7 @@ struct directory_entry * FDECL1(find_file_hash, char *, name) struct name_hash * nh; char * p1; char * p2; - + for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) { p1 = name; @@ -220,6 +220,6 @@ void flush_file_hash(){ nh = nh1; } name_hash_table[i] = NULL; - + } } diff --git a/util/mkisofs/iso9660.h b/util/mkisofs/iso9660.h index 5818ee81c..78a05db92 100644 --- a/util/mkisofs/iso9660.h +++ b/util/mkisofs/iso9660.h @@ -138,7 +138,7 @@ struct eltorito_boot_info char pvd_addr[ISODCL (1, 4)]; /* Boot file address. */ char file_addr[ISODCL (5, 8)]; - /* Boot file length. */ + /* Boot file length. */ char file_length[ISODCL (9, 12)]; /* Boot file checksum. */ char file_checksum[ISODCL (13, 16)]; diff --git a/util/mkisofs/joliet.c b/util/mkisofs/joliet.c index 736037df9..b3c755792 100644 --- a/util/mkisofs/joliet.c +++ b/util/mkisofs/joliet.c @@ -87,13 +87,13 @@ static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir)); static void DECL(assign_joliet_directory_addresses, (struct directory * node)); static int jroot_gen __PR((void)); -/* +/* * Function: convert_to_unicode * * Purpose: Perform a 1/2 assed unicode conversion on a text * string. * - * Notes: + * Notes: */ static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source ) { @@ -127,9 +127,9 @@ static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char * JS integrated from: Achim_Kaiser@t-online.de * * Let all valid unicode characters pass through (assuming ISO-8859-1). - * Others are set to '_' . - */ - if( tmpbuf[j] != 0 && + * Others are set to '_' . + */ + if( tmpbuf[j] != 0 && (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) ) { buffer[i+1] = '_'; @@ -163,7 +163,7 @@ static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char } } -/* +/* * Function: joliet_strlen * * Purpose: Return length in bytes of string after conversion to unicode. @@ -178,7 +178,7 @@ static int FDECL1(joliet_strlen, const char *, string) rtn = strlen(string) << 1; - /* + /* * We do clamp the maximum length of a Joliet string to be the * maximum path size. This helps to ensure that we don't completely * bolix things up with very long paths. The Joliet specs say @@ -191,7 +191,7 @@ static int FDECL1(joliet_strlen, const char *, string) return rtn; } -/* +/* * Function: get_joliet_vol_desc * * Purpose: generate a Joliet compatible volume desc. @@ -212,7 +212,7 @@ static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_de * "expands" 8 bit character codes to 16 bits and does nothing * special with the Unicode characters, therefore shouldn't mkisofs * really be stating that it's using UCS-2 Level 1, not Level 3 for - * the Joliet directory tree. + * the Joliet directory tree. */ strcpy(jvol_desc->escape_sequences, "%/@"); @@ -228,7 +228,7 @@ static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_de /* * Set this one up. */ - memcpy(jvol_desc->root_directory_record, &jroot_record, + memcpy(jvol_desc->root_directory_record, &jroot_record, sizeof(struct iso_directory_record)); /* @@ -256,7 +256,7 @@ static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) struct directory * dpnt; dpnt = node; - + while (dpnt) { if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) @@ -275,7 +275,7 @@ static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) } /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) + if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) { assign_joliet_directory_addresses(dpnt->subdir); } @@ -283,13 +283,13 @@ static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) } } -static +static void FDECL1(build_jpathlist, struct directory *, node) { struct directory * dpnt; - + dpnt = node; - + while (dpnt) { @@ -302,7 +302,7 @@ void FDECL1(build_jpathlist, struct directory *, node) } } /* build_jpathlist(... */ -static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) +static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) { struct directory const *ll = *(struct directory * const *)l; struct directory const *rr = *(struct directory * const *)r; @@ -325,13 +325,13 @@ static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) return -1; } - if (rparent > lparent) + if (rparent > lparent) { return 1; } return strcmp(rr->self->name, ll->self->name); - + } /* compare_paths(... */ static int generate_joliet_path_tables() @@ -346,7 +346,7 @@ static int generate_joliet_path_tables() int tablesize; /* - * First allocate memory for the tables and initialize the memory + * First allocate memory for the tables and initialize the memory */ tablesize = jpath_blocks << 11; jpath_table_m = (char *) e_malloc(tablesize); @@ -361,10 +361,10 @@ static int generate_joliet_path_tables() exit (1); } /* - * Now start filling in the path tables. Start with root directory + * Now start filling in the path tables. Start with root directory */ jpath_table_index = 0; - jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) + jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) * next_jpath_index); memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index); build_jpathlist(root); @@ -373,10 +373,10 @@ static int generate_joliet_path_tables() { fix = 0; #ifdef __STDC__ - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), + qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), (int (*)(const void *, const void *))joliet_compare_paths); #else - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), + qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), joliet_compare_paths); #endif @@ -399,20 +399,20 @@ static int generate_joliet_path_tables() exit (1); } npnt = dpnt->de_name; - + npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { + if(npnt1) + { npnt = npnt1 + 1; } - + de = dpnt->self; - if(!de) + if(!de) { - fprintf (stderr, _("Fatal goof - directory has amnesia\n")); + fprintf (stderr, _("Fatal goof - directory has amnesia\n")); exit (1); } - + namelen = joliet_strlen(de->name); if( dpnt == root ) @@ -426,28 +426,28 @@ static int generate_joliet_path_tables() jpath_table_m[jpath_table_index] = namelen; } jpath_table_index += 2; - - set_731(jpath_table_l + jpath_table_index, dpnt->jextent); - set_732(jpath_table_m + jpath_table_index, dpnt->jextent); + + set_731(jpath_table_l + jpath_table_index, dpnt->jextent); + set_732(jpath_table_m + jpath_table_index, dpnt->jextent); jpath_table_index += 4; - + if( dpnt->parent != reloc_dir ) { - set_721(jpath_table_l + jpath_table_index, - dpnt->parent->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->parent->jpath_index); + set_721(jpath_table_l + jpath_table_index, + dpnt->parent->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->parent->jpath_index); } else { - set_721(jpath_table_l + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); + set_721(jpath_table_l + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); } jpath_table_index += 2; - + /* * The root directory is still represented in non-unicode fashion. */ @@ -459,19 +459,19 @@ static int generate_joliet_path_tables() } else { - convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index, + convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index, namelen, de->name); - convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index, + convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index, namelen, de->name); jpath_table_index += namelen; } - if(jpath_table_index & 1) + if(jpath_table_index & 1) { jpath_table_index++; /* For odd lengths we pad */ } } - + free(jpathlist); if(jpath_table_index != jpath_table_size) { @@ -493,20 +493,20 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE unsigned int total_size; int cvt_len; struct directory * finddir; - + total_size = (dpnt->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); directory_buffer = (char *) e_malloc(total_size); memset(directory_buffer, 0, total_size); dir_index = 0; - + s_entry = dpnt->jcontents; - while(s_entry) + while(s_entry) { if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { s_entry = s_entry->jnext; continue; } - + /* * If this entry was a directory that was relocated, we have a bit * of trouble here. We need to dig out the real thing and put it @@ -535,43 +535,43 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE { s_entry1 = s_entry; } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector + + /* + * We do not allow directory entries to cross sector boundaries. + * Simply pad, and then start the next entry at the next sector */ new_reclen = s_entry1->jreclen; if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & + dir_index = (dir_index + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); } - + memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) - sizeof(s_entry1->isorec.name)); - + cvt_len = joliet_strlen(s_entry1->name); - + /* * Fix the record length - this was the non-Joliet version we * were seeing. */ jrec.name_len[0] = cvt_len; jrec.length[0] = s_entry1->jreclen; - + /* * If this is a directory, fix the correct size and extent * number. */ if( (jrec.flags[0] & 2) != 0 ) { - if(strcmp(s_entry1->name,".") == 0) + if(strcmp(s_entry1->name,".") == 0) { jrec.name_len[0] = 1; set_733((char *) jrec.extent, dpnt->jextent); set_733((char *) jrec.size, ROUND_UP(dpnt->jsize)); } - else if(strcmp(s_entry1->name,"..") == 0) + else if(strcmp(s_entry1->name,"..") == 0) { jrec.name_len[0] = 1; if( dpnt->parent == reloc_dir ) @@ -600,7 +600,7 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE { if(finddir->self == s_entry1) break; finddir = finddir->next; - if(!finddir) + if(!finddir) { fprintf (stderr, _("Fatal goof - unable to find directory location\n")); exit (1); @@ -610,25 +610,25 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE set_733((char *) jrec.size, ROUND_UP(finddir->jsize)); } } - - memcpy(directory_buffer + dir_index, &jrec, + + memcpy(directory_buffer + dir_index, &jrec, sizeof(struct iso_directory_record) - sizeof(s_entry1->isorec.name)); - - - dir_index += sizeof(struct iso_directory_record) - + + + dir_index += sizeof(struct iso_directory_record) - sizeof (s_entry1->isorec.name); - + /* * Finally dump the Unicode version of the filename. * Note - . and .. are the same as with non-Joliet discs. */ - if( (jrec.flags[0] & 2) != 0 + if( (jrec.flags[0] & 2) != 0 && strcmp(s_entry1->name, ".") == 0 ) { directory_buffer[dir_index++] = 0; } - else if( (jrec.flags[0] & 2) != 0 + else if( (jrec.flags[0] & 2) != 0 && strcmp(s_entry1->name, "..") == 0 ) { directory_buffer[dir_index++] = 1; @@ -640,7 +640,7 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE s_entry1->name); dir_index += cvt_len; } - + if(dir_index & 1) { directory_buffer[dir_index++] = 0; @@ -648,13 +648,13 @@ static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE s_entry = s_entry->jnext; } - + if(dpnt->jsize != dir_index) { fprintf (stderr, _("Unexpected joliet directory length %d %d %s\n"), dpnt->jsize, dir_index, dpnt->de_name); } - + xfwrite(directory_buffer, 1, total_size, outfile); last_extent_written += total_size >> 11; free(directory_buffer); @@ -678,7 +678,7 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) { continue; } - + /* * First update the path table sizes for directories. * @@ -690,15 +690,15 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) */ if(s_entry->isorec.flags[0] == 2) { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) + if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) { jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1; - if (jpath_table_size & 1) + if (jpath_table_size & 1) { jpath_table_size++; } } - else + else { if (this_dir == root && strlen(s_entry->name) == 1) { @@ -708,11 +708,11 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) } } - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) + if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) { s_entry->jreclen = sizeof(struct iso_directory_record) - sizeof(s_entry->isorec.name) - + joliet_strlen(s_entry->name) + + joliet_strlen(s_entry->name) + 1; } else @@ -737,9 +737,9 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) this_dir->jcontents = this_dir->contents; status = joliet_sort_directory(&this_dir->jcontents); - /* + /* * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary + * Do not split a directory entry across a sector boundary */ s_entry = this_dir->jcontents; /* @@ -756,10 +756,10 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) } jreclen = s_entry->jreclen; - + if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE) { - this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) & + this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); } this_dir->jsize += jreclen; @@ -771,11 +771,11 @@ static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) * Similar to the iso9660 case, except here we perform a full sort based upon the * regular name of the file, not the 8.3 version. */ -static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) +static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) { char * rpnt, *lpnt; struct directory_entry ** r, **l; - + r = (struct directory_entry **) rr; l = (struct directory_entry **) ll; rpnt = (*r)->name; @@ -788,7 +788,7 @@ static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) { sort_goof++; } - + /* * Put the '.' and '..' entries on the head of the sorted list. * For normal ASCII, this always happens to be the case, but out of @@ -800,13 +800,13 @@ static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) if( strcmp(rpnt, "..") == 0 ) return -1; if( strcmp(lpnt, "..") == 0 ) return 1; - while(*rpnt && *lpnt) + while(*rpnt && *lpnt) { if(*rpnt == ';' && *lpnt != ';') return -1; if(*rpnt != ';' && *lpnt == ';') return 1; - + if(*rpnt == ';' && *lpnt == ';') return 0; - + /* * Extensions are not special here. Don't treat the dot as something that * must be bumped to the start of the list. @@ -815,7 +815,7 @@ static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) if(*rpnt == '.' && *lpnt != '.') return -1; if(*rpnt != '.' && *lpnt == '.') return 1; #endif - + if(*rpnt < *lpnt) return -1; if(*rpnt > *lpnt) return 1; rpnt++; lpnt++; @@ -826,7 +826,7 @@ static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) } -/* +/* * Function: sort_directory * * Purpose: Sort the directory in the appropriate ISO9660 @@ -840,7 +840,7 @@ static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) int i; struct directory_entry * s_entry; struct directory_entry ** sortlist; - + s_entry = *sort_dir; while(s_entry) { @@ -851,9 +851,9 @@ static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) } /* - * OK, now we know how many there are. Build a vector for sorting. + * OK, now we know how many there are. Build a vector for sorting. */ - sortlist = (struct directory_entry **) + sortlist = (struct directory_entry **) e_malloc(sizeof(struct directory_entry *) * dcount); dcount = 0; @@ -867,18 +867,18 @@ static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) } s_entry = s_entry->next; } - + sort_goof = 0; #ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), + qsort(sortlist, dcount, sizeof(struct directory_entry *), (int (*)(const void *, const void *))joliet_compare_dirs); #else - qsort(sortlist, dcount, sizeof(struct directory_entry *), + qsort(sortlist, dcount, sizeof(struct directory_entry *), joliet_compare_dirs); #endif - - /* - * Now reassemble the linked list in the proper sorted order + + /* + * Now reassemble the linked list in the proper sorted order */ for(i=0; ijnext = NULL; *sort_dir = sortlist[0]; - + free(sortlist); return sort_goof; } @@ -934,7 +934,7 @@ static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, } } /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) + if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) generate_joliet_directories(dpnt->subdir, outfile); dpnt = dpnt->next; } @@ -947,7 +947,7 @@ static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, static int FDECL1(jpathtab_write, FILE *, outfile) { /* - * Next we write the path tables + * Next we write the path tables */ xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile); xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile); @@ -995,7 +995,7 @@ static int FDECL1(jvd_write, FILE *, outfile) struct iso_primary_descriptor jvol_desc; /* - * Next we write out the boot volume descriptor for the disc + * Next we write out the boot volume descriptor for the disc */ jvol_desc = vol_desc; get_joliet_vol_desc(&jvol_desc); @@ -1013,7 +1013,7 @@ static int FDECL1(jpathtab_size, int, starting_extent) jpath_table[1] = 0; jpath_table[2] = jpath_table[0] + jpath_blocks; jpath_table[3] = 0; - + last_extent += 2*jpath_blocks; return 0; } diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c index 803317ba0..8e99d5c18 100644 --- a/util/mkisofs/mkisofs.c +++ b/util/mkisofs/mkisofs.c @@ -90,6 +90,8 @@ int extension_record_size = 0; /* These variables are associated with command line options */ int use_eltorito = 0; int use_eltorito_emul_floppy = 0; +int use_embedded_boot = 0; +int use_protective_msdos_label = 0; int use_boot_info_table = 0; int use_RockRidge = 0; int use_Joliet = 0; @@ -100,17 +102,18 @@ int rationalize = 0; int generate_tables = 0; int print_size = 0; int split_output = 0; -char * preparer = PREPARER_DEFAULT; -char * publisher = PUBLISHER_DEFAULT; -char * appid = APPID_DEFAULT; -char * copyright = COPYRIGHT_DEFAULT; -char * biblio = BIBLIO_DEFAULT; -char * abstract = ABSTRACT_DEFAULT; -char * volset_id = VOLSET_ID_DEFAULT; -char * volume_id = VOLUME_ID_DEFAULT; -char * system_id = SYSTEM_ID_DEFAULT; -char * boot_catalog = BOOT_CATALOG_DEFAULT; -char * boot_image = BOOT_IMAGE_DEFAULT; +char *preparer = PREPARER_DEFAULT; +char *publisher = PUBLISHER_DEFAULT; +char *appid = APPID_DEFAULT; +char *copyright = COPYRIGHT_DEFAULT; +char *biblio = BIBLIO_DEFAULT; +char *abstract = ABSTRACT_DEFAULT; +char *volset_id = VOLSET_ID_DEFAULT; +char *volume_id = VOLUME_ID_DEFAULT; +char *system_id = SYSTEM_ID_DEFAULT; +char *boot_catalog = BOOT_CATALOG_DEFAULT; +char *boot_image = BOOT_IMAGE_DEFAULT; +char *boot_image_embed = NULL; int volume_set_size = 1; int volume_sequence_number = 1; @@ -197,6 +200,8 @@ struct ld_option #define OPTION_VERSION 173 +#define OPTION_PROTECTIVE_MSDOS_LABEL 174 + static const struct ld_option ld_options[] = { { {"all-files", no_argument, NULL, 'a'}, @@ -209,6 +214,10 @@ static const struct ld_option ld_options[] = '\0', N_("FILE"), N_("Set Bibliographic filename"), ONE_DASH }, { {"copyright", required_argument, NULL, OPTION_COPYRIGHT}, '\0', N_("FILE"), N_("Set Copyright filename"), ONE_DASH }, + { {"embedded-boot", required_argument, NULL, 'G'}, + 'G', N_("FILE"), N_("Set embedded boot image name"), TWO_DASHES }, + { {"protective-msdos-label", no_argument, NULL, OPTION_PROTECTIVE_MSDOS_LABEL }, + '\0', NULL, N_("Patch a protective DOS-style label in the image"), TWO_DASHES }, { {"eltorito-boot", required_argument, NULL, 'b'}, 'b', N_("FILE"), N_("Set El Torito boot image name"), ONE_DASH }, { {"eltorito-catalog", required_argument, NULL, 'c'}, @@ -555,8 +564,8 @@ void usage(){ } -/* - * Fill in date in the iso9660 format +/* + * Fill in date in the iso9660 format * * The standards state that the timezone offset is in multiples of 15 * minutes, and is what you add to GMT to get the localtime. The U.S. @@ -574,9 +583,9 @@ int FDECL2(iso9660_date,char *, result, time_t, crtime){ result[4] = local->tm_min; result[5] = local->tm_sec; - /* + /* * Must recalculate proper timezone offset each time, - * as some files use daylight savings time and some don't... + * as some files use daylight savings time and some don't... */ result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */ local = gmtime(&crtime); @@ -584,11 +593,11 @@ int FDECL2(iso9660_date,char *, result, time_t, crtime){ local->tm_yday -= result[6]; local->tm_hour -= result[3]; local->tm_min -= result[4]; - if (local->tm_year < 0) + if (local->tm_year < 0) { local->tm_yday = -1; } - else + else { if (local->tm_year > 0) local->tm_yday = 1; } @@ -719,10 +728,16 @@ int FDECL2(main, int, argc, char **, argv){ use_eltorito++; boot_image = optarg; /* pathname of the boot image on cd */ if (boot_image == NULL) - { - fprintf (stderr, _("Required boot image pathname missing\n")); - exit (1); - } + error (1, 0, _("Required boot image pathname missing")); + break; + case 'G': + use_embedded_boot = 1; + boot_image_embed = optarg; /* pathname of the boot image on host filesystem */ + if (boot_image_embed == NULL) + error (1, 0, _("Required boot image pathname missing")); + break; + case OPTION_PROTECTIVE_MSDOS_LABEL: + use_protective_msdos_label = 1; break; case 'c': use_eltorito++; @@ -957,7 +972,7 @@ parse_input_files: { int resource; struct rlimit rlp; - if (getrlimit(RLIMIT_DATA,&rlp) == -1) + if (getrlimit(RLIMIT_DATA,&rlp) == -1) perror (_("Warning: getrlimit")); else { rlp.rlim_cur=33554432; @@ -1077,7 +1092,7 @@ parse_input_files: merge_image); } - memcpy(&de.isorec.extent, mrootp->extent, 8); + memcpy(&de.isorec.extent, mrootp->extent, 8); } /* @@ -1160,8 +1175,8 @@ parse_input_files: break; } *pnt = '\0'; - graft_dir = find_or_create_directory(graft_dir, - graft_point, + graft_dir = find_or_create_directory(graft_dir, + graft_point, NULL, TRUE); *pnt = PATH_SEPARATOR; xpnt = pnt + 1; @@ -1247,12 +1262,12 @@ parse_input_files: if (goof) error (1, 0, _("Joliet tree sort failed.\n")); - + /* * Fix a couple of things in the root directory so that everything * is self consistent. */ - root->self = root->contents; /* Fix this up so that the path + root->self = root->contents; /* Fix this up so that the path tables get done right */ /* @@ -1329,8 +1344,8 @@ parse_input_files: outputlist_insert(&dirtree_clean); - if(extension_record) - { + if(extension_record) + { outputlist_insert(&extension_desc); } @@ -1341,7 +1356,7 @@ parse_input_files: * will always be a primary and an end volume descriptor. */ last_extent = session_start; - + /* * Calculate the size of all of the components of the disc, and assign * extent numbers. @@ -1387,7 +1402,7 @@ parse_input_files: if( verbose > 0 ) { #ifdef HAVE_SBRK - fprintf (stderr, _("Max brk space used %x\n"), + fprintf (stderr, _("Max brk space used %x\n"), (unsigned int)(((unsigned long)sbrk(0)) - mem_start)); #endif fprintf (stderr, _("%llu extents written (%llu MiB)\n"), last_extent, last_extent >> 9); diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h index a1638d80e..79ae50251 100644 --- a/util/mkisofs/mkisofs.h +++ b/util/mkisofs/mkisofs.h @@ -190,7 +190,7 @@ struct file_hash{ unsigned int starting_block; unsigned int size; }; - + /* * This structure is used to control the output of fragments to the cdrom @@ -243,7 +243,7 @@ extern struct output_fragment jdirtree_desc; extern struct output_fragment extension_desc; extern struct output_fragment files_desc; -/* +/* * This structure describes one complete directory. It has pointers * to other directories in the overall tree so that it is clear where * this directory lives in the tree, and it also must contain pointers @@ -296,6 +296,8 @@ extern struct iso_directory_record root_record; extern struct iso_directory_record jroot_record; extern int use_eltorito; +extern int use_embedded_boot; +extern int use_protective_msdos_label; extern int use_eltorito_emul_floppy; extern int use_boot_info_table; extern int use_RockRidge; @@ -324,14 +326,14 @@ extern struct directory * struct directory_entry * self, int)); extern void DECL (finish_cl_pl_entries, (void)); extern int DECL(scan_directory_tree,(struct directory * this_dir, - char * path, + char * path, struct directory_entry * self)); -extern int DECL(insert_file_entry,(struct directory *, char *, +extern int DECL(insert_file_entry,(struct directory *, char *, char *)); extern void DECL(generate_iso9660_directories,(struct directory *, FILE*)); extern void DECL(dump_tree,(struct directory * node)); -extern struct directory_entry * DECL(search_tree_file, (struct +extern struct directory_entry * DECL(search_tree_file, (struct directory * node,char * filename)); extern void DECL(update_nlink_field,(struct directory * node)); extern void DECL (init_fstatbuf, (void)); @@ -372,17 +374,17 @@ extern char *effective_date; extern FILE * in_image; extern struct iso_directory_record * - DECL(merge_isofs,(char * path)); + DECL(merge_isofs,(char * path)); extern int DECL(free_mdinfo, (struct directory_entry **, int len)); -extern struct directory_entry ** +extern struct directory_entry ** DECL(read_merging_directory,(struct iso_directory_record *, int*)); -extern void - DECL(merge_remaining_entries, (struct directory *, +extern void + DECL(merge_remaining_entries, (struct directory *, struct directory_entry **, int)); -extern int - DECL(merge_previous_session, (struct directory *, +extern int + DECL(merge_previous_session, (struct directory *, struct iso_directory_record *)); extern int DECL(get_session_start, (int *)); @@ -399,7 +401,7 @@ struct dirent * DECL(readdir_add_files, (char **, char *, DIR *)); /* */ -extern int DECL(iso9660_file_length,(const char* name, +extern int DECL(iso9660_file_length,(const char* name, struct directory_entry * sresult, int flag)); extern int DECL(iso9660_date,(char *, time_t)); extern void DECL(add_hash,(struct directory_entry *)); @@ -411,7 +413,7 @@ extern int DECL(delete_file_hash,(struct directory_entry *)); extern struct directory_entry * DECL(find_file_hash,(char *)); extern void DECL(add_file_hash,(struct directory_entry *)); extern int DECL(generate_rock_ridge_attributes,(char *, char *, - struct directory_entry *, + struct directory_entry *, struct stat *, struct stat *, int deep_flag)); extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor, @@ -438,20 +440,21 @@ extern char * extension_record; extern int extension_record_extent; extern int n_data_extents; -/* These are a few goodies that can be specified on the command line, and are +/* These are a few goodies that can be specified on the command line, and are filled into the root record */ -extern char * preparer; -extern char * publisher; -extern char * copyright; -extern char * biblio; -extern char * abstract; -extern char * appid; -extern char * volset_id; -extern char * system_id; -extern char * volume_id; -extern char * boot_catalog; -extern char * boot_image; +extern char *preparer; +extern char *publisher; +extern char *copyright; +extern char *biblio; +extern char *abstract; +extern char *appid; +extern char *volset_id; +extern char *system_id; +extern char *volume_id; +extern char *boot_catalog; +extern char *boot_image; +extern char *boot_image_embed; extern int volume_set_size; extern int volume_sequence_number; diff --git a/util/mkisofs/msdos_partition.h b/util/mkisofs/msdos_partition.h new file mode 100644 index 000000000..13985f7bb --- /dev/null +++ b/util/mkisofs/msdos_partition.h @@ -0,0 +1,75 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2004,2007 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 . + */ + +#ifndef MSDOS_PARTITION_H +#define MSDOS_PARTITION_H 1 + +#include + +/* The signature. */ +#define MSDOS_PARTITION_SIGNATURE ((0xaa << 8) | 0x55) + +/* This is not a flag actually, but used as if it were a flag. */ +#define MSDOS_PARTITION_TYPE_HIDDEN_FLAG 0x10 + +/* The partition entry. */ +struct msdos_partition_entry +{ + /* If active, 0x80, otherwise, 0x00. */ + uint8_t flag; + + /* The head of the start. */ + uint8_t start_head; + + /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C + is the cylinder of the start. Note that S is counted from one. */ + uint8_t start_sector; + + /* (C & 0xFF) where C is the cylinder of the start. */ + uint8_t start_cylinder; + + /* The partition type. */ + uint8_t type; + + /* The end versions of start_head, start_sector and start_cylinder, + respectively. */ + uint8_t end_head; + uint8_t end_sector; + uint8_t end_cylinder; + + /* The start sector. Note that this is counted from zero. */ + uint32_t start; + + /* The length in sector units. */ + uint32_t length; +} __attribute__ ((packed)); + +/* The structure of MBR. */ +struct msdos_partition_mbr +{ + /* The code area (actually, including BPB). */ + uint8_t code[446]; + + /* Four partition entries. */ + struct msdos_partition_entry entries[4]; + + /* The signature 0xaa55. */ + uint16_t signature; +} __attribute__ ((packed)); + +#endif diff --git a/util/mkisofs/multi.c b/util/mkisofs/multi.c index 1e7f62aac..d92f14530 100644 --- a/util/mkisofs/multi.c +++ b/util/mkisofs/multi.c @@ -1,5 +1,5 @@ /* - * File multi.c - scan existing iso9660 image and merge into + * File multi.c - scan existing iso9660 image and merge into * iso9660 filesystem. Used for multisession support. * * Written by Eric Youngdale (1996). @@ -166,7 +166,7 @@ readsecs(startsecno, buffer, sectorcount) /* * Parse the RR attributes so we can find the file name. */ -static int +static int FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt) { int cont_extent, cont_offset, cont_size; @@ -219,10 +219,10 @@ FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt) } /* parse_rr */ -static int -FDECL4(check_rr_dates, struct directory_entry *, dpnt, - struct directory_entry *, current, - struct stat *, statbuf, +static int +FDECL4(check_rr_dates, struct directory_entry *, dpnt, + struct directory_entry *, current, + struct stat *, statbuf, struct stat *,lstatbuf) { int cont_extent, cont_offset, cont_size; @@ -233,8 +233,8 @@ FDECL4(check_rr_dates, struct directory_entry *, dpnt, int same_file_type; mode_t mode; char time_buf[7]; - - + + cont_extent = cont_offset = cont_size = 0; same_file = 1; same_file_type = 1; @@ -270,14 +270,14 @@ FDECL4(check_rr_dates, struct directory_entry *, dpnt, if( pnt[4] & TF_CREATE ) { iso9660_date((char *) time_buf, lstatbuf->st_ctime); - if(memcmp(time_buf, pnt+offset, 7) == 0) + if(memcmp(time_buf, pnt+offset, 7) == 0) same_file = 0; offset += 7; } if( pnt[4] & TF_MODIFY ) { iso9660_date((char *) time_buf, lstatbuf->st_mtime); - if(memcmp(time_buf, pnt+offset, 7) == 0) + if(memcmp(time_buf, pnt+offset, 7) == 0) same_file = 0; offset += 7; } @@ -350,7 +350,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, while(i < len ) { idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) + if(idr->length[0] == 0) { i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); continue; @@ -378,7 +378,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, while(i < len ) { idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) + if(idr->length[0] == 0) { i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); continue; @@ -413,16 +413,16 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, */ rlen = idr->length[0] & 0xff; cpnt = (unsigned char *) idr; - + rlen -= sizeof(struct iso_directory_record); cpnt += sizeof(struct iso_directory_record); - + rlen += sizeof(idr->name); cpnt -= sizeof(idr->name); - + rlen -= idr->name_len[0]; cpnt += idr->name_len[0]; - + if((idr->name_len[0] & 1) == 0){ cpnt++; rlen--; @@ -444,7 +444,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]); parse_rr((*pnt)->rr_attributes, rlen, *pnt); - + if( ((*pnt)->isorec.name_len[0] == 1) && ( ((*pnt)->isorec.name[0] == 0) || ((*pnt)->isorec.name[0] == 1)) ) @@ -485,7 +485,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, tt_extent = isonum_733((unsigned char *)idr->extent); tt_size = isonum_733((unsigned char *)idr->size); } - + pnt++; i += idr->length[0]; } @@ -515,7 +515,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, { rlen = isonum_711((*pnt)->isorec.name_len); if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name, - rlen) == 0 + rlen) == 0 && cpnt[2+rlen] == ' ') { (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33); @@ -534,7 +534,7 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, cpnt = cpnt1 + 1; cpnt1 = cpnt; } - + free(tt_buf); } else if( !seen_rockridge && !warning_given ) @@ -553,14 +553,14 @@ FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, { free(dirbuff); } - + return rtn; } /* read_merging_directory */ /* * Free any associated data related to the structures. */ -int +int FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len ) { int i; @@ -792,7 +792,7 @@ struct iso_directory_record * FDECL1(merge_isofs, char *, path) /* * Get the location and size of the root directory. */ - rootp = (struct iso_directory_record *) + rootp = (struct iso_directory_record *) malloc(sizeof(struct iso_directory_record)); memcpy(rootp, pri->root_directory_record, sizeof(*rootp)); @@ -820,7 +820,7 @@ void FDECL3(merge_remaining_entries, struct directory *, this_dir, { continue; } - + if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL) { /* @@ -868,7 +868,7 @@ void FDECL3(merge_remaining_entries, struct directory *, this_dir, this_dir->contents = pnt[i]; pnt[i] = NULL; } - + /* * If we don't have an entry for the translation table, then @@ -945,7 +945,7 @@ void FDECL3(merge_remaining_entries, struct directory *, this_dir, * location. FIXME(eric). */ static int -FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, +FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, struct directory *, parent) { struct directory_entry **contents = NULL; @@ -997,7 +997,7 @@ FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, /* * We can always reuse the TRANS.TBL in this particular case. */ - contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; if( ((contents[i]->isorec.flags[0] & 2) != 0) && (i >= 2) ) @@ -1059,7 +1059,7 @@ FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, char * cdwrite_data = NULL; int -FDECL1(get_session_start, int *, file_addr) +FDECL1(get_session_start, int *, file_addr) { char * pnt; @@ -1171,14 +1171,14 @@ FDECL2(merge_previous_session,struct directory *, this_dir, { int dflag; - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) + if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) { struct directory * child; - child = find_or_create_directory(this_dir, - s_entry->whole_name, + child = find_or_create_directory(this_dir, + s_entry->whole_name, s_entry, 1); - dflag = merge_previous_session(child, + dflag = merge_previous_session(child, &odpnt->isorec); /* If unable to scan directory, mark this as a non-directory */ if(!dflag) @@ -1188,14 +1188,14 @@ FDECL2(merge_previous_session,struct directory *, this_dir, } } } - + /* * Whatever is left over, are things which are no longer in the tree * on disk. We need to also merge these into the tree. */ merge_remaining_entries(this_dir, orig_contents, n_orig); free_mdinfo(orig_contents, n_orig); - + return 1; } diff --git a/util/mkisofs/name.c b/util/mkisofs/name.c index 13f81870a..272471e93 100644 --- a/util/mkisofs/name.c +++ b/util/mkisofs/name.c @@ -27,7 +27,7 @@ #include extern int allow_leading_dots; - + /* * Function: iso9660_file_length * @@ -43,8 +43,8 @@ extern int allow_leading_dots; * would also be nice to have. */ int FDECL3(iso9660_file_length, - const char*, name, - struct directory_entry *, sresult, + const char*, name, + struct directory_entry *, sresult, int, dirflag) { char * c; @@ -69,7 +69,7 @@ int FDECL3(iso9660_file_length, */ if(strcmp(name,".") == 0) { - if(result) + if(result) { *result = 0; } @@ -82,7 +82,7 @@ int FDECL3(iso9660_file_length, */ if(strcmp(name,"..") == 0) { - if(result) + if(result) { *result++ = 1; *result++ = 0; @@ -115,7 +115,7 @@ int FDECL3(iso9660_file_length, while(*pnt) { #ifdef VMS - if( strcmp(pnt,".DIR;1") == 0 ) + if( strcmp(pnt,".DIR;1") == 0 ) { break; } @@ -126,11 +126,11 @@ int FDECL3(iso9660_file_length, * generated by some editors. Lower the priority of * the file. */ - if(*pnt == '#') + if(*pnt == '#') { - priority = 1; - pnt++; - continue; + priority = 1; + pnt++; + continue; } /* @@ -138,11 +138,11 @@ int FDECL3(iso9660_file_length, * generated by some editors. Lower the priority of * the file. */ - if(*pnt == '~') + if(*pnt == '~') { - priority = 1; - tildes++; - pnt++; + priority = 1; + tildes++; + pnt++; continue; } @@ -170,9 +170,9 @@ int FDECL3(iso9660_file_length, * If we have a name with multiple '.' characters, we ignore everything * after we have gotten the extension. */ - if(ignore) + if(ignore) { - pnt++; + pnt++; continue; } @@ -181,7 +181,7 @@ int FDECL3(iso9660_file_length, */ if(seen_semic) { - if(*pnt >= '0' && *pnt <= '9') + if(*pnt >= '0' && *pnt <= '9') { *result++ = *pnt; } @@ -197,19 +197,19 @@ int FDECL3(iso9660_file_length, * option. We still only allow one '.' character in the * name, however. */ - if(full_iso9660_filenames) + if(full_iso9660_filenames) { /* Here we allow a more relaxed syntax. */ - if(*pnt == '.') + if(*pnt == '.') { - if (seen_dot) + if (seen_dot) { - ignore++; + ignore++; continue; } seen_dot++; } - if(current_length < 30) + if(current_length < 30) { if( !isascii (*pnt)) { @@ -222,21 +222,21 @@ int FDECL3(iso9660_file_length, } } else - { - /* + { + /* * Dos style filenames. We really restrict the * names here. */ /* It would be nice to have .tar.gz transform to .tgz, * .ps.gz to .psz, ... */ - if(*pnt == '.') + if(*pnt == '.') { - if (!chars_before_dot && !allow_leading_dots) + if (!chars_before_dot && !allow_leading_dots) { /* DOS can't read files with dot first */ chars_before_dot++; - if (result) + if (result) { *result++ = '_'; /* Substitute underscore */ } @@ -247,36 +247,36 @@ int FDECL3(iso9660_file_length, * If this isn't the dot that we use for the extension, * then change the character into a '_' instead. */ - if(chars_before_dot < 8) + if(chars_before_dot < 8) { chars_before_dot++; - if(result) + if(result) { *result++ = '_'; } } } - else + else { - if (seen_dot) + if (seen_dot) { ignore++; continue; } - if(result) + if(result) { *result++ = '.'; } seen_dot++; } } - else + else { if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot) || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) ) { - if(result) + if(result) { - switch (*pnt) + switch (*pnt) { default: if( !isascii (*pnt) ) @@ -289,7 +289,7 @@ int FDECL3(iso9660_file_length, } break; - /* + /* * Descriptions of DOS's 'Parse Filename' * (function 29H) describes V1 and V2.0+ * separator and terminator characters. @@ -329,7 +329,7 @@ int FDECL3(iso9660_file_length, current_length++; pnt++; } /* while (*pnt) */ - + /* * OK, that wraps up the scan of the name. Now tidy up a few other * things. @@ -345,11 +345,11 @@ int FDECL3(iso9660_file_length, { int prio1 = 0; pnt = name; - while (*pnt && *pnt != '~') + while (*pnt && *pnt != '~') { pnt++; } - if (*pnt) + if (*pnt) { pnt++; } @@ -360,7 +360,7 @@ int FDECL3(iso9660_file_length, } priority = prio1; } - + /* * If this is not a directory, force a '.' in case we haven't * seen one, and add a version number if we haven't seen one @@ -368,12 +368,12 @@ int FDECL3(iso9660_file_length, */ if (!dirflag) { - if (!seen_dot && !omit_period) + if (!seen_dot && !omit_period) { - if (result) *result++ = '.'; + if (result) *result++ = '.'; extra++; } - if(!omit_version_number && !seen_semic) + if(!omit_version_number && !seen_semic) { if(result) { @@ -383,8 +383,8 @@ int FDECL3(iso9660_file_length, extra += 2; } } - - if(result) + + if(result) { *result++ = 0; } diff --git a/util/mkisofs/rock.c b/util/mkisofs/rock.c index 224488af5..a4cc27fa9 100644 --- a/util/mkisofs/rock.c +++ b/util/mkisofs/rock.c @@ -87,7 +87,7 @@ a CE entry for the continuation record */ #define MAYBE_ADD_CE_ENTRY(BYTES) \ - ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) + ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) /* * Buffer to build RR attributes @@ -210,13 +210,13 @@ int deep_opt; }; /* - * Add the posix modes + * Add the posix modes */ if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); Rock[ipnt++] ='P'; Rock[ipnt++] ='X'; Rock[ipnt++] = PX_SIZE; - Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = SU_VERSION; flagval |= (1<<0); set_733((char*)Rock + ipnt, lstatbuf->st_mode); ipnt += 8; @@ -236,7 +236,7 @@ int deep_opt; Rock[ipnt++] ='P'; Rock[ipnt++] ='N'; Rock[ipnt++] = PN_SIZE; - Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = SU_VERSION; flagval |= (1<<1); #if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV) set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); @@ -286,25 +286,25 @@ int deep_opt; cpnt = &symlink_buff[0]; flagval |= (1<<2); - if (! split_SL_field) + if (! split_SL_field) { int sl_bytes = 0; - for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) + for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) { - if (*cpnt1 == '/') + if (*cpnt1 == '/') { sl_bytes += 4; - } - else + } + else { sl_bytes += 1; } } - if (sl_bytes > 250) + if (sl_bytes > 250) { - /* + /* * the symbolic link won't fit into one SL System Use Field - * print an error message and continue with splited one + * print an error message and continue with splited one */ fprintf(stderr, _("symbolic link ``%s'' to long for one SL System Use Field, splitting"), cpnt); } @@ -317,7 +317,7 @@ int deep_opt; Rock[ipnt++] ='L'; lenpos = ipnt; Rock[ipnt++] = SL_SIZE; - Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = SU_VERSION; Rock[ipnt++] = 0; /* Flags */ lenval = 5; while(*cpnt){ @@ -326,7 +326,7 @@ int deep_opt; nchar--; *cpnt1 = 0; }; - + /* We treat certain components in a special way. */ if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){ if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); @@ -349,7 +349,7 @@ int deep_opt; /* If we do not have enough room for a component, start a new continuations segment now */ if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) : - MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) + MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) { add_CE_entry(); if(cpnt1) @@ -397,7 +397,7 @@ int deep_opt; if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */ } /* while nchar */ } /* Is a symbolic link */ - /* + /* * Add in the Rock Ridge TF time field */ if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry(); @@ -422,7 +422,7 @@ int deep_opt; iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); ipnt += 7; - /* + /* * Add in the Rock Ridge RE time field */ if(deep_opt & NEED_RE){ @@ -433,7 +433,7 @@ int deep_opt; Rock[ipnt++] = SU_VERSION; flagval |= (1<<6); }; - /* + /* * Add in the Rock Ridge PL record, if required. */ if(deep_opt & NEED_PL){ @@ -447,7 +447,7 @@ int deep_opt; flagval |= (1<<5); }; - /* + /* * Add in the Rock Ridge CL field, if required. */ if(deep_opt & NEED_CL){ @@ -464,7 +464,7 @@ int deep_opt; #ifndef VMS /* If transparent compression was requested, fill in the correct field for this file */ - if(transparent_compression && + if(transparent_compression && S_ISREG(lstatbuf->st_mode) && strlen(name) > 3 && strcmp(name + strlen(name) - 3,".gZ") == 0){ @@ -498,8 +498,8 @@ int deep_opt; else { int blocksize; blocksize = (header[3] << 8) | header[2]; - file_size = ((unsigned int)header[7] << 24) | - ((unsigned int)header[6] << 16) | + file_size = ((unsigned int)header[7] << 24) | + ((unsigned int)header[6] << 16) | ((unsigned int)header[5] << 8) | header[4]; #if 0 fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size); @@ -534,7 +534,7 @@ int deep_opt; }; } #endif - /* + /* * Add in the Rock Ridge CE field, if required. We use this for the * extension record that is stored in the root directory. */ diff --git a/util/mkisofs/tree.c b/util/mkisofs/tree.c index d11fdc2cd..0d9cf6143 100644 --- a/util/mkisofs/tree.c +++ b/util/mkisofs/tree.c @@ -195,7 +195,7 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) * missing the required '.' entries. Create these now if we need * them. */ - if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != + if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != (DIR_HAS_DOT | DIR_HAS_DOTDOT) ) { attach_dot_entries(this_dir, &fstatbuf); @@ -211,9 +211,9 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) s_entry = s_entry->next; continue; } - + /* - * First assume no conflict, and handle this case + * First assume no conflict, and handle this case */ if(!(s_entry1 = find_file_hash(s_entry->isorec.name))) { @@ -221,16 +221,16 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) s_entry = s_entry->next; continue; } - + if(s_entry1 == s_entry) error (1, 0, _("Fatal goof\n")); - - /* + + /* * OK, handle the conflicts. Try substitute names until we come - * up with a winner + * up with a winner */ strcpy(rootname, s_entry->isorec.name); - if(full_iso9660_filenames) + if(full_iso9660_filenames) { if(strlen(rootname) > 27) rootname[27] = 0; } @@ -241,7 +241,7 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) * a ';'. */ c = strchr(rootname, '.'); - if (c) + if (c) *c = 0; else { @@ -254,25 +254,25 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) { for(d3 = 0; d3 < 36; d3++) { - sprintf(newname,"%s.%c%c%c%s", rootname, + sprintf(newname,"%s.%c%c%c%s", rootname, (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10), (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10), (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10), - (s_entry->isorec.flags[0] == 2 || + (s_entry->isorec.flags[0] == 2 || omit_version_number ? "" : ";1")); - + #ifdef VMS /* Sigh. VAXCRTL seems to be broken here */ { int ijk = 0; - while(newname[ijk]) + while(newname[ijk]) { if(newname[ijk] == ' ') newname[ijk] = '0'; ijk++; } } #endif - + if(!find_file_hash(newname)) goto got_valid_name; } } @@ -283,24 +283,24 @@ static int FDECL1(sort_n_finish, struct directory *, this_dir) */ error (1, 0, _("Unable to generate unique name for file %s\n"), s_entry->name); -got_valid_name: - /* +got_valid_name: + /* * OK, now we have a good replacement name. Now decide which one - * of these two beasts should get the name changed + * of these two beasts should get the name changed */ - if(s_entry->priority < s_entry1->priority) + if(s_entry->priority < s_entry1->priority) { if( verbose > 0 ) { - fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, + fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname, + this_dir->whole_name, SPATH_SEPARATOR, s_entry->name, s_entry1->name); } s_entry->isorec.name_len[0] = strlen(newname); new_reclen = sizeof(struct iso_directory_record) - sizeof(s_entry->isorec.name) + strlen(newname); - if(use_RockRidge) + if(use_RockRidge) { if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ new_reclen += s_entry->rr_attr_size; @@ -309,20 +309,20 @@ got_valid_name: s_entry->isorec.length[0] = new_reclen; strcpy(s_entry->isorec.name, newname); } - else + else { delete_file_hash(s_entry1); if( verbose > 0 ) { - fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, + fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname, + this_dir->whole_name, SPATH_SEPARATOR, s_entry1->name, s_entry->name); } s_entry1->isorec.name_len[0] = strlen(newname); new_reclen = sizeof(struct iso_directory_record) - sizeof(s_entry1->isorec.name) + strlen(newname); - if(use_RockRidge) + if(use_RockRidge) { if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ new_reclen += s_entry1->rr_attr_size; @@ -335,19 +335,19 @@ got_valid_name: add_file_hash(s_entry); s_entry = s_entry->next; } - - if(generate_tables - && !find_file_hash("TRANS.TBL") + + if(generate_tables + && !find_file_hash("TRANS.TBL") && (reloc_dir != this_dir) && (this_dir->extent == 0) ) { - /* - * First we need to figure out how big this table is + /* + * First we need to figure out how big this table is */ for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; + strcmp(s_entry->name, "..") == 0) continue; if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; if(s_entry->table) tablesize += 35 + strlen(s_entry->table); } @@ -355,13 +355,13 @@ got_valid_name: if( tablesize > 0 ) { - table = (struct directory_entry *) + table = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memset(table, 0, sizeof(struct directory_entry)); table->table = NULL; table->next = this_dir->contents; this_dir->contents = table; - + table->filedir = root; table->isorec.flags[0] = 0; table->priority = 32768; @@ -379,7 +379,7 @@ got_valid_name: table->table = (char *) e_malloc(ROUND_UP(tablesize)); memset(table->table, 0, ROUND_UP(tablesize)); iso9660_file_length ("TRANS.TBL", table, 0); - + if(use_RockRidge) { fstatbuf.st_mode = 0444 | S_IFREG; @@ -389,7 +389,7 @@ got_valid_name: &fstatbuf, &fstatbuf, 0); } } - + /* * We have now chosen the 8.3 names and we should now know the length * of every entry in the directory. @@ -403,18 +403,18 @@ got_valid_name: } new_reclen = strlen(s_entry->isorec.name); - + /* * First update the path table sizes for directories. */ if(s_entry->isorec.flags[0] == 2) { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) + if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) { path_table_size += new_reclen + sizeof(struct iso_path_table) - 1; if (new_reclen & 1) path_table_size++; } - else + else { new_reclen = 1; if (this_dir == root && strlen(s_entry->name) == 1) @@ -425,19 +425,19 @@ got_valid_name: } if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */ s_entry->isorec.name_len[0] = new_reclen; - - new_reclen += + + new_reclen += sizeof(struct iso_directory_record) - sizeof(s_entry->isorec.name); - - if (new_reclen & 1) + + if (new_reclen & 1) new_reclen++; - + new_reclen += s_entry->rr_attr_size; - + if (new_reclen & 1) new_reclen++; - - if(new_reclen > 0xff) + + if(new_reclen > 0xff) error (1, 0, _("Fatal error - RR overflow for file %s\n"), s_entry->name); s_entry->isorec.length[0] = new_reclen; @@ -476,14 +476,14 @@ got_valid_name: s_entry->table = NULL; } - if(count != tablesize) + if(count != tablesize) error (1, 0, _("Translation table size mismatch %d %d\n"), count, tablesize); } - /* + /* * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary + * Do not split a directory entry across a sector boundary */ s_entry = this_dir->contents; this_dir->ce_bytes = 0; @@ -497,34 +497,34 @@ got_valid_name: new_reclen = s_entry->isorec.length[0]; if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) - this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & + this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); this_dir->size += new_reclen; /* See if continuation entries were used on disc */ - if(use_RockRidge && - s_entry->rr_attr_size != s_entry->total_rr_attr_size) + if(use_RockRidge && + s_entry->rr_attr_size != s_entry->total_rr_attr_size) { unsigned char * pnt; int len; int nbytes; - + pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; - + /* * We make sure that each continuation entry record is not * split across sectors, but each file could in theory have more - * than one CE, so we scan through and figure out what we need. + * than one CE, so we scan through and figure out what we need. */ while(len > 3) { - if(pnt[0] == 'C' && pnt[1] == 'E') + if(pnt[0] == 'C' && pnt[1] == 'E') { nbytes = get_733((char *) pnt+20); - + if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) this_dir->ce_bytes = + SECTOR_SIZE) this_dir->ce_bytes = ROUND_UP(this_dir->ce_bytes); /* Now store the block in the ce buffer */ this_dir->ce_bytes += nbytes; @@ -546,7 +546,7 @@ static void generate_reloc_directory() /* Create an entry for our internal tree */ time (¤t_time); - reloc_dir = (struct directory *) + reloc_dir = (struct directory *) e_malloc(sizeof(struct directory)); memset(reloc_dir, 0, sizeof(struct directory)); reloc_dir->parent = root; @@ -556,10 +556,10 @@ static void generate_reloc_directory() reloc_dir->whole_name = strdup("./rr_moved"); reloc_dir->de_name = strdup("rr_moved"); reloc_dir->extent = 0; - - + + /* Now create an actual directory entry */ - s_entry = (struct directory_entry *) + s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memset(s_entry, 0, sizeof(struct directory_entry)); s_entry->next = root->contents; @@ -589,13 +589,13 @@ static void generate_reloc_directory() "rr_moved", s_entry, &fstatbuf, &fstatbuf, 0); }; - + /* Now create the . and .. entries in rr_moved */ /* Now create an actual directory entry */ attach_dot_entries(reloc_dir, &root_statbuf); } -/* +/* * Function: attach_dot_entries * * Purpose: Create . and .. entries for a new directory. @@ -616,9 +616,9 @@ static void FDECL2(attach_dot_entries, struct directory *, dirnode, if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 ) { - s_entry = (struct directory_entry *) + s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, + memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup(".."); s_entry->whole_name = NULL; @@ -640,7 +640,7 @@ static void FDECL2(attach_dot_entries, struct directory *, dirnode, } generate_rock_ridge_attributes("", "..", s_entry, - parent_stat, + parent_stat, parent_stat, 0); } dirnode->dir_flags |= DIR_HAS_DOTDOT; @@ -648,9 +648,9 @@ static void FDECL2(attach_dot_entries, struct directory *, dirnode, if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 ) { - s_entry = (struct directory_entry *) + s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, + memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup("."); s_entry->whole_name = NULL; @@ -659,7 +659,7 @@ static void FDECL2(attach_dot_entries, struct directory *, dirnode, iso9660_file_length (".", s_entry, 1); iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); s_entry->filedir = dirnode; - + dirnode->contents = s_entry; dirnode->contents->next = orig_contents; @@ -667,17 +667,17 @@ static void FDECL2(attach_dot_entries, struct directory *, dirnode, { fstatbuf.st_mode = 0555 | S_IFDIR; fstatbuf.st_nlink = 2; - + if( dirnode == root ) { deep_flag |= NEED_CE | NEED_SP; /* For extension record */ } - + generate_rock_ridge_attributes("", ".", s_entry, &fstatbuf, &fstatbuf, deep_flag); } - + dirnode->dir_flags |= DIR_HAS_DOT; } @@ -687,12 +687,12 @@ static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value) { unsigned char * pnt; int len; - + pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; while(len) { - if(pnt[0] == 'P' && pnt[1] == 'X') + if(pnt[0] == 'P' && pnt[1] == 'X') { set_733((char *) pnt+12, value); break; @@ -706,12 +706,12 @@ static void FDECL1(increment_nlink, struct directory_entry *, s_entry) { unsigned char * pnt; int len, nlink; - + pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; while(len) { - if(pnt[0] == 'P' && pnt[1] == 'X') + if(pnt[0] == 'P' && pnt[1] == 'X') { nlink = get_733((char *) pnt+12); set_733((char *) pnt+12, nlink+1); @@ -770,7 +770,7 @@ void finish_cl_pl_entries(){ }; } -/* +/* * Function: scan_directory_tree * * Purpose: Walk through a directory on the local machine @@ -781,7 +781,7 @@ void finish_cl_pl_entries(){ */ int FDECL3(scan_directory_tree,struct directory *, this_dir, - char *, path, + char *, path, struct directory_entry *, de) { DIR * current_dir; @@ -806,7 +806,7 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, if(current_dir) d_entry = readdir(current_dir); - if(!current_dir || !d_entry) + if(!current_dir || !d_entry) { fprintf (stderr, _("Unable to open directory %s\n"), path); de->isorec.flags[0] &= ~2; /* Mark as not a directory */ @@ -827,12 +827,12 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, */ if (de->de_flags & INHIBIT_ISO9660_ENTRY) this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - + if (de->de_flags & INHIBIT_JOLIET_ENTRY) this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - - /* - * Now we scan the directory itself, and look at what is inside of it. + + /* + * Now we scan the directory itself, and look at what is inside of it. */ dflag = 0; while(1==1){ @@ -878,7 +878,7 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, continue; } - if( generate_tables + if( generate_tables && strcmp(d_entry->d_name, "TRANS.TBL") == 0 ) { /* @@ -886,7 +886,7 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, * versions of these files, and we need to ignore any * originals that we might have found. */ - if (verbose > 1) + if (verbose > 1) { fprintf (stderr, _("Excluded: %s\n"), whole_path); } @@ -897,13 +897,13 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, * If we already have a '.' or a '..' entry, then don't * insert new ones. */ - if( strcmp(d_entry->d_name, ".") == 0 + if( strcmp(d_entry->d_name, ".") == 0 && this_dir->dir_flags & DIR_HAS_DOT ) { continue; } - if( strcmp(d_entry->d_name, "..") == 0 + if( strcmp(d_entry->d_name, "..") == 0 && this_dir->dir_flags & DIR_HAS_DOTDOT ) { continue; @@ -918,12 +918,12 @@ FDECL3(scan_directory_tree,struct directory *, this_dir, insert_file_entry(this_dir, whole_path, d_entry->d_name); } closedir(current_dir); - + return 1; } -/* +/* * Function: insert_file_entry * * Purpose: Insert one entry into our directory node. @@ -961,12 +961,12 @@ FDECL3(insert_file_entry,struct directory *, this_dir, fprintf (stderr, _("Non-existant or inaccessible: %s\n"),whole_path); return 0; } - + if(this_dir == root && strcmp(short_name, ".") == 0) root_statbuf = statbuf; /* Save this for later on */ - + /* We do this to make sure that the root entries are consistent */ - if(this_dir == root && strcmp(short_name, "..") == 0) + if(this_dir == root && strcmp(short_name, "..") == 0) { statbuf = root_statbuf; lstatbuf = root_statbuf; @@ -974,13 +974,13 @@ FDECL3(insert_file_entry,struct directory *, this_dir, if(S_ISLNK(lstatbuf.st_mode)) { - + /* Here we decide how to handle the symbolic links. Here we handle the general case - if we are not following links or there is an error, then we must change something. If RR is in use, it is easy, we let RR describe the file. If not, then we punt the file. */ - + if((status || !follow_links)) { if(use_RockRidge) @@ -991,7 +991,7 @@ FDECL3(insert_file_entry,struct directory *, this_dir, statbuf.st_dev = (dev_t) UNCACHED_DEVICE; statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; } else { - if(follow_links) + if(follow_links) { fprintf (stderr, _("Unable to stat file %s - ignoring and continuing.\n"), @@ -1006,7 +1006,7 @@ FDECL3(insert_file_entry,struct directory *, this_dir, } } } - + /* Here we handle a different kind of case. Here we have a symlink, but we want to follow symlinks. If we run across a directory loop, then we need to pretend that @@ -1014,16 +1014,16 @@ FDECL3(insert_file_entry,struct directory *, this_dir, is the first time we have seen this, then make this seem as if there was no symlink there in the first place */ - + if( follow_links - && S_ISDIR(statbuf.st_mode) ) + && S_ISDIR(statbuf.st_mode) ) { if( strcmp(short_name, ".") && strcmp(short_name, "..") ) { if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) { - if(!use_RockRidge) + if(!use_RockRidge) { fprintf (stderr, _("Already cached directory seen (%s)\n"), whole_path); @@ -1034,25 +1034,25 @@ FDECL3(insert_file_entry,struct directory *, this_dir, statbuf.st_dev = (dev_t) UNCACHED_DEVICE; statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; } - else + else { lstatbuf = statbuf; add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); } } } - + /* * For non-directories, we just copy the stat information over * so we correctly include this file. */ if( follow_links - && !S_ISDIR(statbuf.st_mode) ) + && !S_ISDIR(statbuf.st_mode) ) { lstatbuf = statbuf; } } - + /* * Add directories to the cache so that we don't waste space even * if we are supposed to be following symlinks. @@ -1060,7 +1060,7 @@ FDECL3(insert_file_entry,struct directory *, this_dir, if( follow_links && strcmp(short_name, ".") && strcmp(short_name, "..") - && S_ISDIR(statbuf.st_mode) ) + && S_ISDIR(statbuf.st_mode) ) { add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); } @@ -1071,13 +1071,13 @@ FDECL3(insert_file_entry,struct directory *, this_dir, whole_path, strerror (errno)); return 0; } - + /* Add this so that we can detect directory loops with hard links. If we are set up to follow symlinks, then we skip this checking. */ - if( !follow_links - && S_ISDIR(lstatbuf.st_mode) - && strcmp(short_name, ".") - && strcmp(short_name, "..") ) + if( !follow_links + && S_ISDIR(lstatbuf.st_mode) + && strcmp(short_name, ".") + && strcmp(short_name, "..") ) { if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) error (1, 0, _("Directory loop - fatal goof (%s %lx %lu).\n"), @@ -1085,7 +1085,7 @@ FDECL3(insert_file_entry,struct directory *, this_dir, (unsigned long) STAT_INODE(statbuf)); add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); } - + if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && @@ -1094,26 +1094,26 @@ FDECL3(insert_file_entry,struct directory *, this_dir, whole_path); return 0; } - + /* Who knows what trash this is - ignore and continue */ - - if(status) + + if(status) { fprintf (stderr, _("Unable to stat file %s - ignoring and continuing.\n"), whole_path); - return 0; + return 0; } - + /* * Check to see if we have already seen this directory node. * If so, then we don't create a new entry for it, but we do want * to recurse beneath it and add any new files we do find. */ - if (S_ISDIR(statbuf.st_mode)) + if (S_ISDIR(statbuf.st_mode)) { int dflag; - + for( s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { if( strcmp(s_entry->name, short_name) == 0 ) @@ -1121,12 +1121,12 @@ FDECL3(insert_file_entry,struct directory *, this_dir, break; } } - if ( s_entry != NULL - && strcmp(short_name,".") - && strcmp(short_name,"..")) + if ( s_entry != NULL + && strcmp(short_name,".") + && strcmp(short_name,"..")) { struct directory * child; - + if ( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { for( s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) @@ -1136,12 +1136,12 @@ FDECL3(insert_file_entry,struct directory *, this_dir, break; } } - child = find_or_create_directory(reloc_dir, whole_path, + child = find_or_create_directory(reloc_dir, whole_path, s_entry, 1); } else { - child = find_or_create_directory(this_dir, whole_path, + child = find_or_create_directory(this_dir, whole_path, s_entry, 1); /* If unable to scan directory, mark this as a non-directory */ } @@ -1153,15 +1153,15 @@ FDECL3(insert_file_entry,struct directory *, this_dir, return 0; } } - - s_entry = (struct directory_entry *) + + s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); s_entry->next = this_dir->contents; memset(s_entry->isorec.extent, 0, 8); this_dir->contents = s_entry; deep_flag = 0; s_entry->table = NULL; - + s_entry->name = strdup(short_name); s_entry->whole_name = strdup (whole_path); @@ -1204,21 +1204,21 @@ FDECL3(insert_file_entry,struct directory *, this_dir, if( strcmp(short_name, ".") == 0) { this_dir->dir_flags |= DIR_HAS_DOT; - } + } if( strcmp(short_name, "..") == 0) { this_dir->dir_flags |= DIR_HAS_DOTDOT; - } + } - if( this_dir->parent - && this_dir->parent == reloc_dir + if( this_dir->parent + && this_dir->parent == reloc_dir && strcmp(short_name, "..") == 0) { s_entry->inode = UNCACHED_INODE; s_entry->dev = (dev_t) UNCACHED_DEVICE; deep_flag = NEED_PL; - } + } else { s_entry->inode = STAT_INODE(statbuf); @@ -1229,42 +1229,42 @@ FDECL3(insert_file_entry,struct directory *, this_dir, s_entry->rr_attr_size = 0; s_entry->total_rr_attr_size = 0; s_entry->rr_attributes = NULL; - + /* Directories are assigned sizes later on */ - if (!S_ISDIR(statbuf.st_mode)) + if (!S_ISDIR(statbuf.st_mode)) { - if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || + if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) || S_ISLNK(lstatbuf.st_mode)) { - s_entry->size = 0; - statbuf.st_size = 0; + s_entry->size = 0; + statbuf.st_size = 0; } else { - s_entry->size = statbuf.st_size; + s_entry->size = statbuf.st_size; } - set_733((char *) s_entry->isorec.size, statbuf.st_size); - } + set_733((char *) s_entry->isorec.size, statbuf.st_size); + } else { s_entry->isorec.flags[0] = 2; } - - if (strcmp(short_name,".") && strcmp(short_name,"..") && + + if (strcmp(short_name,".") && strcmp(short_name,"..") && S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth) { struct directory * child; if(!reloc_dir) generate_reloc_directory(); - + /* * Replicate the entry for this directory. The old one will stay where it * is, and it will be neutered so that it no longer looks like a directory. * The new one will look like a directory, and it will be put in the reloc_dir. */ - s_entry1 = (struct directory_entry *) + s_entry1 = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memcpy(s_entry1, s_entry, sizeof(struct directory_entry)); s_entry1->table = NULL; @@ -1274,26 +1274,26 @@ FDECL3(insert_file_entry,struct directory *, this_dir, reloc_dir->contents = s_entry1; s_entry1->priority = 32768; s_entry1->parent_rec = this_dir->contents; - + deep_flag = NEED_RE; - - if(use_RockRidge) + + if(use_RockRidge) { generate_rock_ridge_attributes(whole_path, short_name, s_entry1, &statbuf, &lstatbuf, deep_flag); } - + deep_flag = 0; - + /* We need to set this temporarily so that the parent to this is correctly determined. */ s_entry1->filedir = reloc_dir; - child = find_or_create_directory(reloc_dir, whole_path, + child = find_or_create_directory(reloc_dir, whole_path, s_entry1, 0); scan_directory_tree(child, whole_path, s_entry1); s_entry1->filedir = this_dir; - + statbuf.st_size = 0; statbuf.st_mode &= 0777; set_733((char *) s_entry->isorec.size, 0); @@ -1303,10 +1303,10 @@ FDECL3(insert_file_entry,struct directory *, this_dir, s_entry->de_flags |= RELOCATED_DIRECTORY; deep_flag = NEED_CL; } - - if(generate_tables - && strcmp(s_entry->name, ".") - && strcmp(s_entry->name, "..")) + + if(generate_tables + && strcmp(s_entry->name, ".") + && strcmp(s_entry->name, "..")) { char buffer[2048]; int nchar; @@ -1357,8 +1357,8 @@ FDECL3(insert_file_entry,struct directory *, this_dir, #endif #ifdef S_IFLNK case S_IFLNK: - nchar = readlink(whole_path, - (char *)symlink_buff, + nchar = readlink(whole_path, + (char *)symlink_buff, sizeof(symlink_buff)); symlink_buff[nchar < 0 ? 0 : nchar] = 0; sprintf(buffer,"L\t%s\t%s\n", @@ -1379,18 +1379,18 @@ FDECL3(insert_file_entry,struct directory *, this_dir, }; s_entry->table = strdup(buffer); } - + if(S_ISDIR(statbuf.st_mode)) { int dflag; - if (strcmp(short_name,".") && strcmp(short_name,"..")) + if (strcmp(short_name,".") && strcmp(short_name,"..")) { struct directory * child; - - child = find_or_create_directory(this_dir, whole_path, + + child = find_or_create_directory(this_dir, whole_path, s_entry, 1); dflag = scan_directory_tree(child, whole_path, s_entry); - + if(!dflag) { lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; @@ -1402,23 +1402,23 @@ FDECL3(insert_file_entry,struct directory *, this_dir, } /* If unable to scan directory, mark this as a non-directory */ } - + if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0) { deep_flag |= NEED_CE | NEED_SP; /* For extension record */ } - + /* Now figure out how much room this file will take in the directory */ - - if(use_RockRidge) + + if(use_RockRidge) { generate_rock_ridge_attributes(whole_path, short_name, s_entry, &statbuf, &lstatbuf, deep_flag); - + } - + return 1; } @@ -1492,7 +1492,7 @@ struct directory * FDECL4(find_or_create_directory, struct directory *, parent, */ if( de == NULL ) { - de = (struct directory_entry *) + de = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memset(de, 0, sizeof(struct directory_entry)); de->next = parent->contents; @@ -1516,7 +1516,7 @@ struct directory * FDECL4(find_or_create_directory, struct directory *, parent, fstatbuf.st_nlink = 2; generate_rock_ridge_attributes("", (char *) pnt, de, - &fstatbuf, + &fstatbuf, &fstatbuf, 0); } iso9660_date(de->isorec.date, fstatbuf.st_mtime); @@ -1570,7 +1570,7 @@ struct directory * FDECL4(find_or_create_directory, struct directory *, parent, if(!parent || parent == root) { - if (!root) + if (!root) { root = dpnt; /* First time through for root directory only */ root->depth = 0; @@ -1581,7 +1581,7 @@ struct directory * FDECL4(find_or_create_directory, struct directory *, parent, { root->subdir = dpnt; } - else + else { next_brother = root->subdir; while(next_brother->next) next_brother = next_brother->next; @@ -1589,24 +1589,24 @@ struct directory * FDECL4(find_or_create_directory, struct directory *, parent, } dpnt->parent = parent; } - } - else + } + else { /* Come through here for normal traversal of tree */ #ifdef DEBUG fprintf(stderr,"%s(%d) ", path, dpnt->depth); #endif - if(parent->depth > RR_relocation_depth) + if(parent->depth > RR_relocation_depth) error (1, 0, _("Directories too deep %s\n"), path); - - dpnt->parent = parent; + + dpnt->parent = parent; dpnt->depth = parent->depth + 1; - + if(!parent->subdir) { parent->subdir = dpnt; } - else + else { next_brother = parent->subdir; while(next_brother->next) next_brother = next_brother->next; @@ -1670,7 +1670,7 @@ int FDECL1(sort_tree, struct directory *, node){ { break; } - + if(dpnt->subdir) sort_tree(dpnt->subdir); dpnt = dpnt->next; } @@ -1697,7 +1697,7 @@ void FDECL1(update_nlink_field, struct directory *, node) int i; dpnt = node; - + while (dpnt) { if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { @@ -1751,9 +1751,9 @@ void FDECL1(update_nlink_field, struct directory *, node) /* * something quick and dirty to locate a file given a path * recursively walks down path in filename until it finds the - * directory entry for the desired file + * directory entry for the desired file */ -struct directory_entry * FDECL2(search_tree_file, struct directory *, +struct directory_entry * FDECL2(search_tree_file, struct directory *, node,char *, filename) { struct directory_entry * depnt; @@ -1763,7 +1763,7 @@ struct directory_entry * FDECL2(search_tree_file, struct directory *, char * subdir; /* - * strip off next directory name from filename + * strip off next directory name from filename */ subdir = strdup(filename); @@ -1776,65 +1776,65 @@ struct directory_entry * FDECL2(search_tree_file, struct directory *, } /* - * do we need to find a subdirectory + * do we need to find a subdirectory */ - if (p1) + if (p1) { *p1 = '\0'; #ifdef DEBUG_TORITO - fprintf(stderr,"Looking for subdir called %s\n",p1); + fprintf(stderr,"Looking for subdir called %s\n",p1); #endif rest = p1+1; #ifdef DEBUG_TORITO - fprintf(stderr,"Remainder of path name is now %s\n", rest); + fprintf(stderr,"Remainder of path name is now %s\n", rest); #endif - + dpnt = node->subdir; while( dpnt ) { #ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, - dpnt->de_name); + fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, + dpnt->de_name); #endif - if (!strcmp(subdir, dpnt->de_name)) + if (!strcmp(subdir, dpnt->de_name)) { #ifdef DEBUG_TORITO - fprintf(stderr,"Calling next level with filename = %s", rest); + fprintf(stderr,"Calling next level with filename = %s", rest); #endif return(search_tree_file( dpnt, rest )); } dpnt = dpnt->next; } - + /* if we got here means we couldnt find the subdir */ return (NULL); - } - else + } + else { - /* - * look for a normal file now + /* + * look for a normal file now */ depnt = node->contents; while (depnt) { #ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, - depnt->size, depnt->name); + fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, + depnt->size, depnt->name); #endif - if (!strcmp(filename, depnt->name)) + if (!strcmp(filename, depnt->name)) { #ifdef DEBUG_TORITO - fprintf(stderr,"Found our file %s", filename); + fprintf(stderr,"Found our file %s", filename); #endif return(depnt); } depnt = depnt->next; } - /* - * if we got here means we couldnt find the subdir + /* + * if we got here means we couldnt find the subdir */ return (NULL); } diff --git a/util/mkisofs/write.c b/util/mkisofs/write.c index 73c220827..69b6bb623 100644 --- a/util/mkisofs/write.c +++ b/util/mkisofs/write.c @@ -21,11 +21,10 @@ along with this program; if not, see . */ +#include "config.h" + #include #include -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" #include #include @@ -37,7 +36,11 @@ #ifdef HAVE_UNISTD_H #include #endif - + +#include "mkisofs.h" +#include "iso9660.h" +#include "msdos_partition.h" + #ifdef __SVR4 extern char * strdup(const char *); #endif @@ -158,7 +161,7 @@ void FDECL4(xfwrite, void *, buffer, uint64_t, count, uint64_t, size, FILE *, fi error (1, errno, _("Cannot open '%s'"), nbuf); } - while(count) + while(count) { size_t got = fwrite (buffer, size, count, file); @@ -193,7 +196,7 @@ static int FDECL1(assign_directory_addresses, struct directory *, node) struct directory * dpnt; dpnt = node; - + while (dpnt) { /* skip if it's hidden */ @@ -211,13 +214,13 @@ static int FDECL1(assign_directory_addresses, struct directory *, node) { dpnt->extent = last_extent; dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11; - + last_extent += dir_size; - - /* + + /* * Leave room for the CE entries for this directory. Keep them - * close to the reference directory so that access will be - * quick. + * close to the reference directory so that access will be + * quick. */ if(dpnt->ce_bytes) { @@ -225,7 +228,7 @@ static int FDECL1(assign_directory_addresses, struct directory *, node) } } - if(dpnt->subdir) + if(dpnt->subdir) { assign_directory_addresses(dpnt->subdir); } @@ -235,7 +238,7 @@ static int FDECL1(assign_directory_addresses, struct directory *, node) return 0; } -static void FDECL3(write_one_file, char *, filename, +static void FDECL3(write_one_file, char *, filename, uint64_t, size, FILE *, outfile) { char buffer[SECTOR_SIZE * NSECT]; @@ -244,7 +247,7 @@ static void FDECL3(write_one_file, char *, filename, size_t use; - if ((infile = fopen(filename, "rb")) == NULL) + if ((infile = fopen(filename, "rb")) == NULL) error (1, errno, _("cannot open %s\n"), filename); remain = size; @@ -253,12 +256,12 @@ static void FDECL3(write_one_file, char *, filename, use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain); use = ROUND_UP(use); /* Round up to nearest sector boundary */ memset(buffer, 0, use); - if (fread(buffer, 1, use, infile) == 0) - error (1, errno, _("cannot read %llu bytes from %s"), use, filename); + if (fread(buffer, 1, use, infile) == 0) + error (1, errno, _("cannot read %llu bytes from %s"), use, filename); xfwrite(buffer, 1, use, outfile); last_extent_written += use/SECTOR_SIZE; #if 0 - if((last_extent_written % 1000) < use/SECTOR_SIZE) + if((last_extent_written % 1000) < use/SECTOR_SIZE) { fprintf(stderr,"%d..", last_extent_written); } @@ -268,7 +271,7 @@ static void FDECL3(write_one_file, char *, filename, time_t now; time_t the_end; double frac; - + time(&now); frac = last_extent_written / (double)last_extent; the_end = begun + (now - begun) / frac; @@ -287,13 +290,13 @@ static void FDECL1(write_files, FILE *, outfile) dwpnt = dw_head; while(dwpnt) { - if(dwpnt->table) + if(dwpnt->table) { write_one_file (dwpnt->table, dwpnt->size, outfile); table_size += dwpnt->size; free (dwpnt->table); } - else + else { #ifdef VMS @@ -324,11 +327,11 @@ static void dump_filelist() } #endif -static int FDECL2(compare_dirs, const void *, rr, const void *, ll) +static int FDECL2(compare_dirs, const void *, rr, const void *, ll) { char * rpnt, *lpnt; struct directory_entry ** r, **l; - + r = (struct directory_entry **) rr; l = (struct directory_entry **) ll; rpnt = (*r)->isorec.name; @@ -341,7 +344,7 @@ static int FDECL2(compare_dirs, const void *, rr, const void *, ll) { sort_goof++; } - + /* * Put the '.' and '..' entries on the head of the sorted list. * For normal ASCII, this always happens to be the case, but out of @@ -373,16 +376,16 @@ static int FDECL2(compare_dirs, const void *, rr, const void *, ll) if((*l)->isorec.name_len[0] == 1 && *lpnt == 1) return 1; #endif - while(*rpnt && *lpnt) + while(*rpnt && *lpnt) { if(*rpnt == ';' && *lpnt != ';') return -1; if(*rpnt != ';' && *lpnt == ';') return 1; - + if(*rpnt == ';' && *lpnt == ';') return 0; - + if(*rpnt == '.' && *lpnt != '.') return -1; if(*rpnt != '.' && *lpnt == '.') return 1; - + if((unsigned char)*rpnt < (unsigned char)*lpnt) return -1; if((unsigned char)*rpnt > (unsigned char)*lpnt) return 1; rpnt++; lpnt++; @@ -392,7 +395,7 @@ static int FDECL2(compare_dirs, const void *, rr, const void *, ll) return 0; } -/* +/* * Function: sort_directory * * Purpose: Sort the directory in the appropriate ISO9660 @@ -408,7 +411,7 @@ int FDECL1(sort_directory, struct directory_entry **, sort_dir) int i, len; struct directory_entry * s_entry; struct directory_entry ** sortlist; - + /* need to keep a count of how many entries are hidden */ s_entry = *sort_dir; while(s_entry) @@ -425,9 +428,9 @@ int FDECL1(sort_directory, struct directory_entry **, sort_dir) } /* - * OK, now we know how many there are. Build a vector for sorting. + * OK, now we know how many there are. Build a vector for sorting. */ - sortlist = (struct directory_entry **) + sortlist = (struct directory_entry **) e_malloc(sizeof(struct directory_entry *) * dcount); j = dcount - 1; @@ -449,29 +452,29 @@ int FDECL1(sort_directory, struct directory_entry **, sort_dir) s_entry->isorec.name[len] = 0; s_entry = s_entry->next; } - + /* * Each directory is required to contain at least . and .. */ if( dcount < 2 ) { sort_goof = 1; - + } else { /* only sort the non-hidden entries */ sort_goof = 0; #ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), + qsort(sortlist, dcount, sizeof(struct directory_entry *), (int (*)(const void *, const void *))compare_dirs); #else - qsort(sortlist, dcount, sizeof(struct directory_entry *), + qsort(sortlist, dcount, sizeof(struct directory_entry *), compare_dirs); #endif - - /* - * Now reassemble the linked list in the proper sorted order + + /* + * Now reassemble the linked list in the proper sorted order * We still need the hidden entries, as they may be used in the * Joliet tree. */ @@ -479,7 +482,7 @@ int FDECL1(sort_directory, struct directory_entry **, sort_dir) { sortlist[i]->next = sortlist[i+1]; } - + sortlist[dcount+xcount-1]->next = NULL; *sort_dir = sortlist[0]; } @@ -491,7 +494,7 @@ int FDECL1(sort_directory, struct directory_entry **, sort_dir) static int root_gen() { init_fstatbuf(); - + root_record.length[0] = 1 + sizeof(struct iso_directory_record) - sizeof(root_record.name); root_record.ext_attr_length[0] = 0; @@ -530,16 +533,16 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) { continue; } - - /* - * This saves some space if there are symlinks present + + /* + * This saves some space if there are symlinks present */ s_hash = find_hash(s_entry->dev, s_entry->inode); if(s_hash) { if(verbose > 2) { - fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name, + fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name, SPATH_SEPARATOR, s_entry->name); } set_733((char *) s_entry->isorec.extent, s_hash->starting_block); @@ -548,12 +551,12 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) } /* - * If this is for a directory that is not a . or a .. entry, + * If this is for a directory that is not a . or a .. entry, * then look up the information for the entry. We have already * assigned extents for directories, so we just need to * fill in the blanks here. */ - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && + if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && s_entry->isorec.flags[0] == 2) { finddir = dpnt->subdir; @@ -561,7 +564,7 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) { if(finddir->self == s_entry) break; finddir = finddir->next; - if (!finddir) + if (!finddir) error (1, 0, _("Fatal goof\n")); } set_733((char *) s_entry->isorec.extent, finddir->extent); @@ -578,45 +581,45 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) * If this is . or .., then look up the relevant info from the * tables. */ - if(strcmp(s_entry->name,".") == 0) + if(strcmp(s_entry->name,".") == 0) { set_733((char *) s_entry->isorec.extent, dpnt->extent); - - /* + + /* * Set these so that the hash table has the * correct information */ s_entry->starting_block = dpnt->extent; s_entry->size = ROUND_UP(dpnt->size); - + add_hash(s_entry); s_entry->starting_block = dpnt->extent; set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size)); continue; } - if(strcmp(s_entry->name,"..") == 0) + if(strcmp(s_entry->name,"..") == 0) { if(dpnt == root) - { + { total_dir_size += root->size; } set_733((char *) s_entry->isorec.extent, dpnt->parent->extent); - - /* + + /* * Set these so that the hash table has the * correct information */ s_entry->starting_block = dpnt->parent->extent; s_entry->size = ROUND_UP(dpnt->parent->size); - + add_hash(s_entry); s_entry->starting_block = dpnt->parent->extent; set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size)); continue; } - /* + /* * Some ordinary non-directory file. Just schedule the * file to be written. This is all quite * straightforward, just make a list and assign extents @@ -624,28 +627,28 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) * directories, we should be ready write out these * files */ - if(s_entry->size) + if(s_entry->size) { - dwpnt = (struct deferred_write *) + dwpnt = (struct deferred_write *) e_malloc(sizeof(struct deferred_write)); if(dw_tail) { dw_tail->next = dwpnt; dw_tail = dwpnt; - } - else + } + else { dw_head = dwpnt; dw_tail = dwpnt; } - if(s_entry->inode == TABLE_INODE) + if(s_entry->inode == TABLE_INODE) { dwpnt->table = s_entry->table; dwpnt->name = NULL; sprintf(whole_path,"%s%sTRANS.TBL", s_entry->filedir->whole_name, SPATH_SEPARATOR); - } - else + } + else { dwpnt->table = NULL; strcpy(whole_path, s_entry->whole_name); @@ -669,15 +672,15 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) fprintf (stderr, "Warning: large file %s\n", whole_path); fprintf (stderr, "Starting block is %d\n", s_entry->starting_block); fprintf (stderr, "Reported file size is %d extents\n", s_entry->size); - + } #endif #ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ - if(last_extent > (800000000 >> 11)) - { + if(last_extent > (800000000 >> 11)) + { /* - * More than 800Mb? Punt + * More than 800Mb? Punt */ fprintf(stderr,"Extent overflow processing file %s\n", whole_path); fprintf(stderr,"Starting block is %d\n", s_entry->starting_block); @@ -696,7 +699,7 @@ static void FDECL1(assign_file_addresses, struct directory *, dpnt) */ set_733((char *) s_entry->isorec.extent, last_extent); } - if(dpnt->subdir) + if(dpnt->subdir) { assign_file_addresses(dpnt->subdir); } @@ -708,13 +711,13 @@ static void FDECL1(free_one_directory, struct directory *, dpnt) { struct directory_entry * s_entry; struct directory_entry * s_entry_d; - + s_entry = dpnt->contents; - while(s_entry) + while(s_entry) { s_entry_d = s_entry; s_entry = s_entry->next; - + if( s_entry_d->name != NULL ) { free (s_entry_d->name); @@ -750,31 +753,31 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) struct directory_entry * s_entry; struct directory_entry * s_entry_d; unsigned int total_size; - + total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); directory_buffer = (char *) e_malloc(total_size); memset(directory_buffer, 0, total_size); dir_index = 0; - + ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); ce_buffer = NULL; - - if(ce_size) + + if(ce_size) { ce_buffer = (char *) e_malloc(ce_size); memset(ce_buffer, 0, ce_size); - + ce_index = 0; - + /* - * Absolute byte address of CE entries for this directory + * Absolute byte address of CE entries for this directory */ ce_address = last_extent_written + (total_size >> 11); ce_address = ce_address << 11; } - + s_entry = dpnt->contents; - while(s_entry) + while(s_entry) { /* skip if it's hidden */ if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { @@ -782,25 +785,25 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) continue; } - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector + /* + * We do not allow directory entries to cross sector boundaries. + * Simply pad, and then start the next entry at the next sector */ new_reclen = s_entry->isorec.length[0]; if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & + dir_index = (dir_index + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); } - memcpy(directory_buffer + dir_index, &s_entry->isorec, + memcpy(directory_buffer + dir_index, &s_entry->isorec, sizeof(struct iso_directory_record) - sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]); - dir_index += sizeof(struct iso_directory_record) - + dir_index += sizeof(struct iso_directory_record) - sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0]; /* - * Add the Rock Ridge attributes, if present + * Add the Rock Ridge attributes, if present */ if(s_entry->rr_attr_size) { @@ -809,20 +812,20 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) directory_buffer[dir_index++] = 0; } - /* + /* * If the RR attributes were too long, then write the * CE records, as required. */ - if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) + if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) { unsigned char * pnt; int len, nbytes; - - /* + + /* * Go through the entire record and fix up the CE entries - * so that the extent and offset are correct + * so that the extent and offset are correct */ - + pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; while(len > 3) @@ -834,30 +837,30 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) ce_index, ce_address); } #endif - - if(pnt[0] == 'C' && pnt[1] == 'E') + + if(pnt[0] == 'C' && pnt[1] == 'E') { nbytes = get_733( (char *) pnt+20); - + if((ce_index & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) + SECTOR_SIZE) { ce_index = ROUND_UP(ce_index); } - - set_733( (char *) pnt+4, + + set_733( (char *) pnt+4, (ce_address + ce_index) >> 11); - set_733( (char *) pnt+12, + set_733( (char *) pnt+12, (ce_address + ce_index) & (SECTOR_SIZE - 1)); - - - /* - * Now store the block in the ce buffer + + + /* + * Now store the block in the ce buffer */ - memcpy(ce_buffer + ce_index, + memcpy(ce_buffer + ce_index, pnt + pnt[2], nbytes); ce_index += nbytes; - if(ce_index & 1) + if(ce_index & 1) { ce_index++; } @@ -865,11 +868,11 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) len -= pnt[2]; pnt += pnt[2]; } - + } rockridge_size += s_entry->total_rr_attr_size; - memcpy(directory_buffer + dir_index, s_entry->rr_attributes, + memcpy(directory_buffer + dir_index, s_entry->rr_attributes, s_entry->rr_attr_size); dir_index += s_entry->rr_attr_size; } @@ -877,14 +880,14 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) { directory_buffer[dir_index++] = 0; } - + s_entry_d = s_entry; s_entry = s_entry->next; - + /* * Joliet doesn't use the Rock Ridge attributes, so we free it here. */ - if (s_entry_d->rr_attributes) + if (s_entry_d->rr_attributes) { free(s_entry_d->rr_attributes); s_entry_d->rr_attributes = NULL; @@ -912,16 +915,16 @@ void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) last_extent_written += ce_size >> 11; free(ce_buffer); } - + } /* generate_one_directory(... */ -static +static void FDECL1(build_pathlist, struct directory *, node) { struct directory * dpnt; - + dpnt = node; - + while (dpnt) { /* skip if it's hidden */ @@ -933,7 +936,7 @@ void FDECL1(build_pathlist, struct directory *, node) } } /* build_pathlist(... */ -static int FDECL2(compare_paths, void const *, r, void const *, l) +static int FDECL2(compare_paths, void const *, r, void const *, l) { struct directory const *ll = *(struct directory * const *)l; struct directory const *rr = *(struct directory * const *)r; @@ -943,13 +946,13 @@ static int FDECL2(compare_paths, void const *, r, void const *, l) return -1; } - if (rr->parent->path_index > ll->parent->path_index) + if (rr->parent->path_index > ll->parent->path_index) { return 1; } return strcmp(rr->self->isorec.name, ll->self->isorec.name); - + } /* compare_paths(... */ static int generate_path_tables() @@ -965,7 +968,7 @@ static int generate_path_tables() int tablesize; /* - * First allocate memory for the tables and initialize the memory + * First allocate memory for the tables and initialize the memory */ tablesize = path_blocks << 11; path_table_m = (char *) e_malloc(tablesize); @@ -974,7 +977,7 @@ static int generate_path_tables() memset(path_table_m, 0, tablesize); /* - * Now start filling in the path tables. Start with root directory + * Now start filling in the path tables. Start with root directory */ if( next_path_index > 0xffff ) { @@ -983,7 +986,7 @@ static int generate_path_tables() } path_table_index = 0; - pathlist = (struct directory **) e_malloc(sizeof(struct directory *) + pathlist = (struct directory **) e_malloc(sizeof(struct directory *) * next_path_index); memset(pathlist, 0, sizeof(struct directory *) * next_path_index); build_pathlist(root); @@ -992,10 +995,10 @@ static int generate_path_tables() { fix = 0; #ifdef __STDC__ - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), + qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), (int (*)(const void *, const void *))compare_paths); #else - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), + qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), compare_paths); #endif @@ -1017,55 +1020,55 @@ static int generate_path_tables() error (1, 0, _("Entry %d not in path tables\n"), j); } npnt = dpnt->de_name; - - /* - * So the root comes out OK + + /* + * So the root comes out OK */ - if( (*npnt == 0) || (dpnt == root) ) + if( (*npnt == 0) || (dpnt == root) ) { - npnt = "."; + npnt = "."; } npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { + if(npnt1) + { npnt = npnt1 + 1; } - + de = dpnt->self; - if(!de) + if(!de) { error (1, 0, _("Fatal goof\n")); } - - + + namelen = de->isorec.name_len[0]; - + path_table_l[path_table_index] = namelen; path_table_m[path_table_index] = namelen; path_table_index += 2; - - set_731(path_table_l + path_table_index, dpnt->extent); - set_732(path_table_m + path_table_index, dpnt->extent); + + set_731(path_table_l + path_table_index, dpnt->extent); + set_732(path_table_m + path_table_index, dpnt->extent); path_table_index += 4; - - set_721(path_table_l + path_table_index, - dpnt->parent->path_index); - set_722(path_table_m + path_table_index, - dpnt->parent->path_index); + + set_721(path_table_l + path_table_index, + dpnt->parent->path_index); + set_722(path_table_m + path_table_index, + dpnt->parent->path_index); path_table_index += 2; - + for(i =0; iisorec.name[i]; path_table_m[path_table_index] = de->isorec.name[i]; path_table_index++; } - if(path_table_index & 1) + if(path_table_index & 1) { path_table_index++; /* For odd lengths we pad */ } } - + free(pathlist); if(path_table_index != path_table_size) { @@ -1108,7 +1111,7 @@ static int FDECL1(file_write, FILE *, outfile) /* * OK, all done with that crap. Now write out the directories. * This is where the fur starts to fly, because we need to keep track of - * each file as we find it and keep track of where we put it. + * each file as we find it and keep track of where we put it. */ should_write = last_extent - session_start; @@ -1124,16 +1127,16 @@ static int FDECL1(file_write, FILE *, outfile) #ifdef DBG_ISO fprintf(stderr,"Total directory extents being written = %llu\n", last_extent); #endif - - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), + + fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), last_extent - session_start); } - /* - * Now write all of the files that we need. + /* + * Now write all of the files that we need. */ write_files(outfile); - + /* * The rest is just fluff. */ @@ -1145,8 +1148,8 @@ static int FDECL1(file_write, FILE *, outfile) fprintf (stderr, _("Total extents actually written = %llu\n"), last_extent_written - session_start); - /* - * Hard links throw us off here + /* + * Hard links throw us off here */ assert (last_extent > session_start); if(should_write + session_start != last_extent) @@ -1192,7 +1195,7 @@ static int FDECL1(pvd_write, FILE *, outfile) /* * This will break in the year 2000, I supose, but there is no good way - * to get the top two digits of the year. + * to get the top two digits of the year. */ sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year, local.tm_mon+1, local.tm_mday, @@ -1204,28 +1207,28 @@ static int FDECL1(pvd_write, FILE *, outfile) iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15; /* - * Next we write out the primary descriptor for the disc + * Next we write out the primary descriptor for the disc */ memset(&vol_desc, 0, sizeof(vol_desc)); vol_desc.type[0] = ISO_VD_PRIMARY; memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); vol_desc.version[0] = 1; - + memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id)); memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); - + memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id)); memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); - + should_write = last_extent - session_start; set_733((char *) vol_desc.volume_space_size, should_write); set_723(vol_desc.volume_set_size, volume_set_size); set_723(vol_desc.volume_sequence_number, volume_sequence_number); set_723(vol_desc.logical_block_size, 2048); - + /* * The path tables are used by DOS based machines to cache directory - * locations + * locations */ set_733((char *) vol_desc.path_table_size, path_table_size); @@ -1235,9 +1238,9 @@ static int FDECL1(pvd_write, FILE *, outfile) set_732(vol_desc.opt_type_m_path_table, path_table[3]); /* - * Now we copy the actual root directory record + * Now we copy the actual root directory record */ - memcpy(vol_desc.root_directory_record, &root_record, + memcpy(vol_desc.root_directory_record, &root_record, sizeof(struct iso_directory_record) + 1); /* @@ -1257,15 +1260,15 @@ static int FDECL1(pvd_write, FILE *, outfile) if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid)); FILL_SPACE(copyright_file_id); - if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, + if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, strlen(copyright)); FILL_SPACE(abstract_file_id); - if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, + if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, strlen(abstract)); FILL_SPACE(bibliographic_file_id); - if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, + if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, strlen(biblio)); FILL_SPACE(creation_date); @@ -1281,7 +1284,7 @@ static int FDECL1(pvd_write, FILE *, outfile) memcpy(vol_desc.effective_date, effective_date ? effective_date : iso_time, 17); /* - * if not a bootable cd do it the old way + * if not a bootable cd do it the old way */ xfwrite(&vol_desc, 1, 2048, outfile); last_extent_written++; @@ -1296,7 +1299,7 @@ static int FDECL1(evd_write, FILE *, outfile) struct iso_primary_descriptor evol_desc; /* - * Now write the end volume descriptor. Much simpler than the other one + * Now write the end volume descriptor. Much simpler than the other one */ memset(&evol_desc, 0, sizeof(evol_desc)); evol_desc.type[0] = ISO_VD_END; @@ -1313,7 +1316,7 @@ static int FDECL1(evd_write, FILE *, outfile) static int FDECL1(pathtab_write, FILE *, outfile) { /* - * Next we write the path tables + * Next we write the path tables */ xfwrite(path_table_l, 1, path_blocks << 11, outfile); xfwrite(path_table_m, 1, path_blocks << 11, outfile); @@ -1344,6 +1347,9 @@ int FDECL1(oneblock_size, int, starting_extent) /* * Functions to describe padding block at the start of the disc. */ + +#define PADBLOCK_SIZE 16 + static int FDECL1(pathtab_size, int, starting_extent) { path_table[0] = starting_extent; @@ -1357,7 +1363,7 @@ static int FDECL1(pathtab_size, int, starting_extent) static int FDECL1(padblock_size, int, starting_extent) { - last_extent += 16; + last_extent += PADBLOCK_SIZE; return 0; } @@ -1420,17 +1426,45 @@ static int FDECL1(dirtree_cleanup, FILE *, outfile) static int FDECL1(padblock_write, FILE *, outfile) { - char buffer[2048]; - int i; + char *buffer; - memset(buffer, 0, sizeof(buffer)); + buffer = e_malloc (2048 * PADBLOCK_SIZE); + memset (buffer, 0, 2048 * PADBLOCK_SIZE); - for(i=0; i<16; i++) + if (use_embedded_boot) { - xfwrite(buffer, 1, sizeof(buffer), outfile); + FILE *fp = fopen (boot_image_embed, "rb"); + if (! fp) + error (1, errno, _("Unable to open %s"), boot_image_embed); + fread (buffer, 2048 * PADBLOCK_SIZE, 1, fp); } - last_extent_written += 16; + if (use_protective_msdos_label) + { + struct msdos_partition_mbr *mbr = (void *) buffer; + + memset (mbr->entries, 0, sizeof(mbr->entries)); + + /* Some idiotic BIOSes refuse to boot if they don't find at least + one partition with active bit set. */ + mbr->entries[0].flag = 0x80; + + /* Doesn't really matter, as long as it's non-zero. It seems that + 0xCD is used elsewhere, so we follow suit. */ + mbr->entries[0].type = 0xcd; + + /* Start immediately (sector 1). */ + mbr->entries[0].start = 1; + + /* We don't know yet. Let's keep it safe. */ + mbr->entries[0].length = UINT32_MAX; + + mbr->signature = MSDOS_PARTITION_SIGNATURE; + } + + xfwrite (buffer, 1, 2048 * PADBLOCK_SIZE, outfile); + last_extent_written += PADBLOCK_SIZE; + return 0; } diff --git a/util/pci.c b/util/pci.c new file mode 100644 index 000000000..a0c1867be --- /dev/null +++ b/util/pci.c @@ -0,0 +1,76 @@ +/* pci.c - Generic PCI interfaces. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 . + */ + +#include +#include +#include + +grub_pci_address_t +grub_pci_make_address (grub_pci_device_t dev, int reg) +{ + grub_pci_address_t ret; + ret.dev = dev; + ret.pos = reg << 2; + return ret; +} + +void +grub_pci_iterate (grub_pci_iteratefunc_t hook) +{ + struct pci_device_iterator *iter; + struct pci_slot_match slot; + struct pci_device *dev; + slot.domain = PCI_MATCH_ANY; + slot.bus = PCI_MATCH_ANY; + slot.dev = PCI_MATCH_ANY; + slot.func = PCI_MATCH_ANY; + iter = pci_slot_match_iterator_create (&slot); + while ((dev = pci_device_next (iter))) + hook (dev, dev->vendor_id | (dev->device_id << 16)); + pci_iterator_destroy (iter); +} + +void * +grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base, + grub_size_t size) +{ + void *addr; + int err; + err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr); + if (err) + grub_util_error ("mapping 0x%x failed (error %d)\n", base, err); + return addr; +} + +void +grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem, + grub_size_t size) +{ + pci_device_unmap_range (dev, mem, size); +} + +GRUB_MOD_INIT (pci) +{ + pci_system_init (); +} + +GRUB_MOD_FINI (pci) +{ + pci_system_cleanup (); +} diff --git a/util/sparc64/ieee1275/grub-install.in b/util/sparc64/ieee1275/grub-install.in index f49157acd..be9922202 100644 --- a/util/sparc64/ieee1275/grub-install.in +++ b/util/sparc64/ieee1275/grub-install.in @@ -31,9 +31,6 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -# for make_system_path_relative_to_its_root() -. ${libdir}/grub/grub-mkconfig_lib - grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` @@ -121,6 +118,9 @@ for option in "$@"; do esac done +# for make_system_path_relative_to_its_root() +. ${libdir}/grub/grub-mkconfig_lib + if test "x$install_device" = x; then echo "install_device not specified." 1>&2 usage diff --git a/util/sparc64/ieee1275/grub-mkimage.c b/util/sparc64/ieee1275/grub-mkimage.c index 5260996f6..d756586af 100644 --- a/util/sparc64/ieee1275/grub-mkimage.c +++ b/util/sparc64/ieee1275/grub-mkimage.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,8 @@ #define _GNU_SOURCE 1 #include +#include "progname.h" + static void compress_kernel (char *kernel_img, size_t kernel_size, char **core_img, size_t *core_size) diff --git a/util/sparc64/ieee1275/grub-ofpathname.c b/util/sparc64/ieee1275/grub-ofpathname.c index 4b852698f..166ce4cbe 100644 --- a/util/sparc64/ieee1275/grub-ofpathname.c +++ b/util/sparc64/ieee1275/grub-ofpathname.c @@ -20,6 +20,10 @@ #include #include +#include + +#include "progname.h" + int main(int argc, char **argv) { char *of_path; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 6ce8cdf6d..ade1bd595 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,8 @@ #define _GNU_SOURCE 1 #include +#include "progname.h" + /* This program fills in various fields inside of the 'boot' and 'core' * image files. * @@ -419,7 +422,7 @@ DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name +", program_name, DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); diff --git a/video/efi_gop.c b/video/efi_gop.c index 3143135d6..f3a296ef9 100644 --- a/video/efi_gop.c +++ b/video/efi_gop.c @@ -93,7 +93,7 @@ grub_video_gop_get_bpp (struct grub_efi_gop_mode_info *in) total_mask = in->pixel_bitmask.r | in->pixel_bitmask.g | in->pixel_bitmask.b | in->pixel_bitmask.a; - + for (i = 31; i >= 0; i--) if (total_mask & (1 << i)) return i + 1; @@ -123,7 +123,7 @@ grub_video_gop_get_bitmask (grub_uint32_t mask, unsigned int *mask_size, if (!(mask & (1 << i))) break; *field_pos = i + 1; - *mask_size = last_p - *field_pos; + *mask_size = last_p - *field_pos + 1; } static grub_err_t @@ -212,7 +212,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, found = 1; } } - + if (!found) { unsigned mode; @@ -221,7 +221,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, { grub_efi_uintn_t size; grub_efi_status_t status; - + status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); if (status) { @@ -255,7 +255,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, * ((unsigned long long) bpp)) { best_volume = ((unsigned long long) info->width) - * ((unsigned long long) info->height) + * ((unsigned long long) info->height) * ((unsigned long long) bpp); best_mode = mode; } @@ -293,8 +293,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); - - err = grub_video_fb_create_render_target_from_pointer + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) @@ -302,15 +302,15 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't create FB target\n"); return err; } - + err = grub_video_fb_set_active_render_target (framebuffer.render_target); - + if (err) { grub_dprintf ("video", "GOP: Couldn't set FB target\n"); return err; } - + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); @@ -318,7 +318,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't set palette\n"); else grub_dprintf ("video", "GOP: Success\n"); - + return err; } diff --git a/video/efi_uga.c b/video/efi_uga.c index 2a9e78a4f..1fe0aa500 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -84,21 +84,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index a039710a2..f815e789c 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -33,6 +33,9 @@ static int vbe_detected = -1; static struct grub_vbe_info_block controller_info; static struct grub_vbe_mode_info_block active_vbe_mode_info; +/* Track last mode to support cards which fail on get_mode. */ +static grub_uint32_t last_set_mode = 3; + static struct { struct grub_video_mode_info mode_info; @@ -172,6 +175,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, status = grub_vbe_bios_set_mode (vbe_mode, 0); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); + last_set_mode = vbe_mode; /* Save information for later usage. */ framebuffer.active_vbe_mode = vbe_mode; @@ -215,6 +219,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, case 8: framebuffer.bytes_per_pixel = 1; break; default: grub_vbe_bios_set_mode (old_vbe_mode, 0); + last_set_mode = old_vbe_mode; return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); @@ -268,8 +273,9 @@ grub_vbe_get_video_mode (grub_uint32_t *mode) /* Try to query current mode from VESA BIOS. */ status = grub_vbe_bios_get_mode (mode); + /* XXX: ATI cards don't support get_mode. */ if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); + *mode = last_set_mode; return GRUB_ERR_NONE; } @@ -363,6 +369,7 @@ grub_video_vbe_fini (void) if (status != GRUB_VBE_STATUS_OK) /* TODO: Decide, is this something we want to do. */ return grub_errno; + last_set_mode = initial_vbe_mode; /* TODO: Free any resources allocated by driver. */ grub_free (vbe_mode_list); @@ -583,10 +590,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, /* If not available, skip it. */ continue; - if ((vbe_mode_info.mode_attributes & 0x002) == 0) - /* Not enough information. */ - continue; - if ((vbe_mode_info.mode_attributes & 0x008) == 0) /* Monochrome is unusable. */ continue;