diff --git a/ChangeLog b/ChangeLog index d7d6ed847..e594931e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,466 @@ +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. @@ -280,7 +743,7 @@ 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, + (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. @@ -321,7 +784,7 @@ (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): + (notify_booting, notify_fallback, notify_execution_failure): Gettextize. * normal/menu_entry.c (store_completion): Cleanup the gettextized string. @@ -592,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 e1dd0876f..46b380cd5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -484,8 +484,8 @@ 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 $(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): po/$(PACKAGE).pot $(MSGMERGE) -U $@ $^ 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/bus/usb/uhci.c b/bus/usb/uhci.c index 0d3daa5f1..e83fccc1d 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -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/loadbios.c b/commands/efi/loadbios.c index 23586b269..d7ad42690 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -46,7 +46,7 @@ enable_rom_area (void) 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; } @@ -63,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; } @@ -201,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 8fa8db5be..09431d3cb 100644 --- a/commands/halt.c +++ b/commands/halt.c @@ -35,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 4b3e3ef29..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} }; 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 344dcecd8..befd58804 100644 --- a/commands/i386/pc/halt.c +++ b/commands/i386/pc/halt.c @@ -23,7 +23,7 @@ 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 bcaafa4f8..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,12 +115,21 @@ 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 (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", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), @@ -143,27 +153,75 @@ grub_lspci_iter (grub_pci_device_t dev, 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(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(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 6c9c33a0e..9e06fa5de 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -354,28 +354,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 86c9e2dd9..2add295ef 100644 --- a/commands/reboot.c +++ b/commands/reboot.c @@ -35,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 6fe4b9bd1..15525524b 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -178,7 +178,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/common.rmk b/conf/common.rmk index 56f17e4e7..1ed30a404 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -638,3 +638,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 e597328e7..8b69f7796 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -109,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) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 629b83999..3a219e71b 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -67,7 +67,7 @@ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genke /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 +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 031c24adf..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 +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/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 d19e927a5..4e90a4d35 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -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 ee511e1bd..a82b35222 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -67,7 +67,7 @@ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genke /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,8 +160,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 +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/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/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 c780887c6..f3097d60b 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; diff --git a/genmk.rb b/genmk.rb index 127b8096b..b3dbe8678 100644 --- a/genmk.rb +++ b/genmk.rb @@ -364,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/gettext/gettext.c b/gettext/gettext.c index 65db73a78..fe14dab2e 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -29,8 +29,8 @@ #include #include -/* - .mo file information from: +/* + .mo file information from: http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html . */ 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 43f152981..b12205ad3 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -55,6 +55,10 @@ 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); 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/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/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 1b470f8c2..e14cc3e96 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -85,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/xnu.h b/include/grub/i386/xnu.h index 306dc7b65..3be2c3bcc 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -20,6 +20,7 @@ #define GRUB_CPU_XNU_H 1 #include +#include #include #define XNU_RELOCATOR(x) (grub_relocator32_ ## x) @@ -67,15 +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; #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 926195d2c..92fb460cf 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -183,9 +183,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, 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/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/xnu.h b/include/grub/xnu.h index cf778cf6b..6ce17c25e 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, @@ -101,7 +103,10 @@ 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 void *grub_xnu_heap_start; extern struct grub_video_bitmap *grub_xnu_bitmap; +extern int grub_xnu_is_64bit; #endif 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/qemu/startup.S b/kern/i386/qemu/startup.S index 7d3cb1b5e..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 diff --git a/kern/misc.c b/kern/misc.c index d9988961c..f6d189e94 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -879,68 +879,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 24e9d5b15..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} }; 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 index ae7caf28b..453f73fdd 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -85,14 +85,14 @@ write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest, 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)); diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index d39732987..6b803db13 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -32,8 +32,8 @@ #else #define RAX %eax #define RCX %ecx -#define RDI %edi -#define RSI %esi +#define RDI %edi +#define RSI %esi #endif /* The code segment of the protected mode. */ @@ -41,7 +41,7 @@ /* The data segment of the protected mode. */ #define DATA_SEGMENT 0x18 - + .p2align 4 /* force 16-byte alignment */ RELOCATOR_VARIABLE(start) @@ -92,7 +92,7 @@ RELOCATOR_VARIABLE(size) #endif mov RDI, RAX - + #ifdef BACKWARD add RCX, RSI add RCX, RDI @@ -104,7 +104,7 @@ RELOCATOR_VARIABLE(size) add $0x3, RCX shr $2, RCX - + #ifdef BACKWARD /* Backward movsl is implicitly off-by-four. compensate that. */ sub $4, RSI @@ -213,7 +213,7 @@ RELOCATOR_VARIABLE (eip) LOCAL(gdt): /* NULL. */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - + /* Reserved. */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -234,7 +234,7 @@ LOCAL(gdt_addr): /* Filled by the code. */ .long 0 #endif - + .p2align 4 LOCAL(jump_vector): /* Jump location. Is filled by the code */ diff --git a/lib/relocator.c b/lib/relocator.c index d10af34d4..6a5acc548 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -79,7 +79,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, /* 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) + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) && (grub_addr_t) dest + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) > (grub_addr_t) relocator) { @@ -105,7 +105,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, "Backward relocator: code %p, source: %p, " "destination: 0x%x, size: 0x%lx\n", (char *) relocator - overhead, - (char *) relocator - overhead, + (char *) relocator - overhead, (unsigned) dest - overhead, (unsigned long) size + overhead); 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/multiboot.c b/loader/i386/multiboot.c index f5036a2ae..be824e2f4 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -201,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 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 6a3535950..4786bfd39 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -25,9 +25,13 @@ #include #include #include +#include #include #include +#include #include +#include +#include char grub_xnu_cmdline[1024]; grub_uint32_t grub_xnu_heap_will_be_at; @@ -46,6 +50,14 @@ struct tbl_alias table_aliases[] = {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, }; +struct grub_xnu_devprop_device_descriptor +{ + 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) { @@ -192,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 @@ -203,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? */ @@ -414,7 +832,7 @@ grub_xnu_boot_resume (void) state.eax = grub_xnu_arg1; return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, - state); + state); } /* Boot xnu. */ @@ -430,12 +848,29 @@ 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); if (err) @@ -448,89 +883,6 @@ 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 - = ((grub_uint8_t *) devtree - (grub_uint8_t *) 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; grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point); const char *debug = grub_env_get ("debug"); @@ -541,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) @@ -557,12 +916,121 @@ grub_xnu_boot (void) bootparams_relloc->lfb_base = 0; } - if (! grub_autoefi_finish_boot_services ()) + 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; + + 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_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, + descriptor_version,memory_map); + 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/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 cc6d55ae2..37239e23c 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -31,10 +31,12 @@ #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; @@ -65,7 +67,7 @@ grub_xnu_heap_malloc (int size) advanced mm is ready. */ grub_xnu_heap_start = XNU_RELOCATOR (realloc) (grub_xnu_heap_start, - newblknum + newblknum * GRUB_XNU_HEAP_ALLOC_BLOCK); if (!grub_xnu_heap_start) return NULL; @@ -326,6 +328,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; @@ -345,7 +349,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; @@ -361,10 +365,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); @@ -387,7 +391,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); @@ -395,7 +399,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); @@ -429,13 +433,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; } @@ -487,6 +590,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) @@ -498,6 +629,18 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) int neededspace = sizeof (*exthead); 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"); @@ -513,7 +656,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 @@ -548,7 +694,11 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) 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; @@ -574,9 +724,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); @@ -641,7 +799,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); @@ -732,135 +896,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 @@ -1157,53 +1192,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; @@ -1264,6 +1252,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; static grub_err_t @@ -1309,13 +1398,15 @@ grub_xnu_unlock () locked = 0; } -static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir, - cmd_ramdisk, cmd_devtree, cmd_resume, cmd_splash; +static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext; +static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume, cmd_splash; 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, @@ -1326,8 +1417,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_command ("xnu_splash", grub_cmd_xnu_splash, 0, "Load a splash image for XNU"); @@ -1335,7 +1424,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) @@ -1346,8 +1438,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_command (cmd_kernel64); grub_unregister_command (cmd_splash); + + grub_cpu_xnu_fini (); } 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 7a5b6ec84..6d74e6e69 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) { @@ -266,14 +268,14 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, grub_refresh (); } - 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); @@ -334,7 +336,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 f080a6971..e8dfb182b 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_ (N_("\ - [ 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_text.c b/normal/menu_text.c index bb1f52203..4f2dfb78e 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -53,7 +53,7 @@ print_spaces (int number_spaces) grub_putchar (' '); } -static void +void grub_print_ucs4 (const grub_uint32_t * str, const grub_uint32_t * last_position) { @@ -64,8 +64,35 @@ grub_print_ucs4 (const grub_uint32_t * str, } } -static grub_ssize_t -getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position) +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; @@ -77,44 +104,39 @@ getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position) return width; } -static void -print_message_indented (const char *msg) +void +grub_print_message_indented (const char *msg, int margin_left, int margin_right) { - const int line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') * 15; + 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; - grub_ssize_t msg_len = grub_strlen (msg); + int msg_len; - unicode_msg = grub_malloc (msg_len * sizeof (*unicode_msg)); - - msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len, - (grub_uint8_t *) msg, -1, 0); - - if (!unicode_msg) - { - grub_printf ("print_message_indented ERROR1: %s", msg); - return; - } + msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position); if (msg_len < 0) { - grub_printf ("print_message_indented ERROR2: %s", msg); - grub_free (unicode_msg); return; } - const grub_uint32_t *last_position = unicode_msg + msg_len; - 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 (getstringwidth (current_position, next_new_line) > line_len + while (grub_getstringwidth (current_position, next_new_line) > line_len || (*next_new_line != ' ' && next_new_line > current_position && next_new_line != last_position)) { @@ -127,12 +149,12 @@ print_message_indented (const char *msg) (grub_uint32_t *) last_position : next_new_line + line_len; } - print_spaces (6); + print_spaces (margin_left); grub_print_ucs4 (current_position, next_new_line); - grub_putchar ('\n'); next_new_line++; current_position = next_new_line; + first_loop = 0; } grub_free (unicode_msg); } @@ -182,26 +204,26 @@ print_message (int nested, int edit) if (edit) { grub_putchar ('\n'); - print_message_indented (_("Minimum Emacs-like screen editing is \ + 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.")); +command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN); } else { const char *msg = _("Use the %C and %C keys to select which \ -entry is highlighted."); +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'); - print_message_indented (msg_translated); + grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN); grub_free (msg_translated); - print_message_indented (_("Press enter to boot the selected OS, \ -\'e\' to edit the commands before booting or \'c\' for a command-line.")); + 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) { @@ -368,22 +390,26 @@ get_entry_number (const char *name) } static void -print_timeout (int timeout, int offset, int second_stage) +print_timeout (int timeout, int offset) { const char *msg = _("The highlighted entry will be booted automatically in %ds."); - const int msg_localized_len = grub_strlen (msg); - const int number_spaces = GRUB_TERM_WIDTH - msg_localized_len - 3; - char *msg_end = grub_strchr (msg, '%'); + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - grub_gotoxy (second_stage ? (msg_end - msg + 3) : 3, GRUB_TERM_HEIGHT - 3); - grub_printf (second_stage ? msg_end : msg, timeout); - print_spaces (second_stage ? number_spaces : 0); + 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 (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., @@ -434,7 +460,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 (1) { @@ -451,7 +477,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); } } 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 7d213c357..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,5 +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/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 b521e25cd..25f4eae61 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. */ diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 8caf4f154..bd4b3e2c8 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -100,7 +100,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-mkrescue.in b/util/grub-mkrescue.in index 8e4a77f58..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,16 @@ 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 @@ -128,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 @@ -155,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}" @@ -172,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.d/00_header.in b/util/grub.d/00_header.in index 96352cdae..feeb69b70 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -107,12 +107,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 5c95e5f88..38c96f9f8 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 '^' ' '`" @@ -115,53 +165,8 @@ EOF ;; macosx) OSXUUID="`grub-probe --target=fs_uuid --device ${DEVICE} 2> /dev/null`" - cat << EOF -menuentry "${LONGNAME} (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 - 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/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/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/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/video/efi_gop.c b/video/efi_gop.c index e2eb2f7ae..0cae91e7b 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/i386/pc/vbe.c b/video/i386/pc/vbe.c index be1b519c5..28442eab6 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -356,6 +356,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);